AtCoderの言語アップデート(現在テスト公開中?)でRust環境に入出力系の便利ライブラリが追加されていました。ライブラリを使うと入出力周りがかなりスッキリ書けるようになっていたので紹介します。
追加されているライブラリの一覧はこちら(https://github.com/rust-lang-ja/atcoder-rust-base/blob/ja-all-enabled/Cargo.toml)
確認に使用する問題
入力
入力は以下の形式で標準入力から与えられる。
a b
出力
積が奇数なら Odd と、 偶数なら Even と出力せよ。
ライブラリ使用なしのコード
まずはライブラリ使用なしで解いた場合のコードです。
fn main() {
let mut buf = String::new();
// 標準入力をStringで読み込み。IOは失敗するのでunwrap()
std::io::stdin().read_to_string(&mut buf).unwrap();
// 空白区切りのiteratorに分割
let mut iter = buf.split_whitespace();
// iteratorからnext()で値を取り出し、parseでi32に変換。next(), parse()ともに失敗するのでunwrap()
let a: i32 = iter.next().unwrap().parse().unwrap();
let b: i32 = iter.next().unwrap().parse().unwrap();
let answer = if a % 2 == 0 || b % 2 == 0 { "Even" } else { "Odd" };
println!("{}", answer)
}
標準入力、空白区切り、数値変換がそれぞれ失敗する可能性があるのはわかりますが、毎回unwrap()を書くのは面倒ですね。
rustでAtCoderに参加している方はこのあたりの面倒な処理をマクロで解決していることが多いようです。
ライブラリ使用ありのコード
AtCoder環境に追加されたライブラリ一覧には、入出力周りで以下3つのライブラリが追加されています。
それぞれのライブラリを使用した場合のコードを示します。
proconio
名前の通りプロコンのIO専門のライブラリのようです。
input!マクロの中に読み込む値を並べると自動的に値を読んでくれます。今回使用しませんでしたが、多次元配列を読み込む機能もあるようでかなり高機能なライブラリです。
use proconio::input;
fn main() {
input! {
a: i32,
b: i32,
}
let answer = if a % 2 == 0 || b % 2 == 0 { "Even" } else { "Odd" };
println!("{}", answer)
}
text_io
read!()マクロで1ブロックずつ値を読み込むライブラリです。
C++のstd::cinに近い挙動でしょうか。
#[macro_use] extern crate text_io;
fn main() {
let a: i32 = read!();
let b: i32 = read!();
let answer = if a % 2 == 0 || b % 2 == 0 { "Even" } else { "Odd" };
println!("{}", answer)
}
whiteread
こちらは1行単位で読み込んで、空白区切り分割&parse()をまとめてくれるライブラリです。
もともとの問題が何度もunwrap()しないといけないのが面倒ということで、unwrap()を一回にまとめてくれている感じです。問題をシンプルに解決していて個人的には一番好みです。
use whiteread::parse_line;
fn main() {
let (a, b): (i32, i32) = parse_line().unwrap();
let answer = if a % 2 == 0 || b % 2 == 0 { "Even" } else { "Odd" };
println!("{}", answer)
}
終わりに
AtCoder言語アップデートでRust環境に追加された入出力ライブラリを紹介しました。
どのライブラリを使用する場合でも入出力をシンプルに書けて楽ですね。
今回は整数2つを読むだけのシンプルな入力でしたが、配列やグラフ構造の入力が必要な問題ではまた印象が変わってくると思います。
入出力のやりかたを調べるのが面倒でRustでAtCoder参加をためらうことがありましたが、
これらのライブラリが正式に使えるようになったらまた挑戦して見ようと思います。