rust
競技プログラミング

Rustで競プロに使えそうな入力取得用マクロ

つらみがある。デフォでは1行取ってくるだけでも面倒くさいんですよね。
趣旨からずれるかもしれないですが、マクロ書けば、scanfやcinほど簡単じゃないんですが多少はマシなものが作れました。

競技プログラミングガチ勢じゃないので「これじゃ○○のときに使えねぇ!」とかありましたらコメント欄まで。

#![allow(unused_macros, unused_imports, dead_code)]

use std::io;

fn read_line() -> String {
    let mut s = String::new();
    io::stdin().read_line(&mut s).unwrap();
    s
}

macro_rules! from_line {
    ($($a:ident : $t:ty),+) => {
        $(let $a: $t;)+
        {
            let _line = read_line();
            let mut _it = _line.trim().split_whitespace();
            $($a = _it.next().unwrap().parse().unwrap();)+
            assert!(_it.next().is_none());
        }
    };
}

使い方

from_line!(変数名: 型, ...);
のようにすると、let 変数名: 型;されて、値が代入されます。
mutはつけられないので、必要なら後でlet mut x = x;のようにしてください。

例題:
https://yukicoder.me/problems/no/431

3つの死亡フラグの状態と、1つの生存フラグの状態が与えられるので、
死亡か生存か判定してください。判定方法は次の通りです。

  • 死亡フラグが2本以上立っていれば死亡、2本未満なら生存
  • 生存フラグが立っていれば、死亡フラグの状態に関わらず生存

入力

$D_1\ D_2\ D_3\ S$

$D_i$ は死亡フラグiの状態、Sは生存フラグの状態で、1か0が与えられます。
1はON(フラグが立っている)、0はOFF(フラグが立っていない)を表します。

出力

死亡なら"DEAD"、生存なら"SURVIVED"と出力してください。
最後に改行してください。

これが、こんな感じになります。

fn main() {
    from_line!(d1: u32, d2: u32, d3: u32, s: u32);
    println!("{}",
             if s > 0 || d1 + d2 + d3 < 2 {
                 "SURVIVED"
             } else {
                 "DEAD"
             });
}