Observed since 20 Oct, 17:49 UTC
No superseded metadata states collected. Unchanged observations do not create new revisions.
acac
競プロ便利 CLI ツール。AtCoder と アルゴ式 に対応。
競プロ便利 CLI ツール。AtCoder と アルゴ式 に対応。
*現在 Pre-release のため、挙動やコマンドは変更される場合があります。
競技プログラミングの過去問を解くときの(個人的に)典型的なワークフローを CLI として自動化したものです。
過去問だけでなく開催中のコンテストでも使えますが、ログイン機能は実装されていないため、手動で HTML ファイルを取得する必要があります。
Python 3.9 以上がインストールされていれば利用可能です。
pip install acac
作業ディレクトリに移動して、acac init を実行します。
# 例
mkdir kyopro
cd kyopro
acac init
acac.toml が作成されます。これが設定ファイルです。
まず、ブラウザで問題ページ(例えば、ABC 280 A - Pawn on a Grid)にアクセスします。
URL をコピーします
ターミナルで以下のようなコマンドを実行すると、問題用のフォルダ(以下、問題フォルダ)に環境が自動作成されます。
acac https://atcoder.jp/contests/abc280/tasks/abc280_a
cache.html が無ければ)問題ページにアクセスし、HTML ファイルを cache.html として保存します。metadata.toml を作成します。
acac.toml で設定したコマンドを実行します。acac.toml で設定したメッセージをクリップボードにコピーします。
コードを書いて問題を解きます。
ターミナルで以下のようなコマンドを実行します。
acac https://atcoder.jp/contests/abc280/tasks/abc280_a -j
すると、以下のように処理されます。
acac.toml で設定したコマンドを実行します(バージョン確認、コンパイル等)。acac.toml で設定したコマンドを実行します(クリーンアップ等)。y と答えれば、同じ言語で AC した提出の一覧ページをブラウザで開きます。acac.toml で設定したメッセージをクリップボードにコピーします。私が実際に使用している設定ファイルは こちら です。
# 設定ファイルの例
[create]
# 環境作成後に実行されるコマンドのリスト(以下は git add をして、VSCode でソースコード用のファイルを開いている)
post_create_commands = [
"git add ${dir_path}/in ${dir_path}/out ${dir_path}/metadata.toml",
"code . ${dir_path}/${source_file_name}",
]
# 環境作成後にクリップボードにコピーされるメッセージ
clipboard_message = "Create: ${url}"
[judge]
# ジャッジ後にソースコードをクリップボードにコピーするかどうか
copy_source_code_when_ac = true
# ジャッジ後にクリップボードにコピーされるメッセージ
clipboard_message = "AC: ${url} ${source_file_name}"
[language]
# デフォルトの使用言語
default = "cpp"
[language.settings.cpp]
# ソースコードのファイル名
source_file_name = "main.cpp"
# テンプレートファイルのパス
template_file_path = "templates/main.cpp"
[language.settings.cpp.commands]
# ジャッジ前に実行するコマンドのリスト(以下はバージョンを表示し、コンパイルしている)
pre_execute = [
"g++ --version",
"g++ ${dir_path}/${source_file_name} -o ${dir_path}/a.out",
]
# 実行コマンド
execute = "${dir_path}/a.out"
# ジャッジ後に実行するコマンドのリスト(以下は `a.out` を削除している)
post_execute = ["rm ${dir_path}/a.out"]
[language.settings.python3]
# ...
${var} の置換リスト| 置換前 | 置換後 |
|---|---|
| ${dir_path} | 問題フォルダのパス |
| ${lang} | 言語名 |
| ${source_file_name} | ソースコードのファイル名(パスではありません) |
| ${url} | 問題ページの URL |
| オプション | モード |
|---|---|
| -c, --create | 作業環境構築(デフォルト) |
| -j, --judge | ジャッジ |
| -m, --manual | URL にアクセスせず、HTML ファイルを手動で配置してテストケースを作成する |
ログインが必要な場合、acac <url> -m を実行後、問題フォルダに問題ページの HTML ファイルを配置してください。
acac.toml に指定したデフォルト値を一時的に上書きするような動きをします。イコールは必須です。
| オプション | 上書きされるもの |
|---|---|
| -l, --lang, lang=LANG_NAME | 使用言語 |
| -s, --source, source=SOURCE_FILE_NAME | ソースコードのファイル名 |
# 例
acac https://atcoder.jp/contests/abc280/tasks/abc280_a -l=python3 --source=main2.py
acac https://atcoder.jp/contests/abc280/tasks/abc280_a -s=main2.py lang=python3 --judge
acac create <url> や acac judge <url> のような一般的な CLI の慣例に沿っていないのかacac <url> で環境作成-j をつけてジャッジという流れを高速で行うためです。基本的に、一つの問題に対し複数のコマンドを実行することが多いので、URL のあとにコマンドやオプションを指定する方式を採っています。
開発当初は AtCoder/ABC/280/A/ のようなフォルダ構成にしていましたが、過去のコンテストの URL 規則との整合性や、未来への拡張性、ghq のような厳密性を保持するため、現在のような形にしました。
Download counts and popularity will appear here as the collector receives them.
| Package / target | Requirement | Relationship |
|---|---|---|
beautifulsoup4Environment{
"extras": "",
"marker": null,
"requires_python": "<4.0,>=3.9",
"evaluation": "NOT_EVALUATED"
} | beautifulsoup4<5.0.0,>=4.11.1 | runtime |
lxmlEnvironment{
"extras": "",
"marker": null,
"requires_python": "<4.0,>=3.9",
"evaluation": "NOT_EVALUATED"
} | lxml<6.0.0,>=4.9.1 | runtime |
pydanticEnvironment{
"extras": "",
"marker": null,
"requires_python": "<4.0,>=3.9",
"evaluation": "NOT_EVALUATED"
} | pydantic<3.0.0,>=1.10.1 | runtime |
pyperclipEnvironment{
"extras": "",
"marker": null,
"requires_python": "<4.0,>=3.9",
"evaluation": "NOT_EVALUATED"
} | pyperclip<2.0.0,>=1.8.2 | runtime |
readcharEnvironment{
"extras": "",
"marker": null,
"requires_python": "<4.0,>=3.9",
"evaluation": "NOT_EVALUATED"
} | readchar<5.0.0,>=4.0.3 | runtime |
requestsEnvironment{
"extras": "",
"marker": null,
"requires_python": "<4.0,>=3.9",
"evaluation": "NOT_EVALUATED"
} | requests<3.0.0,>=2.28.1 | runtime |
richEnvironment{
"extras": "",
"marker": null,
"requires_python": "<4.0,>=3.9",
"evaluation": "NOT_EVALUATED"
} | rich<14.0.0,>=12.5.1 | runtime |
tomliEnvironment{
"extras": "",
"marker": null,
"requires_python": "<4.0,>=3.9",
"evaluation": "NOT_EVALUATED"
} | tomli<3.0.0,>=2.0.1 | runtime |
tomli-wEnvironment{
"extras": "",
"marker": null,
"requires_python": "<4.0,>=3.9",
"evaluation": "NOT_EVALUATED"
} | tomli-w<2.0.0,>=1.0.0 | runtime |
typing-extensionsEnvironment{
"extras": "",
"marker": null,
"requires_python": "<4.0,>=3.9",
"evaluation": "NOT_EVALUATED"
} | typing-extensions<5.0.0,>=4.3.0 | runtime |
bdist_wheel · 14.79 KB · Python py3
sdist · 13.05 KB · Python source
Observed since 20 Oct, 17:49 UTC
No superseded metadata states collected. Unchanged observations do not create new revisions.
package_version:cedb21e8cb8ab0b35fc9ea8f46b59adbaf6df3156dd6e2a527965b1a0e794a6d