6
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

ElixirでAtCoder参加してみよう(atcoder-toolsの導入)

Last updated at Posted at 2023-05-14

はじめに

AtCoderに先ずは慣れようとおもって、Pythonで何度か参加してみました。
調べてみると、コンテストの参加を手助けしてくれるソフトがいくつかあるんですね。
そのなかで、atcoder-toolsを使って便利だったので、これをElixirでも使えるようにしてみました。

atcoder-toolsの紹介

どんな機能があるかというと

  • AtCoderへのログイン,入出力例データなどの抽出
  • 枝刈り探索による高精度・高速な入力フォーマット解析 (ARC、ABC、AGCについては約9割ほど)
  • 問題文中に含まれるMOD値、YES/NO文字列、誤差ジャッジのための誤差値等の定数値抽出
  • サンプルのローカルテスト機能
  • 誤差ジャッジに対応 by @chaemon
  • コード提出機能
  • 入力フォーマット解析結果や抽出した定数値を用いたテンプレートからのコード自動生成(以下の表に記載されている言語をサポートしています)
    (サイトからの転記)

と、とても便利です。

問題画面からコピペしなくてもテストできるのはとても便利です。

インストール方法

Elixir対応版は、本家にはまだ含まれていません。

Forkしたものを公開したので、
pip installでGitのURL指定でインストールすれば使えると思います。

Python 3.6以上が動作する必要があります。
本家の資料を基にインストールしてください。

pip install atcoder-toolsの部分は、以下のようにGitのURL指定にします。

pip install git+https://github.com/masahiro-999/atcoder-tools.git@elixir

atcoder-toolsコマンドを実行したときに、markupsafeに関するエラーが発生した場合は、pip install MarkupSafe==2.0.1でバージョン指定すると解決します。

こんなエラー ```bash (atcoder) masa@WINPC1:~$ atcoder-tools Traceback (most recent call last): File "/home/masa/.venv/atcoder/bin/atcoder-tools", line 5, in from atcodertools.atcoder_tools import main File "/home/masa/.venv/atcoder/lib/python3.10/site-packages/atcodertools/atcoder_tools.py", line 8, in from atcodertools.tools.envgen import main as envgen_main File "/home/masa/.venv/atcoder/lib/python3.10/site-packages/atcodertools/tools/envgen.py", line 14, in from atcodertools.client.atcoder import AtCoderClient, Contest, LoginError, PageNotFoundError File "/home/masa/.venv/atcoder/lib/python3.10/site-packages/atcodertools/client/atcoder.py", line 15, in from atcodertools.common.language import Language File "/home/masa/.venv/atcoder/lib/python3.10/site-packages/atcodertools/common/language.py", line 4, in from atcodertools.codegen.code_generators import cpp, elixir, java, rust, python, nim, d, cs, swift, go, julia File "/home/masa/.venv/atcoder/lib/python3.10/site-packages/atcodertools/codegen/code_generators/cpp.py", line 2, in from atcodertools.codegen.template_engine import render File "/home/masa/.venv/atcoder/lib/python3.10/site-packages/atcodertools/codegen/template_engine.py", line 5, in from jinja2 import Environment File "/home/masa/.venv/atcoder/lib/python3.10/site-packages/jinja2/__init__.py", line 12, in from .environment import Environment File "/home/masa/.venv/atcoder/lib/python3.10/site-packages/jinja2/environment.py", line 25, in from .defaults import BLOCK_END_STRING File "/home/masa/.venv/atcoder/lib/python3.10/site-packages/jinja2/defaults.py", line 3, in from .filters import FILTERS as DEFAULT_FILTERS # noqa: F401 File "/home/masa/.venv/atcoder/lib/python3.10/site-packages/jinja2/filters.py", line 13, in from markupsafe import soft_unicode ImportError: cannot import name 'soft_unicode' from 'markupsafe' (/home/masa/.venv/atcoder/lib/python3.10/site-packages/markupsafe/__init__.py) ```

私の使用している、テンプレートファイルと、.atcodertools.tomlを参考に載せておきます。

my_template.ex
defmodule Main do
    import Bitwise
    def next_token(acc \\ "") do
        case IO.getn(:stdio, "", 1) do
          " " -> acc
          "\n" -> acc
          x -> next_token(acc <> x)
        end
    end
    def input(), do: IO.read(:line) |> String.trim()
    def ii(), do: next_token() |> String.to_integer()
    def li(), do: input() |> String.split(" ") |> Enum.map(&String.to_integer/1)

{% if mod %}
    MOD = {{ mod }}
{% endif %}
{% if yes_str %}
    YES = "{{ yes_str }}"
{% endif %}
{% if no_str %}
    NO = "{{ no_str }}"
{% endif %}

{% if prediction_success %}
    def solve({{ actual_arguments }}) do

    end
{% else %}
    def solve() do

    end
{% endif %}

    def main() do
{% if prediction_success %}
        {{input_part}}
        solve({{ actual_arguments }})
{% else %}
        # Failed to predict input format
{% endif %}
    end

end
.atcodertools.toml
[codestyle]
indent_type='space' # 'tab' or 'space'
indent_width=4
template_file='~/atcoder-workspace-ex/my_template.ex'
workspace_dir='~/atcoder-workspace-ex/'
lang='elixir' # Check README.md for the supported languages.
#code_generator_file="~/custom_code_generator.py"
#code_generator_toml="~/atcoder-workspace/code_generator-ex.toml"
[postprocess]
#exec_on_each_problem_dir='clang-format -i ./*.cpp'
#exec_on_contest_dir='touch CMakeLists.txt'
[compiler]
#compile_command='g++ main.cpp -o main -std=c++17'
#compile_only_when_diff_detected=true
[tester]
compile_before_testing=true
compile_only_when_diff_detected=true
timeout_adjustment=1.2
[etc]
download_without_login=false
parallel_download=false
save_no_session_cache=false
skip_existing_problems=false
in_example_format="in_{}.txt"
out_example_format="out_{}.txt"

使い方(コード生成)

abc139コンテストの場合

atcoder-tools gen abc139

main.exのひな型が生成されます。

defmodule Main do
    def input(), do: IO.read(:line) |> String.trim()
    def ii(), do: input() |> String.to_integer()
    def li(), do: input() |> String.split(" ") |> Enum.map(&String.to_integer/1)


    def solve(a, b) do

    end

    def main() do
        a = ii()
        b = ii()
        solve(a, b)
    end

end

この問題は、二つの整数a,bが与えられるので、solveに与える引数もa,bとなっています。
オリジナルのatcoder-toolsでは、問題文の表記と同じA,Bと大文字の変数名が使われますが、Elixirでは大文字の変数名が使えないのですべて小文字に変換されます。

image.png

入力の値のプログラムの自動生成は、Elixirの対応はまだうまく行かない場合もあるので、あてにせず確認して下さい。
この課題のA Bが同じ行になっている場合、私の設定ではうまくいかず、

[a,b] = li()

とする必要があります。

テスト

solve関数を実装してテストしてみます。

defmodule Main do
    def input(), do: IO.read(:line) |> String.trim()
    def ii(), do: input() |> String.to_integer()
    def li(), do: input() |> String.split(" ") |> Enum.map(&String.to_integer/1)

    def get_ans(num_tap, socket, a, b) do
        cond do
         socket >= b -> num_tap
         num_tap == 0 -> get_ans(1, a, a, b)
         :true -> get_ans(num_tap+1, socket+a-1, a, b)
        end
    end

    def solve(a,b) do
        ans = get_ans(0, 1, a, b)
        IO.puts(ans)
    end

    def main() do
        [a, b] = li()
        solve(a, b)
    end

end

main.exのあるディレクトリで次のコマンドを実行すると、テストが実行されます。

$ atcoder-tools test

次のような感じで結果が表示されます。

image.png

問題のページにある例以外の値をテストした場合は、in_*.txtout_*.txtのファイルを追加すれば任意の値でテストできます。

提出

提出もでます。

$ atcoder-tools submit 

image.png

提出前に、テストを実行してOKの場合のみ提出する設定がデフォルトになっています。
この例では、すでに提出済みなので、エラーになっています。二度目の提出の場合は-uを付けます

まとめ

これで問題の回答に専念できる環境ができました。

ElixirでAtCoderに参加してみましょう!

2023/9/23

pip installのパスを変更しました。

6
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?