競プロ始めました-kaede2020-

競技プログラミング初心者向けのブログです

RECRUIT 日本橋ハーフマラソン 2024冬(AtCoder Heuristic Contest 029)参加記

0.はじめに

はじめまして、もしくはお久しぶりです、競プロ歴約4年のかえでです。

今回は、RECRUIT 日本橋ハーフマラソン 2024冬(AtCoder Heuristic Contest 029)に参加しました。開催期間は2023年12月22日(金)12:00から2023年12月26(火)21:00までの5日間の長期コンテストでした。

さて、今回は体調がすぐれない中でのスタートになりました。いったいどこまでできるのかはわからないのですが、やっぱり記録は取っていた方が良いのではないかと思い、参加記を書きながら始めることにしました。

復習をするときにも自分が何を考え、どんなことをしたいと考えていたのかを振り返ることができるので、参加記を書くことは全ての参加者におすすめしたいところです。また参加していなかった人にも、どんな問題だったかを伝えることができるので、参加者を増やしたいと思っている自分には参加記を書くことは必要なことだと思っています。

とはいうものの、内容に関しては余分な部分も多くあります。軽い読み物として読んでもらえればと思っています。そして解説要素が欲しい方はもっと上位の方の解説を読むことをおすすめします。

それでは始めましょう。

1.問題文を読む

atcoder.jp

おー、題材がお仕事だ!と問題文を読んでわくわくしました。

会社を経営するゲームなので、社長になったつもりで采配を行えばよいのですね!ゲーム終了時の所持金を最大化することが目的です。インタラクティブ形式です。その場の形勢に合わせて判断していくことが必要なようです。

Business Simulation Gameというタイトルがついていました。

  • Tターン行う(T=1000)
  • 方針カードN枚を持っている。方針は5種類
    • 通常労働カード(正の労働力が決まっている。指定したプロジェクトの残務を労働力分減らす)
    • 全力労働カード(全てのプロジェクトの残務を労働力分減らす)
    • キャンセルカード(指定したプロジェクトの実行をやめる)
    • 業務転換カード(全てのプロジェクトの実行をやめる)
    • 増資カード(その後現れる労働力とコストが2倍になる)
  • M個のプロジェクトを持っていて、残務量と価値がわかる。
  • N枚のカードから1枚を選んで実行する
  • プロジェクトから残務量が減って0以下になるとプロジェクトが消えて、価値が所持金に足される。また、その分の新しくプロジェクトが足される。
  • K枚のカードの中から方針カードを1枚引く。カードのコストが引かれる。
2.最初の考察

何がわからない部分なのかを考えます。どうもプロジェクトをキャンセルすると別のプロジェクトを入れることができそうです。

  • 新しいプロジェクトを受け取ったときにその場で判断でき入ると良さそうです。
  • 途中でお金が足りなくなって労働力を強化することもできずTターン内に終わらないと良くなさそうです。
  • 労力のわりに収益が悪いプロジェクトはやらない方が良い可能性があります。

ローカルテスタで使用する入力ファイルも読みます。全部の入力が与えられているので、最適に選んだ場合の所持金がいくらになるかを最初に計算した方が良さそうです。

ん、増資カードが肝っぽい感じがします。適切な場所でレベルアップ(増資)していくことが必要な気がします。これだけが回数20回という制限がついています。なるほど~。

3.サンプルコードを理解する

サンプルコードがついていたので提出しました。絶対スコア54,598が出ます。

サンプルコードの絶対スコア:54,598

このサンプルコードの内容が問題文に書いてありました。

AtCoder問題文より引用

これをビジュアライザで見たいのですが、seed0をリダイレクトで実行すると、outputファイルが生成される前にassertが出て3ターン目で終わっている模様...。どうして?

asserのメッセージ:所持金がマイナスになっている?

そういえば、インタラクティブなので、ローカルで実行する際は、応答部分を自分で書かなければいけませんでした。ローカルで実行する際の入力も読みこんでいませんでした。というわけでローカルでの応答部分を実装します。

4.ビジュアライザを見る

その前に入力と出力について良く読んだら、実装前にサンプルコードのビジュアライザの出力をExcelで書くことができました。方針カードを出す(0 0)と補充するカードを選ぶ(0)を交互に1000ターン出力すればOKでした。

ビジュアライザをやっと見ることができました!

ただアニメーションで再生すると、カードの点滅が嫌な感じがして見続けることができません。スピードを遅くすると進行を表すためのカードをめくるアクションのために色の変化をつけているようでした。正直なところグレーの色がなければよかったなぁ…。文句を言う前に早く自分でビジュアライザを実装できるようになろうと思いました。

seed0のビジュアライザ サンプルコード score=857
5.考察の続き
  • 労働力が大きいカードを選ぶ
  • 割の良いプロジェクトを選ぶ
  • お金がたまったら増資カードを買う

そんな貪欲をするだけでも今よりよくなりそうです。

何番目のカードかをサンプルコードでは保存していなかったので、idを追加します。その後カードを選ぶ方法を実装したので、提出します。

(え?テストケースも実行せずに提出するんですか?)

結果はWAで0点。相対スコアは769点でした(サンプルコードの相対スコアは2023年12月22日午後10時現在で388,309,021点)。

提出結果はWA

相対スコア

うん、ローカルのテスト環境を作りましょう。

割とコードはうまく書けている気がしたのですがやはりテスケースの実行は必要ですね…。ローカルの実装を書きましたがまだバグっています。面倒だなぁという気持ちに。体調が良くないのもあるかもしれません。今日はもう寝たいと思います。

6.コンテスト2日目はTLEの嵐

翌日の朝です。早くも問題文の誤読に気がつきました。

  • 方針カードを使ったら、次に選んだ方針カードは使ったカードの場所に補充される
  • プロジェクトが遂行されたら、次の新しいプロジェクトは完遂したプロジェクトの場所に補充される

そうなのかー。昨日つけたidもいらなさそうです。気を取り直して実装します。

何とかローカルを読み込みました。方針カードの最初の手持ちのN枚がコストが入っていないことに気がつかずに苦労しました。

出力デバッグを続けて修正し、だいたいの入出力は合ってきたように思います。ただ肝心の選択する貪欲がイマイチなのでスコアは低いままです。ACできるかを確認するために一旦提出してみることにします。全てTLEして得点は0点になりました。

うーん、バグってそう。

提出結果はTLE

順位表の得点もなし

やっとローカルの結果とビジュアライザの結果が同じになりました。seed0のスコアは1476になりました。

seed0のビジュアライザ score=1476

提出をするとまたもやTLE。うーん、どこだろう?インタラクティブ、難しい…。2時間半経過しているものの3連続TLEで焦ります。疲れたので寝ます。

3連続TLE

お昼寝して起きたら、何とかデバッグして間違いに気がつきました。1回多く入力を読み込んでいました(だから出力するタイミングで入力を待っていたのでTLEしていました)。提出します。

ACしました!よかった。

絶対スコアは132,330、相対スコアは363,723,271、426人中179位になりました。このままACできずに終わるのかと思ったのでホッとしました。なお、サンプルコードの相対スコアは現在255,823,663です。現在のトップはyunixさんで30,910,887,631。100倍ほど離れていますが、増資カードが2のべき乗なので、このカードをうまく使えるのがポイントなんだろうなあと思っています。 

絶対スコア:132,330

相対スコア:363,723,271 179位/426人中

100テストケースを回して結果を見ます。今やっていることです。

  • 方針カードの選択方法(優先順位の高い順)
    • 増資カードを持っていたら使う
    • プロジェクトの残務量以上、残務量+5以下の労働カードがあれば使う
    • 残務量が価値より大きいときキャンセルカードや業務転換カードを使う
    • 最小の労働カードを残務量が一番少ないものに使う
  • 補充カードの選択方法
    • 増資カードが買えるなら買う
    • 残務量より価値が大きいものを買う

良さそうに思えることを適当にやっているだけなのでもう少し詰めたいところですが、100テストケースの結果は倍以上良くなりました。

100テストケースの結果

スコアそのままだとカードの無駄遣いをしてしまうので、評価関数をうまく考えたいところです。情報が少ないので、後ほど入力値を分析したいと思います。

7.方針カードの選択を改善したら2桁順位、青パフォが出た

ビジュアライザのseed58を見ながら考察をします。手持ちの方針カードはいろいろとあるのに、wの大きい労働カードを使わずに最小の労働カードばかりを選んでいます。そこで、

  • 残りの残務量が一番小さくなるような方針カードとプロジェクトの組み合わせを使う

ことにしました。

すると、seed0の値が7647に急上昇しました。

おお!

100テストケースを回します。平均は23301になり、ほぼ10倍になりました。

提出をします。絶対スコアは1,357,815になり、相対スコアは1,267,114,218、466人中88位になりました。2桁順位に上がり、青パフォが出ました。

テンションが上がります。

絶対スコア:1,357,815

相対スコア:1,267,114,218 88位/466人中

ここで21時になったので、今年最後のABCに参加することにしました。結果はAとDの2問が解けました。うーん、難しかった…。来年もがんばろう。

風邪はまだ良くならないので、今日はこの辺で終了したいと思います。

と思ったのですが、まだやっています(お風呂に入って戻ってきたところ)。

最後にカードを使い切るようにして、無駄なカードを買わないことにしました。100テストケースの平均は50745と倍になったので提出します。絶対スコアは上がりましたが、相対スコアは1,153,044,737と下がりました。徐々にトップと離されているんだなあと思います。順位は499人中86位と少しだけ上がりました。

絶対スコア:2,265,351

相対スコア:1,153,044,737 86位/499人中

今度こそ本当にお休みなさい。

明日(0時を過ぎたので厳密には今日)は全力労働カードをうまく使えるようにしたいなぁ。夜更かしできるようになったので、だいぶ体調も良くなってきたのかもしれません。昨日は午後10時前に寝ていたので。

8.入力生成値の分析

コンテスト3日目の朝です。今気になっているのは、どのくらいのコストを払って補充カードを購入するかということです。あと隠れパラメータの推測も追加した方が良さそうだと思っています。増資カードが肝なので、出現確率が低かったら高くても買うべきだし、出現確率が高かったら次に出るまで待った方が良さそうです。ちょっと雑なのですがseed0の入力値です。

seed0の入力値

さてまだ入力値は分析中なのですが、別のことを試します。

労働力が残りの残務より大きくても使える範囲を無料労働力5回分までOKに広げるとスコアは2倍近く増えました。

提出してみると絶対スコアは上がりましたが、相対スコアは変わりませんでした。

絶対スコア:5,794,385

相対スコア:1,016,307,192 114位/549人中

残りのターンで無料の労働力だけでは全てのプロジェクトが終わらないときにキャンセルカードを補充することにしました。100テストケースの得点はさらに1.5倍になりました。先ほどは悪くなったものが100ケース中35個くらいありましたが、今回は悪くなったものは15個に減りました。

先ほどよりはさすがに上がりそうと思ったので提出をします。

絶対スコア:5,248,504

相対スコア:1,097,388,543 108位/550人中

あれ?絶対スコアは下がってしまいました。相対スコアは少し上がりました。

なるほど~。1000ターン終わる前にスコアを確定させても良いのかもしれません。いちばんMONEYを持っているときに、補充カードにお金を使うのをやめてみたいと思います。まずはターン中の最大MONEYを出力してみることにします。見づらいので軸を対数目盛にしました。ケース毎の差が結構大きなと思います。

最大値が現れるのは平均970ターン位でした。かなり終盤ですね。

ターン中の最大MONEY(100ケース)

だんだん考えがまとまってきたのですが、たとえば800ターンより後ろになったら、これから出るカードを予想しながらプロジェクトを遂行し、970ターン前後でこれくらいかなというMONEYを得たらSTOPするみたいなことができればなあと思っています。

最大MONEY獲得後に何をしているかをビジュアライザで確認します。

終盤にカードを買って良い条件を考えます。

  • そのカードを買うことによって、今あるカードと無料のカードでプロジェクトを終わらせることができ、なおかつカードを買う前よりも所持金が増えること

おおー、シンプルに言語化できたので実装します。950ターン以降の無駄遣いを制限、980ターン以降、900ターン以降と試して、900ターン以降が一番よかったので提出します。結果は1WAで絶対スコアは0でした。相対スコアは1,531,552,312になり、順位は提出前の121位から98位に上がりました。2桁順位復帰です。

絶対スコアは0

相対スコア:1,531,552,312 98位/604人中

一番スコアのよかったseed45のビジュアライザです(再生時のアニメーションをかなり間引いています)。絶対スコアが良いものが相対スコアも良いとは限らないのですが、増資カードが13回使われています。

seed45のビジュアライザ score=3843074

N(手持ちの方針カード数)とM(プロジェクト数)、K(補充カード数)によって戦略を変えた方が良い気がしてきたので、結果を分析します。雑ですが、こんな感じ。テストケースが少ないので、あまりきれいではないですね。プロジェクト(M)が少ないときにスコアが悪いのはキャンセルカードをあまり使っていないからのような気がします。補充カード数(K)が少ないときも苦手そう。というか、Kが2のときは1枚が無料カードなので、かなりカードの取捨選択が難しそうです。

 

N,M,Kとスコアの関係

キャンセルカードの使い方をSINGLEとALLで分けていなかったので分けました。

提出するとまた1個WA。ん、公式ジャッジツールの出番ですね。

順位は101位から99位に上がりました。

相対スコア:1,594,518,616 99位/614人中

100テストケースでは公式ジャッジツールを用いてもWAが出ませんでした。テストケースを増やします。500テストケースで3個WAになりました。エラーメッセージは"Not enough money"です。詳細を調べます。

キャンセルカードを買うときのif文にカッコをつけ忘れている箇所と同じ個所のカードタイプを間違えていました。コードを修正して提出します。

無事にACしました。絶対スコアは18,815,648、相対スコアは1,522,946,724、620人中98位になりました。

絶対スコア:18,815,648

相対スコア:1,522,946,724 98位/620人中

損をするカードを買わないことにしてみます。絶対スコアは伸びましたが、相対スコアは上がりません。

絶対スコア:23,015,938

相対スコア:1,502,708,737 99位/622人中
9.キャンセルカードで割の合わない仕事をキャンセルする

割の合わない仕事がある場合にキャンセルカードを買うことにします。割の合わない仕事はwよりhが大きいプロジェクトとします。実装して100テストケースを回すと、3倍くらいスコア平均が伸びました。

提出します。

提出制限にひっかかっているところ

あ。まだ先ほどの提出から30分間経っていなくて提出制限に引っかかってしまいました。この時間がもどかしく感じます(大体こういう待ち時間にブログを書いています)。

やっと提出できました。

おっしゃーっ!!!

ACした後に絶対スコアを見て思わずガッツポーズをしていました。絶対スコアは前回の約4倍、93,819,092になっていました。

絶対スコア:93,819,092

どきどきしながら順位表を見ます。

!!!

41位!

やったー!!!

もう一度ガッツポーズ。初めての黄パフォです。順位表を見ながらドキドキが止まりません。

相対スコア:2,982,417,626 41位/629人中
10.黄パフォの理由を考える

お風呂に入って落ち着きました。ということは時刻はもう夜です。

何だかうまくいきすぎています。解法ガチャに当たっている気がします。自分には自明だけど他の人には自明ではない何かがありそうです。考えてみました。

  • 増資カードが肝要である
    • これは最初から思っていたことです。この問題を読んだときからレベル上げゲームだなあと思っていました。頭の中には過去の「RECRUIT 日本橋ハーフマラソン 2021〜増刊号〜」の問題が思い浮かんでいました。早くレベルを上げることができると勝ちます。
  • 割の合わないプロジェクト、割の合わない労働カードを選ばない
    • これは本当に適当に線引きをしていて、多分NやKが大きいときには引き上げることができると思っています。今はこんな感じで半分を却下しているつもりでいます。

      プロジェクトの半分を却下している

ここまで、全部IF文の条件分岐で書いています。コードの長さは600行ほどで大した量ではありません。インタラクティブ問題は初心者にも夢があってうれしいなぁと思います。というか、もう私は初心者ではないのかもしれません。少し前から何となく気がついていました。成長の理由はAtCoderに入社したことが大きいと思っています。本当に競プロerにとって幸せな環境だと思います。

さて、次の改善に取り組みたいと思います。

11.労働カードを厳選する

選ぶ基準を労働力(h)とコスト(w)が同等以上にしていましたがコストの1.1倍以上のカードにします。100テストケースを回すと、平均が倍になりました。

あ、これはいけるかも。

1.2倍、1.3倍、1.4倍とコストと労働力の比率を高めたカードを選ぶようにしていきます。1.4倍で下がり始めたので1.3倍で提出してみました。絶対スコアは120,865,975と1桁上がりました。相対スコアは3,131,965,065、639人中44位でした。    

絶対スコア:120,865,975    

相対スコア:3,131,965,065 44位/639人中

プロジェクトも同じようにもっと厳選しても良い?

試してみます。価値が残務量の1.1倍にないときキャンセルするとしてみます。100テストケースのスコアの平均は上がりました。しかし下がったものの方が多そうです。

少し考え方を変えた方が良さそうです。一旦中止します。

一方、労働カードの全力労働カードに労働力の比率を高めるのを忘れていたのでそれを実装します。平均が上がったので提出します。絶対スコアは594,601,726とグンと上がりました。相対スコアはあまり変わらず3,245,670,721、641人中45位でした。    

絶対スコア:594601726    

相対スコア:3,245,670,721 45位/641人中

明日以降やりたいことをリストにしておきます。

  • 累積の労働コストをプロジェクト毎に計算しておくこと。これを計算しておけば損をすることは無さそうです。
  • 無駄遣いとは逆になるのですが、先行投資的な労働カードの購入ができるのも良さそう。
  • 序盤の無駄遣いも減らしたいところです。
12.順位表からの考察

コンテスト4日目、2023年12月25日の朝です。クリスマスらしいことは何一つしていません。自分の順位は51まで落ちましたが、まだ黄パフォです。このまま終わればヒューリスティック・レーティングが青色になることがわかりました。ドキドキしながらコンテストが終了するのを待っています。

ところで、現在のトップ5です。

2023年12月25日朝の順位表

これを見る限り、全てのテストケースで勝つ解法がないのかなぁという様子。場合分けをした方が良さそうな気がしています(ちなみに自分は50位くらいなのに十分の一くらいのスコアしかありません)。今自分がいろいろと試していることは、あるテストケースでは良くなり、あるテストケースでは悪くなるということが起こっています。うまく良いものだけを集める方法があれば良いのですが、NやMやKでうまく切り分けられずにいます。ただ一つ言えるのは、N=2のとき(方針カードの所持枚数)とK=2のとき(補充カードの選択肢数)がかなり生スコアが高くならないので、ここを場合分けして考えるだけでもスコアが良くなるのではないかと思っています。

13.ビジュアライザを見て考える

心の声がビジュアライザをしっかりと見なさいと言ってきます。一番得点の高かったseed40です。増資カードを17枚使っています。

seed40 score=101,933,600

全力労働カードを良く使っている感じ。プロジェクトチェンジもなかなかうまく使えていました。高い増資カードを選ぶことも避けられています。NよりもKが大きい方が多分大事で、M(プロジェクト数)が大きいのも良さそう。プロジェクトをキャンセルするときに最善(残りのHとVの比率で一番悪いもの)にしていなかったので修正します。

1000テストケースを回すと、seed295の得点1,330,471,760点が出ていました。増資カードを20まで使えています。これをできるだけ多くのseedで出したいものです。

もしかして増資カードはすぐに使うのではなく複数枚持っていると良いことがあるのかなあ?

ターン983の全力労働カードがとてもよかった。こんなふうに上手に使いたいなあ。

seed290で良かった場所

キャンセルカードを選ぶのを持っていないときだけにする、全力労働カードは1.2の比率でも選んで良いとします。

100ケースのスコア分布

少し良くなっている感じがしたので提出してみました。結果は絶対スコアが大幅に下がり、順位も49位から64位に下がりました。

絶対スコア:339,498,611

相対スコア:2,500,009,025 64位/705人中

うーん、これは危険かも。システスでどれだけ下がるか予想がつきません。自分の微妙な結果をもう少し確定させたいです。今あるNMT以外の隠し要素なんだろうなぁ、やっぱり。

キャンセルカードを持っていないときに1枚購入しておくことにします。Highestを更新することはできません。提出する前は100テストケースを回して良くなっている思っているから提出しているのですが。

わからないなぁ。うーん…。自分の中で相対的に何が良くて何が悪いのかがわからずにいます。

絶対スコア:525,597,081

相対スコア:2,918,954,017 53位/714人中


seedの解析に戻りたいと思います。よくわからないままだったら昨日のコードを提出し直して終了したいと思います。

14.増資カードを何枚使えたかを調べる

N,M,Kそれぞれと増資レベルを調べましたが一番相関がありそうだったのはK(補充カードの枚数)でした。

補充カードと増資レベル(100テストケース)

うーん、いろいろと試してみますが良くなりません。とりあえず一回出します。(記録用)

100テストケースを試しているところ

絶対スコアが下がった割に順位はそれほど下がらないので、難しいところ(NやKが小さいところ)の値が相対的に良いのかもしれません。

絶対スコア:476,331,961

相対スコア:2,864,381,704 59位/722位
15.1000テストケースを試して最終提出をする

もう改善はあきらめて、今一番良いスコアのコードを1000テストケース試したいと思います。

キャンセルカードだけ1枚保持にしました。絶対スコアはさらに下がったものの順位は上がるという不思議な現象。うーん...。謎が深まりました。ただ、自分がやっていることがどうも他の人と違う分、相対的に良いスコアの何かがあるようです。

絶対スコア:333,131,77

相対スコア:2,901,803,626 56位/725人中

1000テストケースの結果、スコアが0のものが3つありました。増資カードを20回以上使ってしまっていました。コードを修正します。100テストケースのときよりも平均は上がりましたがMEDIANは下がっています。各テストケースの得点差が大きいため、途中から指標の一つとしてMEDIANを入れるようにしました。いろいろなテストケースの寄せ集めだとこの倍くらいのスコアをMEDIANで出すことができます。

しかし、その条件はよくわかりませんでした。コンテストは明日が最終日ですが、今回はこのコードを最終提出として終わりにしたいと思います。システスで少しでも順位を下げずにいてもらえると良いのですが。

それでもサンプルコードに比べれば、随分と得点を伸ばすことができました。

1000テストケースの結果
17.終わりに

このコンテストが終わったらもしかしたら、もしかすると、私のヒューリスティック・レーティングが1600以上になるかもしれません。そうしたら青色になります。競プロでは入青といった呼び方をします。

今の結果のまま終了した場合のレーティング変化予測

それは、もしもらえるのだとしたら、自分にとって何よりのクリスマス・プレゼントになります。そう、今日は2023年12月25日、クリスマスだからです。

順位表で私を見つけて応援してくれる声を聞きました。うれしかったけど、こんなにも不安定な解法で自信なんか少しもありません。今はただシステスで良い結果が出ることを祈るだけです。

楽しいから続けてきました。それは間違いありません。でも私は強くなりたかった。ずっと、もっと強くなりたい、そう言い続けてきました。だから入青は私にとって、とても大事な節目なのです。

この参加記を読んだ人は、これなら自分もできたと思うかもしれません。私が書いたコードは単純で簡単なものだったから。だけど少しでも手がかりを得ようと試行錯誤した結果なのです。

「これなら自分もできる」と思った人はぜひ次のコンテストに一緒に参加してもらえたらなと思います。そして、コンテストに参加していた人には「よくがんばったね」と思ってもらえたら、うれしく思います。

私の参加記はこれで終了です。最後まで長い文章を読んでくださり、どうもありがとうございました!

18.戻ってきました(コンテスト最終日)

終えたはずなのにこれは何っ?と思った方もいるかもしれません。時系列なのですが、目次の順番が前後します。そう、昨日記事を書き終えて全て終わったつもりでいました。昨日までは。しかし起きてみたらまだ今日はコンテスト最終日。まだできることがあるのではないかと思い始めてしまいました。ヒューリスティック・コンテストあるあるです。というわけで戻ってきました。

まずは1000テストケースの分析です。

1000テストケースの分析

補充カードの割合も調べます。スコアに影響するものを調べたいと思います。

1000テストケースの補充カードの割合

まず自分の予想は増資カードが多い方が良いと思っていたけどそうでもない感じ(数字はレベルで約何割みたいな数にしています)。確かにINVESTカードが全体の3は必要なさそう(たった20枚しか使えないので)。全力労働カードは多い方が良いだろうなあというのは、その通りかもしれません。

増資カードと全力労働カード

色々と組み合わせを試していた中で相性が良さそうだったのが、全力労働カードが多くてキャンセルカードが多いとき。効率の良いプロジェクトを選んで、効率の良い労働力でこなすのは確かに良さそう。

キャンセルカードと全力労働カード

というわけで、戦略的には各補充カードの割合をカウントしておいて、割合が多いならより安く手に入れることを考え、割合が少ないなら多少高くても手元にそのカードを持っておく方が良さそうです。常に平均を求めて、基準を変動するようにしたいと思います。これをすると終盤のカードの選び方が良くなるのではないかと思います。

1000テストケースから求めた基準の割合をセットします。

1000テストケースから求めた割合の基準

ん、無料のカードの枚数を含めていますね。まぁ、いいか。計算できたので、これを評価関数に置きかえます。

たとえば、seed0では通常労働カードは少なめなので少し割高でも良いかなとか、増資カードは多めなので少し割安のときに買いたいとかそんな感じです。1000テストケースで価格も基準を計算できているとうれしい気がしましたが、まぁいいか。

seed0の補充カードの割合

また、価値として、労働カードは労働力/コスト、それ以外はコストの平均を持つことにしました。また、全力労働カードの場合はプロジェクト数を掛けることにします。私が1.3倍という数値を使っていたのもわかる気がしてきました。

seed0の価値(労働カードは労働力/コストの割合、それ以外はコストの平均)

とりあえず基準を変える前に、この計算した結果を100テストケース分出力してみます。まずキャンセルカードと業務転換カード、増資カードはそれぞれ5,5,600で、これは自分がseed0を見て思った数字と同じなので、もう基準通り(変動なし)でいいかなという感じでした。ただ出現確率が違うので、確率が低いときはちょっと高めでも買わないといけなそう。

増資カードの出現確率とレベルは正の相関がありそうだなと思います。これだけでもまずは改善したいと思います。

100テストケースの到達レベルと増資カードの出現確率

書けたので100テストケースを回すと少し良くなっていそう。提出します。絶対スコアが1桁増えて2,343,233,516になりました。

おお!

絶対スコア:2,343,233,516

ドキドキしながら順位表を見ます。

あれ?

提出前は81位だったので、2つ順位を上げただけでした。うーん、やっぱり相対スコアを見る限り、スコアを上げる方向ではあまり順位が上がらないのかもしれません。

相対スコア:2,568,801,123  79位/797人中

労働カードを選ぶ基準を変えます。

10%増えたら0.1倍プラス、10%減ったら0.1倍基準をマイナスすることにしました。100テストケースでは上がっていそうなものの、提出をすると下がりました。

絶対スコア:1,243,739,488

相対スコア:2,240,216,209 88位/806人中

うーん。全力労働カードの基準を変えてみましたが、100テストケースの結果はよくありません。

時刻はそろそろ残り2時間となりました。50テストケースはあまりに不安なので1000テストケースの結果の良いものを出したいと思います。

結局、19時過ぎに提出したもので1000ケースを試し、その後はそれ以上良いものがなかったので提出するのを辞めました。時刻は20時41分。現在の順位はちょうど100位でした。残念ですがこれでは青にはなれそうもありません。クリスマスで良い夢を見させてもらった感じです。今はシステスで少しでも順位が上がるといいなあということを祈るだけでした。

相対スコア

相対スコア:1,975,688,047 100位/832人中

うーん、がんばったけど難しかった。詰め切れなかったなぁ。残念。

正直、他の人の解法がとても気になります。どんな解法だったんだろうなぁ。わくわくどきどきの時間がこの後待っています。

さあ、つぎはCodinGameをやるよー!楽しい年末年始を過ごせて最高です!

CodinGame Fall Challenge 2023はBot Programmingです。楽しいので時間のある人はこちらもぜひ参加してみてくださいね。

www.codingame.com

19.最終結果(2023年12月28日更新)

システムテストの結果が出ました。システムテスト前の暫定順位は101位でした。結果は831人中103位でした。パフォーマンスは1966、3000テストケース全てにACしていました。

公式詳細順位表(AtCoderの解説ページにリンクがあります)を見ると、NとKが小さいときが得点源だったことがわかります。1位と比べると本当に微々たるスコアですが。

今回に限って言えば、Nが2と3のとき、Kが2のときのスコアを良くすることを考えると順位が上がったようです。コンテスト中にそこまで突き止めたかったけど、わかりませんでした。

公式詳細表より(N)

公式詳細表より(M)

公式詳細表より(K)

昨日の夜(2023年12月28日)はAHCラジオがありました。chokudaiさんが最初の1時間で初心者向けのサンプルコードを使った改善方法を説明してくれました。その後、評価関数の考え方を解説して下さり、終わってみたら何と2時間半のボリューム。長いのですが、とてもおすすめの内容になっているのでぜひご覧ください。私も出ています。これを見ると、自分の得点源がKが小さいときだった謎もわかります。

www.youtube.com

今回のコンテストの結果、私のヒューリスティック・レーティングは86上がり、1588になりました。あと少しで1600に到達します。今回は無理でしたが、次回は青に到達したいです。それではみなさん、また次のコンテストでお会いしましょう!

ヒューリスティック・レーティングは1588になりました