HACK TO THE FUTURE 2020予選の参加記

2019/11/02に行われたHACK TO THE FUTURE 2020予選に参加しました。 解法はダイクストラ(曲がり回数100ゴールからの距離を負のコスト+4近傍のブロックの個数の2乗-ゴールからのマンハッタン-5)からの不要矢印削除で、最終成績は07:32に提出した4,941,365点で143位(参加者は841人)でした。

f:id:matsu7874:20191102230224p:plain

一瞬6位になりました。

問題概要

N*Nのグリット上に矢印をいくつか出して、ロボットをゴールさせ、ゴールしたロボット数と矢印の数に応じた点数を最大化する問題でした。

やったこと

00:05 48,047 print(0)

48,047点が得られます。正の点数を得ました。

00:33 4,374,029 幅優先探索

ビジュアライザを見てみるとゴールしていないロボットがいることが分かります。 ロボットのゴールに対する加点(1000点/ロボット)が矢印を置くペナルティ(-10点/矢印)よりも大きく、全てのマスに矢印を敷き詰めたとしても点数を改善できるため、実装します。 同じ矢印に囲まれている矢印は消しました。
ゴールから幅優先探索を行い、全てのロボットがゴールできるようにすると4,374,029点が得られます。 ゴール連結な全てのマスに矢印が置かれている状態になりました。

02:32 4,907,639 シミュレータの実装

シミュレータを実装しました。 テストケースを500ケースダウンロードしてきて、手元でまとめて回せるようにしました。

if [ -e summary.csv ] ; then
    mv summary.csv summary_old.csv
fi
echo "case,score,n_goaled,n_guide,n_visited" > summary.csv
for i in $(seq 0 499); do
    python httf.py < testCase/testCase_${i}.txt > testCase/testCase_${i}.out
    cat testCase/testCase_${i}.txt testCase/testCase_${i}.out | python simulator.py summary.csv testCase_${i}.txt
    if [ $(expr $i % 20) = 0 ] ; then
        echo "finished processing testCase/testCase_${i}.txt"
    fi
done
csvstat summary.csv

csvstatを使うと各カラムの合計と分散が簡単に得られます。

  1. "case"

        Type of data:          Text
        Contains null values:  False
        Unique values:         500
        Longest value:         16 characters
        Most common values:    testCase_0.txt (1x)
                               testCase_1.txt (1x)
                               testCase_2.txt (1x)
                               testCase_3.txt (1x)
                               testCase_4.txt (1x)

  2. "score"

        Type of data:          Number
        Contains null values:  False
        Unique values:         276
        Smallest value:        96,862
        Largest value:         99,165
        Sum:                   49,385,296
        Mean:                  98,770.592
        Median:                98,892.5
        StDev:                 374.902
        Most common values:    98,886 (12x)
                               98,893 (6x)
                               98,919 (5x)
                               98,876 (5x)
                               98,909 (5x)

  3. "n_goaled"

        Type of data:          Number
        Contains null values:  False
        Unique values:         3
        Smallest value:        98
        Largest value:         100
        Sum:                   49,930
        Mean:                  99.86
        Median:                100
        StDev:                 0.375
        Most common values:    100 (435x)
                               99 (60x)
                               98 (5x)

  4. "n_guide"

        Type of data:          Number
        Contains null values:  False
        Unique values:         45
        Smallest value:        130
        Largest value:         179
        Sum:                   78,091
        Mean:                  156.182
        Median:                156
        StDev:                 8.461
        Most common values:    155 (32x)
                               159 (31x)
                               158 (26x)
                               160 (25x)
                               156 (25x)

  5. "n_visited"

        Type of data:          Number
        Contains null values:  False
        Unique values:         111
        Smallest value:        400
        Largest value:         545
        Sum:                   236,206
        Mean:                  472.412
        Median:                472
        StDev:                 24.536
        Most common values:    459 (14x)
                               466 (13x)
                               465 (12x)
                               462 (11x)
                               489 (11x)

05:33 4,907,639 何をやっても点数が改善しません

  • bfs -> dfs
    • ドツボにはまるとパネルの消費が激しい
  • 特定パターンの改善をしたい

    →↓
    ○→ とか改善できないかなと思って実装をしていましたが、無理でした。

06:07 4,913,977 敷き詰めた後使わないマスを消す

ロボットに踏まれた回数を持っておいて、0回のものを削除しました。

07:19 4,938,045 bfs -> ダイクストラ

曲がり回数を最小化したい気持ちになったので、ダイクストラ法に切り替えました。

07:32 4,941,365 ダイクストラのパラメータを探す

ゴールの近くには矢印がたくさん置かれるので、遠くから真っ直ぐ向かってきてくれると嬉しい気持ちになったので、距離を負のコストに追加していました。 ブロックの多いゾーンは嫌な気持ちになったので、4近傍のブロック数をコストに追加しました。

この後は踏むマスの数を考えないといけないか……というところで時間切れです。

感想

これまでのマラソンマッチの中では、順位が良かったほうですが、探索が全くできず実行時間は2秒以上余らせてしまって、申し訳ない気持ちです。 本戦出場の皆さん頑張ってください。

解説放送を見て復習します。