09 Aug 2010

TopCoder の問題文とシステムテストの入出力を取得する python スクリプト

しょぼいコードでも勇気を出して晒そうシリーズ.

python を手に馴染む程度に身につけたいのですが, まださほど書く機会がない. かつ, 最近競技プログラミングの問題をできていない. じゃあ python で競技プログラミングをやればいいじゃんと思ったのがきっかけ. Google Code Jam はどんな言語でも使えるし, Codeforces はたしか python に対応していたと思うんですが, わけあってまとまったデータを外部に送信することが制限されている環境でも問題をやりたい. TopCoder はアカウントさえあればシステムテストの入出力結果も得られるので, これをローカルに落としてくれば GCJ っぽく好きな言語で書けてテストもできるはず. というわけで TopCoder の問題文, システムテストのテストケースとその出力を取得しファイルに保存する python スクリプトを書いてみました.

使い方

BeautifulSoup, html2text に依存しているので, 事前に準備してください. 両方とも easy_install で入ります.

% easy_install BeautifulSoup
% easy_install html2text

コードは gist にあげてあります. コピペするなり wget するなりして入手します. ついでにパーミッションも与えてあげると良いでしょう.

% wget http://gist.github.com/raw/514061/72f17c8b111160e7deac58626d052fd0f29cfedf/tcget.py
chmod 755 tcget.py

オプションとして取得したい問題名と TopCoder のユーザー名, パスワードを与えます. この例では Member SRM 478 の KiwiJuice という問題を取得しています. 毎回ユーザー名・パスワードを入力するのが面倒な場合は, コードの15, 16行目にハードコードしても動くようになっています.

% ./tcget.py kiwijuice -u cou929 -p password

結果として 問題名と同じ名前のディレクトリが作成され, その中に問題文(problem_statement.txt), システムテストの入力(system_input.txt), システムテストの出力(system_output.txt)が保存されます.

% tree KiwiJuice/
|-- problem_statement.txt
|-- system_input.txt
`-- system_output.txt

0 directories, 3 files

problem_statement.txt はこんな感じ. まだちょっと見づらいです.

### Problem Statement


Taro has prepared delicious kiwi fruit juice. He poured it into N bottles
numbered from 0 to N-1. Each bottle has a capacity of **C** liters, and he
poured **bottles**[i] liters of kiwi juice into the i-th bottle initially.
...

system_input.txt は GCJ っぽくスペースと改行で値を列挙するようにしてあります.

10
5 8
0 0 0 0 0 0 0 0 0 0 10
10
5 8
0 0 0 0 0 10 10 10 10 10 10
...

system_output.txt はただ単に各テストの出力が改行区切りで羅列してあります. GCJ のように "Case #n" のようなプレフィックスははいっていません.

10
20
625
13364
...

サンプルのテストケースは大抵システムテストのはじめの数個と共通なので, あえて別ファイルを準備していません.

ヘルプもあります. -h か -help オプションを指定してください. optparse というモジュールで簡単にできます. python すごい.

% ./tcget.py -h
Usage: tcget.py  [options]

Search the specified problem of TopCoder, and save the problem statement and
it's input/output of system test as a file.

Options:
  -h, --help            show this help message and exit
  -u USER_NAME, --user_name=USER_NAME
                        user name of topcoder account
  -p PASSWORD, --password=PASSWORD
                        password of topcoder account

感想やTodo

TopCoder のサイトの html が汚すぎて大変でした. 今回は BeautifulSoup でスクレイピングして, 問題文は html2text でタグを取り除いたりしていますが, これがベストなのかはわかりません. あとはシステムテストのテストケースの書式がこれでいいのか, すべてのケースに対応できているのかに自信がないので, しばらくドッグフードを食べながら改良していきたいと思います.

python はまだ不慣れなので, ぜったいもっとスマートな書き方があるよなあと思いながら書いてる部分が多々あります. そういう部分も直していきたいです. あとはテストを書いたり, クラス化したり, python のモジュールの書き方を勉強したり, パッケージングの仕方を勉強したり, PyPI にあげたり, 余裕があったらしていきたいです.

コード

長いので最後にコードです. 大したコードでもないので gist にはりつけました. ローカルでは git で管理しています.

Fetch TopCoder problem statement, test cases and expected result of system test. And save these data to file. ? GitHub