Security News
Research
Data Theft Repackaged: A Case Study in Malicious Wrapper Packages on npm
The Socket Research Team breaks down a malicious wrapper package that uses obfuscation to harvest credentials and exfiltrate sensitive data.
2024/6/7にAtCoderがatcoder-toolsを含むコード自動生成ツールを特定のコンテストで禁止するルール変更を行いました。詳しくは『生成AIの台頭に伴うABCにおけるルール変更について』を御覧ください。
これに伴い、atcoder-toolsの入力解析を伴うコード自動生成機能をAtCoder Beginer Contestのコンテスト開催期間中に利用してコード生成を行うことはUnrated, Ratedでの参加を問わず禁止となります。 現行のatcoder-tools バージョン2.13.0 にはコンテストの種類を検知して生成をスキップする機能はありませんので、各自の責任において利用を避けて頂くようお願い申し上げます。
ライセンスにもありますように、このツールを利用したことで生じるあらゆる損害に対し、atcoder-tools管理者は何の責任も負いません。何卒ご了承くださいますようお願い申し上げます。
Python 3.6 以降で動作する AtCoder からサンプル入力をダウンロードしたりする際に便利なツールです。
このツールには次のような機能があります。
対応言語 | Contributor 1 | Contributor 2 |
---|---|---|
C++ | @kyuridenamida (generator, template) | @asi1024 (template) |
Java | @kyuridenamida (generator, template) | |
Rust | @fukatani (generator, template) | @koba-e964 (template, CR) |
Python3 | @kmyk (generator, template) | @penpenpng (generator) |
D | @penpenpng (generator, template) | |
Nim | @chaemon (generator, template) | |
C# | @chaemon (generator, template) | |
Swift | @firewood (generator, template) | |
Go | @nu50218 (generator, template) | @chaemon (generator, template) |
Julia | @yatra9 (generator, template) | @chaemon (generator, template) |
pip3 install atcoder-tools
ただのpip
だとPython 2系を使ってインストールされる可能性があるためうまくいかないかもしれません。
Tampermonkey(各種ブラウザで動作)でインストールすることが可能なUserscriptです。公開されている過去問を対象として、atcoder-toolsで自動生成されたコードをそのままAtCoderのスニペット上で利用できます。
https://kyuridenamida.github.io/atcoder-tools/
各問題ごとの解析結果などが載っています。
重要: かつてパスワード入力なしでログインを実現するためにAccountInformation.py
にログイン情報を書き込むことを要求していましたが、セキュリティリスクが高すぎるため、セッション情報のみを保持する方針に切り替えました。
今後はできるだけ保持されているセッション情報を利用してAtCoderにアクセスし、必要に応じて再入力を要求します。
過去のユーザーの皆様にはAccountInformation.py
を削除して頂くようお願い申し上げます。
atcoder-tools gen {contest_id}
コンテスト環境を用意します。atcoder-tools test
カレント・ディレクトリ上に実行ファイルと入出力(in_*.txt, out_*.txt)がある状態で実行するとローカルテストを行います。atcoder-tools submit
カレント・ディレクトリ上で実行すると対応する問題がサンプルに通る場合ソースコードを提出します。既にAtCoder上にその問題に対する提出がある場合、-u
を指定しないと提出できないようになっています。atcoder-tools version
現在の atcoder-tools のバージョンを出力します。atcoder-tools gen --help
でatcoder-tools gen
の引数の詳細について確認することができます。
例:
atcoder-tools gen agc001
cd ~/atcoder-workspace/agc001/A
g++ main.cpp
atcoder-tools test
--without-login
引数を指定するとログインなしでデータをダウンロードできます(一般公開されているコンテストのみ)。
$ atcoder-tools gen [contest_id] --without-login
usage: atcoder-tools gen
[-h] [--without-login] [--workspace WORKSPACE] [--lang LANG]
[--template TEMPLATE] [--parallel] [--save-no-session-cache]
[--skip-existing-problems] [--config CONFIG]
contest_id
positional arguments:
contest_id Contest ID (e.g. arc001)
optional arguments:
-h, --help show this help message and exit
--without-login Download data without login
--workspace WORKSPACE
Path to workspace's root directory. This script will create files in {WORKSPACE}/{contest_name}/{alphabet}/ e.g. ./your-workspace/arc001/A/
[Default] /home/kyuridenamida/atcoder-workspace
--lang LANG Programming language of your template code, cpp or java or rust or python or nim or d or cs or julia.
[Default] cpp
--template TEMPLATE File path to your template code
[Default (C++)] /atcodertools/tools/templates/default_template.cpp
[Default (Java)] /atcodertools/tools/templates/default_template.java
[Default (Rust)] /atcodertools/tools/templates/default_template.rs
[Default (Python3)] /atcodertools/tools/templates/default_template.py
[Default (NIM)] /atcodertools/tools/templates/default_template.nim
[Default (D)] /atcodertools/tools/templates/default_template.d
[Default (C#)] /atcodertools/tools/templates/default_template.cs
--parallel Prepare problem directories asynchronously using multi processors.
--save-no-session-cache
Save no session cache to avoid security risk
--skip-existing-problems
Skip processing every problem for which a directory already exists
--config CONFIG File path to your config file
[Default (Primary)] /home/kyuridenamida/.atcodertools.toml
[Default (Secondary)] /atcoder-tools/atcodertools/tools/atcodertools-default.toml
usage: atcoder-tools test [-h] [--exec EXEC] [--num NUM]
[--dir DIR] [--timeout TIMEOUT]
[--knock-out]
[--skip-almost-ac-feedback]
[--judge-type JUDGE_TYPE]
[--error-value ERROR_VALUE]
optional arguments:
-h, --help show this help message and exit
--exec EXEC, -e EXEC File path to the execution target. [Default] Automatically detected exec file
--num NUM, -n NUM The case number to test (1-origin). All cases are tested if not specified.
--dir DIR, -d DIR Target directory to test. [Default] Current directory
--timeout TIMEOUT, -t TIMEOUT
Timeout for each test cases (sec) [Default] 1
--knock-out, -k Stop execution immediately after any example's failure [Default] False
--skip-almost-ac-feedback, -s
Hide inputs and expected/actual outputs if result is correct and there are error outputs [Default] False,
--judge-type JUDGE_TYPE, -j JUDGE_TYPE
error type must be one of [normal, absolute, relative, absolute_or_relative]
--error-value ERROR_VALUE, -v ERROR_VALUE
error value for decimal number judge: [Default] 0.000000001
usage: atcoder-tools submit [-h] [--exec EXEC] [--dir DIR]
[--timeout TIMEOUT] [--code CODE]
[--force] [--save-no-session-cache]
[--unlock-safety]
[--judge-type JUDGE_TYPE]
[--error-value ERROR_VALUE]
optional arguments:
-h, --help show this help message and exit
--exec EXEC, -e EXEC File path to the execution target. [Default] Automatically detected exec file
--dir DIR, -d DIR Target directory to test. [Default] Current directory
--timeout TIMEOUT, -t TIMEOUT
Timeout for each test cases (sec) [Default] 1
--code CODE, -c CODE Path to the source code to submit [Default] Code path written in metadata.json
--force, -f Submit the code regardless of the local test result [Default] False
--save-no-session-cache
Save no session cache to avoid security risk
--unlock-safety, -u By default, this script only submits the first code per problem. However, you can remove the safety by this option in order to submit codes twice or more.
--judge-type JUDGE_TYPE, -j JUDGE_TYPE
error type must be one of [normal, absolute, relative, absolute_or_relative]
--error-value ERROR_VALUE, -v ERROR_VALUE
error value for decimal number judge: [Default] 1e-09
usage: ./atcoder-tools codegen [-h] [--without-login] [--lang LANG]
[--template TEMPLATE] [--save-no-session-cache]
[--config CONFIG]
url
positional arguments:
url URL (e.g. https://atcoder.jp/contests/abc012/tasks/abc012_3)
optional arguments:
-h, --help show this help message and exit
--without-login Download data without login
--lang LANG Programming language of your template code, cpp or java or rust.
[Default] cpp
--template TEMPLATE File path to your template code
[Default (C++)] /home/user/GitHub/atcoder-tools/atcodertools/tools/templates/default_template.cpp
[Default (Java)] /home/user/GitHub/atcoder-tools/atcodertools/tools/templates/default_template.java
[Default (Rust)] /home/user/GitHub/atcoder-tools/atcodertools/tools/templates/default_template.rs
--save-no-session-cache
Save no session cache to avoid security risk
--config CONFIG File path to your config file
[Default (Primary)] /home/user/.atcodertools.toml
[Default (Secondary)] /home/user/GitHub/atcoder-tools/atcodertools/tools/atcodertools-default.toml
~/.atcodertools.toml
に以下の設定を保存すると、コードスタイルや、コード生成後に実行するコマンドを指定できます。
設定ファイルはcodestyle, postprocess, tester, submit, etcのテーブルに分かれていて、codestyle.nimというようにテーブル名の後に.[言語名]で指定するとその言語のみに適用されます。
以下は、次の挙動を期待する場合の~/.atcodertools.toml
の例です。
indent_type='space'
スペースがインデントに使われる('tab'
を指定した場合はタブが使われる)
indent_width=4
インデント幅は4である (indent_width
が無指定の場合4
(nim言語以外), 2
(nim言語)が規定値として使われます。)
template_file='~/my_template.cpp'
コード生成テンプレートとして~/my_template.cpp
を使う
workspace_dir='~/atcoder-workspace/'
ワークスペースのルートは ~/atcoder-workspace/
lang='cpp'
言語設定は cpp
(提出時もしくはデフォルトのコードジェネレーター生成時に使われます)
code_generator_file="~/custom_code_generator.py"
カスタムコードジェネレーター ~/custom_code_generator.py
を指定する
code_generator_toml="~/universal_code_generator.toml"
ユニバーサルコードジェネレーター ~/universal_code_generator.toml
を指定する
exec_on_each_problem_dir='clang-format -i ./*.cpp'
exec_on_contest_dir='touch CMakeLists.txt'
clang-format
を実行して、最後にCMakeLists.txt
(空)をコンテスト用ディレクトリに生成するcompile_before_testing
テスト前にコンパイルを実行するか否かをTrue/Falseで指定。何も指定しないとFalseとなります。
compile_only_when_diff_detected
テスト前のコンパイルの際、元のソースに変更があった場合のみ実行するかをTrue/Falseで指定。何も指定しないとFalseとなります。
timeout_adjustment=1.2
問題文に記載された実行時間制限にこの値をかけた秒数がローカルテストの際の実行時間制限になります。例えばatcoderで制限時間2秒の問題は2x1.2=2.4秒となります。atcoderとローカルの実行環境が異なる場合の調整に使用してください。
なお、compile_before_testing
, compile_only_when_diff_detected
はいずれもtesterの引数で指定することも可能で、指定した場合はそちらが優先されます。
download_without_login=false
AtCoderにログインせずにダウンロードを行う機能を使わない (公開コンテストに対してのみ可能)parallel_download=false
データの並列ダウンロードを無効にするsave_no_session_cache=false
ログイン情報のクッキーを保存するskip_existing_problems=false
ディレクトリが既に存在する問題の処理をスキップするin_example_format="in_{}.txt"
テストケース(input)のフォーマットをin_1.txt, in_2.txt, ...
とするout_example_format="out_{}.txt"
テストケース(output)のフォーマットをout_1.txt, out_2.txt, ...
とする[codestyle]
indent_type='space' # 'tab' or 'space'
indent_width=4
template_file='~/my_template.cpp'
workspace_dir='~/atcoder-workspace/'
lang='cpp' # Check README.md for the supported languages.
code_generator_file="~/custom_code_generator.py"
[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"
また、以下のように提出時にコマンドを実行してその結果を提出することが可能です。C++以外のAC-libraryを自動に展開するような用途で用いることができます。下記の例はNim言語でACLのexpanderを実行しその出力ファイルを提出し、その後ローカルの出力ファイルを削除するという設定です。 なお、C++に関してはAC-libraryがatcoderのジャッジにも搭載されているためこのような設定は不要です。
exec_before_submit
提出前に実行するコマンドsubmit_filename
exec_before_submitを実行した結果提出するファイルが変わる場合に指定exec_after_submit
提出後に行う処理[submit.nim]
exec_before_submit='rm ./combined.nim | python3 ~/git/Nim-ACL/expander.py main.nim --lib /home/chaemon/git/Nim-ACL/ -s'
exec_after_submit='rm ./combined.nim'
submit_filename='./combined.nim'
標準のC++コードジェネレーターに倣って、
(CogeGenArgs) -> str(ソースコード)
が型であるようなmain
関数を定義した.pyファイルをcode_generator_file
で指定すると、コード生成時にカスタムコードジェネレーターを利用できます。
ユニバーサルコードジェネレーターはループ・配列アクセス方法等のいくつかの言語仕様を記述するだけでカスタムコードジェネレーターよりも簡単にコード生成することを意図して作成したジェネレーターです。設定ファイルのcode_generator_toml
で指定します。書き方は以下です。
以下のようにテーブルを定義します。各項目はダブルコーテーションあるいはシングルコーテーションを用いた文字列で指定します。Pythonのformatメソッドに渡されるため、波括弧等の文字を直に書きたい場合はエスケープする必要があります。 テーブルのキーは整数(int), 浮動小数(float), 文字列(str), およびこれら3つを使った1次元配列(seq), 2次元配列(2d_seq)となっています。
[index] ループインデックスの名称を指定します。1重目をi
, 2重目をj
で指定してください。省略可能で省略した場合はi, jが指定されます。Perl, PHPなどの言語で$i, $jなどとi, j以外の名前を指定しなければならないとき用のつもりです。
[loop] ループに関することを記述します
{loop_var}
, 回す回数は{length}
を用いてください。}}
とエスケープする必要があることに注意してください。[type] タイプ(int, float, str)のタイプについて記述します。例を参照してください。
[default] デフォルトの値について記述します。例を参照してください。注意: TOMLの表記に癖があるようで、ダブルコーテーション2つ(空の文字列)を表記する際にはstr='""'とするとよいようです。""""だとエラーになるようです。
[input_func] int, float, strについて入力時に呼び出す関数を記述します。
[arg] solve関数の引数の記述方法について指定します。int
, float
, str
, seq
, 2d_seq
について記述してください。{name}
が変数名, {type}
がseq
, 2d_seq
についてベースとなる型です。
[actual_arg] seq
, 2d_seq
についてsolve関数を呼び出す際の引数の渡し方について記述します。C++などでmoveをつかってメモリを節約したいときなどに指定できます。省略可能で、省略した場合はそのまま渡されます。
[access] 配列のアクセス方法について記述します。seq
, 2d_seq
について指定してください。{name}
で変数名, {index_i}
, {index_j}
でインデックス名を指定します。
以下は宣言・確保・入力を行うためのコードを記述します。いくつかを同時に行う方法も指定できます。いずれも一行または複数行に渡る指定が可能でセミコロン等の終端子も(必要な言語では)記述してください。
キーワードとして{name}
, {type}
はそれぞれ対象となる変数名、タイプ名で、上記で指定した{default}
が使えます。また、指定していれば{input_func}
も使えます。seq
, 2d_seq
の場合は{type}
はベースとなる型名になります(vector<int>
におけるint
)のでご注意ください。また、seq
の長さは{length}
, 2d_seq
の長さは{length_i}
, {length_j}
となっています。
seq
, 2d_seq
の確保の方法を記述します。seq
, 2d_seq
について宣言と確保を同時に行う方法について記述します。以下は入力コードの冗長性を下げる目的で指定するテーブルで省略可能なものです。指定方法についてはPythonの設定を参照してください。
seq
, 2d_seq
について確保と入力をまとめて行うことができる場合に記述します。省略した場合、上記で指定した確保と入力の方式を複合したものが挿入されますseq
, 2d_seq
について宣言・確保・入力をまとめて行うことができる場合に記述します。省略した場合、上記で指定した宣言と確保と入力の方式を複合したものが挿入されます例えばC++での設定方法は以下です。
base_indent = 1
insert_space_around_operators = false
# global変数宣言時の接頭辞
global_prefix = ""
# ループ
[loop]
header = "for(int {loop_var} = 0 ; {loop_var} < {length} ; {loop_var}++){{"
footer = "}}"
# タイプ
[type]
int = "long long"
float = "long double"
str = "std::string"
# デフォルト値
[default]
int = "0"
float = "0.0"
str = '""'
# 引数
[arg]
int = "long long {name}"
float = "long double {name}"
str = "std::string {name}"
seq = "std::vector<{type}> {name}"
2d_seq = "std::vector<std::vector<{type}>> {name}"
# 引数への渡し方
[actual_arg]
seq = "std::move({name})"
2d_seq = "std::move({name})"
# 配列アクセス
[access]
seq = "{name}[{index}]"
2d_seq = "{name}[{index_i}][{index_j}]"
# 宣言
[declare]
int = "long long {name};"
float = "long double {name};"
str = "std::string {name};"
seq = "std::vector<{type}> {name};"
2d_seq = "std::vector<std::vector<{type}>> {name};"
# 確保
[allocate]
seq = "{name}.assign({length}, {default});"
2d_seq = "{name}.assign({length_i}, std::vector<{type}>({length_j}));"
# 宣言と確保
[declare_and_allocate]
seq = "std::vector<{type}> {name}({length});"
2d_seq = "std::vector<std::vector<{type}>> {name}({length_i}, std::vector<{type}>({length_j}));"
# 入力
[input]
#int = "std::cin >> {name};"
int = "std::scanf(\"%lld\", &{name});"
#float = "std::cin >> {name};"
float = "std::scanf(\"%Lf\", &{name});"
str = "std::cin >> {name};"
例えばPythonでの設定方法は以下です。
base_indent = 1
insert_space_around_operators = true
# global変数宣言時の接頭辞
global_prefix = ""
# インデックス
[index]
i = "i"
j = "j"
# ループ
[loop]
header = "for {loop_var} in range({length}):"
footer = ""
# タイプ
[type]
int = "int"
float = "float"
str = "str"
# デフォルト値
[default]
int = "int()"
float = "float()"
str = "str()"
# 宣言
[declare]
int = ""
float = ""
str = ""
seq = ""
2d_seq = ""
# 確保
[allocate]
seq = "{name} = [{default}] * ({length})"
2d_seq = "{name} = [[{default}] * ({length_j}) for _ in {length_i}]"
# 宣言と確保
[declare_and_allocate]
seq = "{name} = [{default}] * ({length}) # type: \"List[{type}]\""
self.declare_and_allocate_2d_seq = "{name} = [[{default}] * ({length_j}) for _ in {length_i}] # type: \"List[List[{type}]]\""
# 入力関数
[input_func]
int = "int(next(tokens))"
float = "float(next(tokens))"
str = "next(tokens)"
# 入力
[input]
int = "{name} = {input_func}"
float = "{name} = {input_func}"
str = "{name} = {input_func}"
# 宣言と入力
[declare_and_input]
int = "{name} = {input_func} # type: int"
float = "{name} = {input_func} # type: float"
str = "{name} = {input_func} # type: str"
# 確保と入力
[allocate_and_input]
seq = "{name} = [{input_func} for _ in range({length})]"
2d_seq = "{name} = [[{input_func} for _ in range({length_j})] for _ in range({length_i})]"
# 宣言と確保と入力
[declare_and_allocate_and_input]
seq = "{name} = [{input_func} for _ in range({length})] # type: \"List[{type}]\""
2d_seq = "{name} = [[{input_func} for _ in range({length_j})] for _ in range({length_i})] # type: \"List[List[{type}]]\""
# 引数
[arg]
int = "{name}: int"
float = "{name}: float"
str = "{name}: str"
seq = "{name}: \"List[{type}]\""
2d_seq = "{name}: \"List[List[{type}]]\""
# 配列アクセス
[access]
seq = "{name}[{index}]"
2d_seq = "{name}[{index_i}][{index_j}]"
atcoder-tools gen
コマンドに対し--template
でテンプレートソースコードを指定できます。
テンプレートエンジンの仕様についてはjinja2 の公式ドキュメントを参照してください。
テンプレートに渡される変数は以下の通りです。
prediction_success 入力形式の推論に成功したとき True
、 失敗したとき False
が格納されている。この値がTrue
のとき次の3種類の変数も存在することが保証される。
mod 問題文中に存在するmodの整数値
yes_str 問題文中に存在する yes や possible などの真を表しそうな文字列値
no_str 問題文中に存在する no や impossible などの偽を表しそうな文字列値
#include <bits/stdc++.h>
using namespace std;
{% if mod %}
const long long MOD = {{ mod }};
{% endif %}
{% if yes_str %}
const string YES = "{{ yes_str }}";
{% endif %}
{% if no_str %}
const string NO = "{{ no_str }}";
{% endif %}
{% if prediction_success %}
void solve({{ formal_arguments }}){
}
{% endif %}
int main(){
{% if prediction_success %}
{{input_part}}
solve({{ actual_arguments }});
{% else %}
// Failed to predict input format
{% endif %}
return 0;
}
CONTRIBUTING.md を参照してください。
FAQs
Convenient modules & tools for AtCoder users, written in Python 3.6
We found that atcoder-tools demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
Research
The Socket Research Team breaks down a malicious wrapper package that uses obfuscation to harvest credentials and exfiltrate sensitive data.
Research
Security News
Attackers used a malicious npm package typosquatting a popular ESLint plugin to steal sensitive data, execute commands, and exploit developer systems.
Security News
The Ultralytics' PyPI Package was compromised four times in one weekend through GitHub Actions cache poisoning and failure to rotate previously compromised API tokens.