AtCoderにElixirで参加してみました。
AtCoder自体初心者なので、その点は、今後慣れていくとして、Elixirでやってみて気づいたことを書いてみます。
Livebookでコーディング
Regular Contestに予習なしで参加するのは、無謀なのでBeginners Selectionの問題をやってみました。
Livebookでいろいろ試しながらできたらいいんじゃないか?ということでこの環境を整えてみました。
標準入力からデータを読み込む必要がありますが、Livebookで再現する方法がみあたりませんでした。
私がたどり着いた方法は、
- 回答のプログラムは文字列を引数とするsolve/1に作成する。
- main()で標準入力から読み込んで、solve/1を呼び出す。
- 開発は文字列を入力にしたsolve/1で行う。
def main() do
solve(IO.read(:stdio, :all))
end
動作確認は、Livebook上で、次の様に書けます
"""
10
20 30
abc
"""
|> Main.solve()
入力データの扱い
入力されたテキストデータを適切に変換する必要があります。
Beginners Selectionをやってみて、次の関数を使いました。
| 関数 | 用途 |
|---|---|
| String.split() | "\n"や" "での分割 |
| String.trim() | 入力データに、適用したほうがいい |
| String.to_integer | 数値への変換必須 |
| String.to_charlist | "110101"のようなデータをリストに変換等 |
| tl/1 | 先頭がデータ件数の場合が多い。これを除く時便利 |
| Enumの関数全部 | chunk_every等、知ってると楽 |
このあたりの関数をパイプを使って並べて、気持ちよく書けると思います。
パターンマッチを使った[a,b] = String.split(input, " ")も大活躍です。
AtCoderの常識なんだとおもいますが、入力データにはString.trim()を必ずかけるようにしたほうがいいです。
行末の改行の有無違いによるものだと思いますが、Beginners Selectionの問題でこれをしないとパスできない問題がありました。
出力
結果の出力は、
IO.putsで行う。
IO.puts("#{a + b + c} #{s}")
数値を出力するだけだったら、IO.inspectでもできるとおもいます。
この辺りは、気分で。
Elixirの再帰処理をフル活用
この問題では、再帰で書いてくださいと言わんばかりの問題だと思いました。
いざ書いてみると、うまく行かなくて、勉強になりました。
ガード節は大活躍でした。
Bitwiseに巡り合えた
たぶん、AtCoderやらなかったら、ガリガリのBit演算することもなかったかも。
偶数、奇数の判定は、rem(x, 2)しか語彙にありませんでした。
Bitwiseを使えば、C言語のbit演算なみの事はできるし、なにより、ガード節にbit演算を書けるではないですか!
Elixirがまた楽しくなりました。
AtCoder Regular Contest 156 に参加
Aの問題に挑戦。問題なくプログラムを作れて、サンプルのデータではOK
しかしテストデータのいくつかで不正解この原因がわからない。
なんとか、残り、5分で、原因がわかって400点でした。
競プロって難しいんだなぁと実感しました。もうちょっと修行します。
その他
AtCoderで動作しているElixirは1.10.2と少し古いです。
バージョンの違いでエラーになる事もあるかもしれません。
今のところ、気づいた事は、then/2が使えない事です
感想
- 再帰での記述など、関数型に慣れる事ができる
- Bitwiseなど新たな機能を知るきっかけになった
- 新しい言語を学んだあと、アウトプットの機会としてAtCoderは手ごろ
- Elixirは楽しい!
