最初はRubyの勉強のために始めた競技プログラミング(以下競プロ)ですが、最近はほぼ趣味として取り組んでいます。いずれは競プロに適しているとされる、コンパイル言語のC++で取り組んでみたいとは思っているものの、まだRuby学習中の身なのでしばらくはRubyでやっていこうと思っています。
僕の競プロ歴はAtCoderのABCに4回出場、実力は3完できるくらいの初心者ではありますが、Rubyで競プロを行う上で役に立つTipsをブログに書き溜めていきたいと思い立ち、この記事を書いています。
競プロのRuby情報は多くないと思いますので、誰かの役に立てれば幸いです。
ということで、今回は競プロでは必須の「標準入力を扱う方法」についてです。
getsメソッドで標準入力を取得できる
Rubyでは、gets
で標準入力を取得できます。ただし、gets
で取得した文字列は改行コード付きのため、競プロにおいてはgets
単独ではほとんど使いません。
<標準入力> sample
x = gets => "sample\n" # 末尾に改行コード
文字列を扱う場合
入力を文字列で扱う場合は、chomp
を使って末尾の改行コードを取り除きます。
これをしないと、パッと見正しい出力ができていても、オンラインジャッジで誤答と判定される場合があるので注意です。このことを知らず、「明らかに正しい出力が得られているのにACにならない。なぜ。。。」とドツボにはまったことがありました。
ちなみに、入力を数値で扱う場合はchomp
は必要ありません。chomp
を付けると処理速度の低下につながるようなので、文字列を扱う場合のみ付けるようにしましょう。
<参考> leokun0210.hatenablog.com
<標準入力> sample
x = gets.chomp => "sample"
文字列を1文字ずつ分けて配列に格納する
入力の文字列を、1文字ずつ扱いたい場合はchars
を使って分割し配列に格納できます。
<標準入力> sample
x = gets.chomp.chars => ["s", "a", "m", "p", "l", "e"]
数値を扱う場合
整数として取得する
gets
は文字列を返すので、数値として扱いたい場合はto_i
で整数に変換します。
<標準入力> 32
x = gets.to_i
=> 32
数値を文字列として扱いたい場合はgets.chomp
を使います。
x = gets.chomp => "32"
浮動小数点数として取得する
入力値を小数で扱いたい場合はto_f
を使います。
<標準入力> 32
x = gets.to_f
=> 32.0
スペース区切りの数値を取得する
競プロでよくあるのがスペース区切りで数値が並んでいる入力です。この場合は、split
を使って各数値を分割します。
<標準入力> 5 3 12 1
x = gets.split.map(&:to_i) => [5, 3, 12, 1]
たまにsplit(' ')
と引数に区切り文字の半角スペースを指定している人を見かけますが、split
は引数を省略すると半角スペースで区切ってくれるので、結果は変わりません。
x = gets.split(' ').map(&:to_i) => [5, 3, 12, 1]
各数値を配列でなく、独立した変数に格納したい場合は多重代入を使います。
a, b, c, d = gets.split.map(&:to_i) => [5, 3, 12, 1] p a => 5 p c => 12
縦に並んだ数値を取得する
縦に数値がならんだ入力を扱う方法です。
最初に「数値の数」が入力として与えられ、以降、縦に数値が並ぶケースが多いです。
以下の例だと、数値の数「4」が与えられ、以降、4つの数値が縦に並びます。この場合は、4回gets.to_i
を繰り返せばOKです。
<標準入力> 4 5 3 12 1
n = gets.to_i => 4 n.times.map { gets.to_i } => [5, 3, 12, 1]