Julia言語で競技プログラミング(入出力編)
筆者は競技プログラミング初心者で、DPわからんといいつづけてます。
とくに最初の方は入出力の処理にめちゃくちゃ手間取っていたということもあり、そのような悲劇を自分で終わらせるべく、備忘録も兼ねて筆をとることにしました。(競プロ界でもJulia流行ってくれたのむ)
入力の処理
標準入力
Juliaの標準入力の処理は主にreadline
とreadlines
の2通りあります。
readline
は標準入力の1行分を受け取って文字列として返し、他方readlines
の返り値は各行の文字列を格納した配列であることに注意する必要があります。
具体例として、以下のような入力を処理する場合について考えてみましょう。
N
M
readline
とreadlines
でそれぞれの場合についてみてみましょう。
- 標準入力から1列の文字列を受け取る
N = readline()
M = readline()
- 標準出力から全ての列の文字列を受け取る
NM = readlines()
N = NM[1]
M = NM[2]
文字列→数値への変換について
競技プログラミングでは入力が数値であることが多いが、先ほどのままでは文字列として扱われてしまうため、変換の処理が必要です。Julia言語ではこのような変換はparse(T, str)
でサポートされています。第一引数は変換先の型、第二引数は変換したい文字列が入ります。
余談ですが、Juliaには任意精度整数が実装されており、通常の整数型ではREとなる問題であっても任意精度整数へ変換するだけで通ったという場合もかなりあるため、整数が大きくなりすぎるような問題では任意精度整数への変換を常に検討しましょう。
parse(Int64, str) #整数への変換。Int64はIntでも可
parse(BigInt, str) #任意精度整数への変換
parse(Float64, str) #実数への変換。Float64はFloatの省略は不可
空白の処理
競技プログラミングの入力ではしばしば1行に空白文字を挟んで複数の数字が現れることがあります。
このような入力を整数として正しく処理するには、split
関数を用います。
N M
A_1 A_2 \cdots A_M
上記のような2行の入力は、筆者の場合には次のように処理することが多いです。
parseInt(str=readline()) = parse.(Int, split(str))
N, M = parseInt()
A = parseInt() #要素数Mの配列
split
関数は受け取った文字列をデリミタ(デフォルトは空白)で分割し、配列として返す関数です。parse
関数のとなりについている奇妙なピリオドはJulia言語のブロードキャストという機能で、配列が引数に入っている場合に各要素に関数をかけたものの配列を返り値として返してくれるという便利機能です。例えばparseInt
で受け取るという作業をあえて書き下すとこんな感じです。
str = readline() #"26 42"という文字列
strs = split(str) #["26", "42"]という文字列を要素とする配列
N, M = parse.(Int, strs) #[parse(Int, "26"), parse(Int, "42")] = Int[26, 42]
出力
標準出力へ出力するにはprint
とprintln
の2通りあります。print
はそのまま標準出力へ流すのに対して、println
は内容を標準出力へ流した後改行してくれるものです。恐らく競技プログラミングの文脈においてはprintln
さえ知っておけば問題ないでしょう(少なくとも筆者は競プロでprint
を一度も使用したことがないです)。引数は数値でも文字列でも問題なく表示してくれるのでそこは安心して使いましょう。
"Yes"
42
と2行の出力を表示させたい場合には以下のように記述します。
N = 42
println("Yes")
println(N)
Discussion