これはCompetitive Programming (1) Advent Calendar 2020の8日目の記事です。
AtCoder Tools for Swift
SwiftでAtCoderを楽しむ方が増えてきたので、kyuridenamidaさん作のAtCoder ToolsをSwift対応させてみました。主にSwift環境について記述しますが、後半でC++の場合についても説明します。
-
AtCoder Tools Swift対応版
swift
branchにあります。本家にもマージされていますが、こちらには追加のサンプルなどが入っています。 -
AtCoder Tools Xcode対応版
xcode
branchにあります。上記のswift
ブランチに加えてC++用のサンプルが含まれています。
AtCoder Toolsというのは、AtCoderから問題文やサンプルを取得して、ローカルテストや提出までできる超便利ツールです。
詳しくは「便利! AtCoder で競技プログラミングをするときに重宝する AtCoder Tools のご紹介」などを読んでみてください。
インストール方法
バージョン3.6以上のPythonが必要です。本家のAtCoder Toolsはpipでインストール可能ですが、上記の開発版をインストールするにはpoetryもインストールしておく必要があります。以下の手順でインストールできます。
$ cd (適当な作業ディレクトリを作ってそこに移動する)
$ git clone https://github.com/firewood/atcoder-tools.git
$ cd atcoder-tools
$ git checkout swift # C++の方は xcode
$ poetry install
オプション省略時には、設定ファイルを~/.atcodertools.toml
として作成する必要があります。workspace_dir
の指定は必須です。
swift
ブランチでは examples/swift/config.toml
に以下のような設定ファイルを用意してあります。
[codestyle]
#indent_type='tab'
indent_type='space' # 区切り文字はスペース (default)
#indent_width=4 # インデント幅は4 (default)
#workspace_dir='~/temp/atcoder-tools/examples/swift'
workspace_dir='.'
#lang='python'
lang='swift'
code_generator_toml='./codegen.toml' # コードジェネレータの指定、おそらく変更する必要はない
template_file='./template.swift' # コードテンプレートファイルの指定
コードジェネレータを指定することで、(浮動小数点の変数の型を変更したりなど)かなり細かいカスタマイズをすることができますが、カスタマイズしたい場合はそれほどないと思います。
コードテンプレートファイルのほうは、自前のライブラリ関数などを追加していくことになると思います。
無指定時のテンプレートファイルはこれです。template_file
で指定できます。
コンテストデータの取得
コマンドラインから atcoder-tools gen abc200
のように呼び出すと、コンテストデータを取得し、workspace_dir
の下のコンテスト名のディレクトリ(例えば abc200
)が作成されます。そこに問題毎のA
B
C
D
E
F
のようなディレクトリが作成され、それぞれのディレクトリの下にmain.swift
が生成されます。
swift
ブランチでは examples/swift/gen.sh
にシェルスクリプトを用意してあります。
このシェルスクリプトでは gen
コマンドを呼び出したあと、project_files
にあるプロジェクトファイルをコンテスト名のディレクトリにコピーします。
$ cd examples/swift
$ ./gen.sh abc200
Xcodeで編集する
Xcodeで編集するにはCommand Line Toolのプロジェクトを作成する必要があります。
上記の gen.sh
では abc200/A/ProblemA.xcodeproj
が生成されるようになっています。
$ cd abc200/A
$ xed .
のようにしてプロジェクトを開くと、以下のように、パラメータの入力部分を含んだmain.swift
が自動生成されているはずです。(問題によっては解析に失敗することもあり、その場合はmain
関数だけが生成されます)
あとはsolve関数の中身を埋めるだけになっています。
import Foundation
func solve(_ N:Int) {
var ans = 0
print(ans)
}
func main() {
var tokenIndex = 0, tokenBuffer = [String]()
func readString() -> String {
if tokenIndex >= tokenBuffer.count {
tokenIndex = 0
tokenBuffer = readLine()!.split(separator: " ").map { String($0) }
}
defer { tokenIndex += 1 }
return tokenBuffer[tokenIndex]
}
func readInt() -> Int { Int(readString())! }
func readDouble() -> Double { Double(readString())! }
let N = readInt()
_ = solve(N)
}
#if DEBUG
let caseNumber = 1
_ = freopen("in_\(caseNumber).txt", "r", stdin)
#endif
main()
Xcodeでデバッグする
AtCoderのように標準入力を前提とするプログラムをデバッグするときは、Xcodeのコンソールに入力を貼りつける必要があります。ただ毎回手入力したくないので、ローカル環境で試すときには、AtCoder Toolsで取得したテストケースのファイルを標準入力にリダイレクトするようにしてみました。(上のコードのfreopen
)
これにより手元(DEBUG
定義時)ではファイルから、提出時には標準入力から入力できます。提出時にファイルを書き換えたりする必要もありません。caseNumber
を変えれば任意のテストケースでデバッグできます。
これを行うためにはデバッグ時のカレントディレクトリを入力ファイルのあるディレクトリにしておく必要があります。Product -> Scheme -> Edit Scheme... から変更できます。たとえば$(PROJECT_DIR)
とするとプロジェクトのディレクトリにできます。そうするとプロジェクトファイルをコピーしたときでも使えます。(swift
ブランチのサンプルではこの状態になっています)
実行すると、キーボード入力を待たずに結果が出力され、プログラムが終了するはずです。
XcodeのバージョンによってはDEBUG
が未定義かもしれません。その場合はプロジェクトのBuild SettingsのSwift Compiler - Custom FlagsのActive Compilation ConditionsのDebugのところにDEBUG
を追加します。(下図)
まとめてテスト&提出する
Atcoder Toolsのtestコマンドにより、全てのサンプルでテストできます。これは例えばこういう感じのMakefileを用意しておくといいと思います。(サンプルにあります)
.PHONY: test submit resubmit
test: build
atcoder-tools test
submit: build
atcoder-tools submit
resubmit: build
atcoder-tools submit -u
build: a.out
a.out: main.swift
swiftc $< -o $@
この例だとmake
とmake test
は同じで、全てのサンプルをテストします。
大丈夫そうであればmake submit
で提出できます。テストが通らないと提出できませんが、テストケースと完全一致しない場合もあるので、そういうときは手動でコピー&ペーストして提出してください。
make resubmit
で再提出可能です。
C++の場合
ほぼSwiftと同じです。xcodeブランチのexamples/cpp/
以下にプロジェクトファイルのサンプルがあります。
このサンプルを試すには、AtCoder Libraryを/usr/local/include
以下にインストールしてください。(つまり/usr/local/include/atcoder/modint
などが存在する状態)
おわりに
私は普段もっぱらC++でコンテストに参加していますが、これからはSwiftでも復習していきたいなと思っています。不具合や改善点などあれば、コメント欄やTwitterでぜひ教えていただきたいです。
Xcodeで楽しいAtCoderライフを送りましょう!
宣伝
競技プログラミングのコンテストカレンダーを作っていますのでよかったらご利用ください。主に短時間のコンテストを載せています。
自分のGoogle Calendarに追加することもできます。
https://competitiveprogramming.info/calendar
Swiftでの競技プログラミングで役立つ記事
-
便利! AtCoder で競技プログラミングをするときに重宝する AtCoder Tools のご紹介
- 非常に便利なツール
-
[AtCoder]Swiftでも競プロがしたい!
- AtCoderの登録のところから説明している
-
Swift版 競プロ用チートシート(初心者向け)
- AtCoder ABCなどで頻出の基本的なアルゴリズム
-
Swiftで競技プログラミング
- 標準入力から変数をタプルで受け取りたい時のテクニック
-
AtCoderSupport
- Swiftによる様々なアルゴリズムと実装例
-
Swift Algorithm Club
- 大量のアルゴリズムサンプル
編集履歴
- 2021-05-03: Swiftブランチが本家に取り込まれたため、記述を更新
- 2021-10-01: 生成されるディレクトリ名をツールの標準の方法にして、gen.shを整えた