yukicoder で初めて作問とテスターを担当しました
yukicoder contest 251 で初めて Writer と Tester をしました。いろいろ勉強になったり苦労したり楽しかったりしたので感想を書いておきます。
ついでにはてなブログを開設しました。
きっかけ
TLで作問したりテスター募集したりしているのを見て、面白そうだなと思いました(単純)。
ところで、最初は単発で出す予定だったのですが、2問目を作ったときに nmnmnmnmnmnmnm さんから下記の提案をもらいました。
これは取り引きなのですが、テスターをやるので、こちらが★3以下の問題を3つ出すのでテスターをお願いできませんか。あわせて5問で6/5に出せると良いと思っています。
— nmnmnmnmnmnmnm (@enuemuenuemuenu) May 14, 2020
これは私にとっても願ったり叶ったりだったので喜んでOKしました。
やったこと
作問を担当した各問題について、だいたい下記のステップをしました。順番は若干前後したり、行ったり来たりするものもあります。
1. 問題の素案を考える
2. 問題文を考えて入力する
3. 制約を決める
4. テストケース作成
5. ACコード作成
6. 答えの作成とテキストファイルの作成
7. 入力ファイル、出力ファイルのアップロード
8. ACコードを投げる
9. 自己チェック
10. 解説を書く
11. 難易度を設定する
12. テスター
1. 問題の素案を考える
良い感じの問題設定を思いつく必要があります。思いつき方はさまざまでした。
一番最初に手掛けた 無限すごろく は、小学校ぐらいのときにボードゲームをしていたときに計算した記憶があったので、そこから作成しました。
次に手掛けた 木の上の山 は、先に「全方位木DP」を使って何かいい設定はないかなというところから考えました。解法ありきの作問方式です。
最後の ベホマラー は、その時点で(私がテスターをした問題も含めて)5問だったので、もう1問欲しいねという話になり雑に考えた問題です。
2. 問題文を考えて入力する
誰が見ても問題が理解でき、誤解のない説明をすることに気を付けました。 yukicoder だとある程度テンプレートができているので、入力は比較的簡単にできました。 TeX も使えるので入力も簡単でした。
3. 制約を決める
無限すごろくは思考停止で 1018 にしました。
木の上の山は少し迷いました。計算量が O(NK) なので設定には割と自由度があります。 O(N2K) は落としたかったのでNもKも1000にしました。 PyPy でやってみると若干余裕があったので、片方または両方2000にするのも考えましたが、その時はテストケースをもう作っていたのもあり、多少余裕あってもいいやってことにしました。
4. テストケース作成
無限すごろくは入力が1つで出力も1つなので、テストケースの作成は簡単です。ケースも、最大ケースを入れるのは一応やりましたが、コーナーなどもないし適当に整数を選んでソートして終わりです。 Writer 初心者にはちょうどいい問題でした。
木の上の山は少し大変です。まず、木の入力を作るのはやったことがなかったです。
ランダム、一列、ウニ、の3つが基本かなと思ったので、これらを適当に生成しました。特に、ウニは全方位木DPがちゃんとできてない解法を落とすのに必要です。あとはこれらの組み合わせ(一列とウニ、など)も入れました。
なお、テストケースができたらテキストファイルに書き出す必要がありますが、これは下の正答を作ってから一緒に行いました。
ところで私は Local では Jupyter Notebook を使っているのですが、順次実行できるのがテストケース作成時に特に重宝しました。
- ランダムに作る関数を最初に作っておく
- 一列やウニの関数も作っておく
- 順番をシャッフルするケースではシャッフルする
- マニュアルで作ったものと組み合わせる場合は適宜組み合わせる
- small / medium / large の input をそれぞれ作って、順番にリストに入れていく
などを「試行錯誤しながら」進められるのがとても使い勝手が良かったです。
5. ACコード作成
自分の解法を作ります。
6. 答えの作成とテキストファイルの作成
3. と 4. から正答を作成します。
ここでも Jupyter が便利でした。例えば予め
def calc(n): # n に対する答えを返す
# hogehoge
return ret
をしておいて、答えを作るときは
for each n in list_N:
output_to_textfile(n, calc(n)) # 入力ファイルと出力ファイルに書き出す
みたいにすれば良いです。
7. 入力ファイル、出力ファイルのアップロード
yukicoder の機能でアップロードします。
8. ACコードを投げる
自分の想定解を投げてACできるかを確認します。
9. 自己チェック
問題文やテストケースなどに不備がないか確認します。
主に下記をしました。
- 問題文を読み直して、意味が通るか、誤解がないかを確認
- サンプルが分かりやすいものになっているか、サンプルの説明がおかしくないかを確認
- テストケースが制約を満たしているかを確認
- 特に木の問題では、入力がちゃんと木になっているかも確認します。これ自体も300点ぐらいの問題になりそうです。
- 小さいケースで愚直解を作ってみて、想定解と一致するかを確認
- テストケースのうち、サンプルに相当するものが、サンプルと一致しているかを確認
- 実行時間が想定とかけ離れていないか、実行時間に余裕があるかを確認
- アップロードしたファイルでも意図通り動いているか再度確認します。これは確認用のためだけのコードを書いて確認しました。(Submission が膨大になるので、別環境でやりました。)
愚直解との比較でも Jupyter が便利でした。
def calc(n): # 想定解
# hogehoge
return ret
と
def calc2(n): # 愚直解
# fugafuga
return ret
をしておいて、
for each n in list_N:
if calc(n) != calc2(n):
# ErrorMessage
で確認できます。木の上の山は、特に心配だったのでこれを念入りにやったのですが、愚直解を書くのも結構大変でした。
10. 解説を書く
解説を書きます。
11. 難易度を設定する
設定します。ちなみに、これは後でテスターさんから修正が入りました。私の設定は若干、低めになりがちだったみたいです。特に無限すごろくは★1.5から★2.5に2段階修正しました。結果の投票を見ても、修正して良かったと思います。
12. テスター
テスターさんにテストをお願いします。
自分がテスターを担当した問題も、だいたい上と同じようなチェックをしました。
各問題について
ここから少しネタバレを含みます。
(作成した順なのでコンテストでの順番とは異なります。)
無限すごろく
上でも書きましたが、シンプルな設定で初めての作問にしては良い練習になりました。
解法もシンプルで、行列累乗を初めてやる人にも良い練習になるかもしれません。逆に上級者にとっては虚無だったかも知れません。
木の上の山
これが一番自信作のつもりでした。全方位木DPについてはちょうど記事を書いていたので、そこからいろいろ考えて作りました。ちなみにこの問題の設定だと私のライブラリではそのまま対応できなくて、ライブラリの中身をいじらないといけなかったです。
ベホマラー
最初はバギクロスも入れたりしてもう少し難しい設定にする予定だったのですが、力尽きてこの形になりました。
Python 以外はよく知らないですが、 1018 ぐらいを超えると言語によっては困るというのをなんとなく知っていたので、必ず 1018 におさまる設定にしました。ただ、コンテスト後のTLを見ると、解法によっては途中計算の段階で 1018 を超えて困ったという意見がありました。私の解法だと問題なかったので気にしてませんでしたが、こういうのも気を付ける必要があるというのは発見でした。
ところでベホマラー知ってる人どれぐらいいるのかなと思ってましたが、アンケートによると、参加者のうち3分の2ぐらいが知ってたようです。
今日のゆきこ出た?「ベホマラー」を知ってた?
— きり (@kiri8128) June 5, 2020
「まんたん」の話や、IIIのベホマズンの消費MPの話に触れてる人がいるなどの反響も面白かったです。(私も作問中似たようなこと考えていたので。)
全体の感想
- コンテスト中は、不備がないかどうかを一番心配していました。今回はすべての問題に携わっていたので、何も来ないと暇なので順位表とかを眺めてました。
- 通す人数が想定通りかどうかも見てました。結果的にはまあきれいなのかなと思ってます。木の上の山は ★4.0 でも良かったかな。
- Clar が来るととても焦ります。今回は nmnmnmnmnmnmnm さんにも対応してもらったので助かりました。
- 作問を一度すると、頭が作問のことでいっぱいになります。なので、通常の精進はあまり進まないです。コンテストに出るときも、問題を見て「これはこういう作問ができるんじゃないか」みたいな関係ない考察もしそうになります。
- でもまあ全体としては勉強になることが多かったし、多くの人に解いてもらえたので良かったです。今後もできる範囲で続けようと思っています。
- 今回はジャッジが簡単なものばかりでしたが、スペシャルジャッジやインタラクティブ問題もやってみたいです。(これも考え始めると時間がめちゃくちゃ溶けます。)