第1回 深夜の真剣レポート60分一本勝負 「今週の学び」の作品です。
今日の昼頃天井眺めてたら思いついた。
ヒット・アンド・ブローは二人で遊ぶ数字当てゲームで、ルールは以下の通りである:
- 各プレイヤーは0~9の数字から3桁の順列(以下、「組」と呼ぶ)を選ぶ(123や846など。225のような重複のあるものはだめ)。
- プレイヤーは各ターン、相手の選んだ組を一つ推測し、提示する。
- 相手の推測に対して、以下のような情報を返す:
- ヒット(H):数字も位置も合っているものの個数
- ブロー(B):数字は合っているが位置が違うものの個数
- 例:答えが123、推測が324の場合、1H1Bとなる。
- 少ないターン数で相手の選んだ組を当てた(3H0Bを出した)方が勝ち。 自分の「答え」としてわかりやすい組を選んでしまうとすごい勢いで負けるらしい。
方針:各ターンの情報量を貪欲に最大化する。先のことは考えない。
相手が組を完全にランダムに選んでくるとしたら(←非常に強い仮定。大概は「探られにくい」組を選ぶので、偏る。)、各回の推測で得られる情報量は計算可能である。
ある推測に対してあるヒントを得た際、そこまでのヒントからあり得る組が残りn個になったとすると、確定までに必要な情報量は残りlog_2(n) bitである。この「残り必要な情報量」の期待値を最小化するように推測をすることにする。
具体的には、推測の候補(現時点であり得る組すべて)について、それを提示したときの返答として0H0B, 0H1B, 0H2B, ..., 3H0B を得たときの残りの候補数を計算し、そこから各推測候補に対して「残り必要な情報量」の期待値を計算する。3桁のヒット・アンド・ブローでは高々720通りの候補しかないため、n^2オーダーの計算は十分許容できる。
以上のアルゴリズムを愚直に実装したので、いくつかの数字について推測の実例を置いておく。なお、メタ戦法対策の観点からは、期待値が同じ候補の中からランダムに選ぶことが望ましそうであるが、ここでは戦略の振る舞いを理解するために辞書順最小の候補を選ぶことにした。
自分の選択?> 8 2 5
提示した質問> 0 1 2
答え: 0H1B
残りの候補数: 252
提示した質問> 1 3 4
答え: 0H0B
残りの候補数: 80
提示した質問> 5 0 6
答え: 0H1B
残りの候補数: 21
提示した質問> 7 2 5
答え: 2H0B
残りの候補数: 2
提示した質問> 8 2 5
答え: 3H0B
残りの候補数: 1
自分の選択?> 3 7 0
提示した質問> 0 1 2
答え: 0H1B
残りの候補数: 252
提示した質問> 1 3 4
答え: 0H1B
残りの候補数: 75
提示した質問> 3 5 0
答え: 2H0B
残りの候補数: 5
提示した質問> 3 6 0
答え: 2H0B
残りの候補数: 3
提示した質問> 3 7 0
答え: 3H0B
残りの候補数: 1
自分の選択?> 2 1 9
提示した質問> 0 1 2
答え: 1H1B
残りの候補数: 42
提示した質問> 0 2 3
答え: 0H1B
残りの候補数: 18
提示した質問> 2 1 4
答え: 2H0B
残りの候補数: 5
提示した質問> 2 1 5
答え: 2H0B
残りの候補数: 4
提示した質問> 2 1 6
答え: 2H0B
残りの候補数: 3
提示した質問> 2 1 7
答え: 2H0B
残りの候補数: 2
提示した質問> 2 1 8
答え: 2H0B
残りの候補数: 1
提示した質問> 2 1 9
答え: 3H0B
残りの候補数: 1
三つ目の例は最も手数のかかる組を選んだ。この場合、分の悪い推測をしているように見える……。
すべての組に対して何手かかるか計算したところ、平均5.15手、最悪8手であることがわかった。これは実際高速である。なお、筆者が観測した事例によれば、本当にヒットアンドブローに勝ちたいなら、機械に推測させるより先に機械に数字を生成させるところからはじめたほうがよい。
2 1 9に対して分の悪い推測をしていたのは、相手の答えとしてあり得ない組(上の例では7 8 9など)を推測の候補から省いていたからだった。すべての組を推測の候補に含めると、平均5.26手、最悪7手となって、平均的な成績は悪化した。なんで……
なお、この場合の2 1 9に対する推測は、以下の流れとなった:
自分の選択?> 2 1 9
提示した質問> 0 1 2
答え: 1H1B
残りの候補数: 42
提示した質問> 0 3 4
答え: 0H0B
残りの候補数: 10
提示した質問> 1 5 6
答え: 0H1B
残りの候補数: 3
提示した質問> 0 7 8
答え: 0H0B
残りの候補数: 1
提示した質問> 2 1 9
答え: 3H0B
残りの候補数: 1
何らかのヒントを受けて相手の選んだ組が確定したとき、3H0Bとそれ以外では最終的なターン数が1異なる。上の例から720通りの絞り込みに平均5手程度要していることを考えると、一手あたりおおよそ2bit程度の情報量を得ていることになる。
そのため、3H0Bが出る場合の「推測に必要な残り情報量」を-2bitとして計算するようコードを改変したところ、平均5.02手、最悪7手となり、成績が改善した。
必要手数が最大であった例について、推測の流れは以下の通りであった:
自分の選択?> 3 2 9
提示した質問> 0 1 2
答え: 0H1B
残りの候補数: 252
提示した質問> 1 3 4
答え: 0H1B
残りの候補数: 75
提示した質問> 3 5 0
答え: 1H0B
残りの候補数: 16
提示した質問> 6 4 0
答え: 0H0B
残りの候補数: 6
提示した質問> 3 2 7
答え: 2H0B
残りの候補数: 2
提示した質問> 3 2 8
答え: 2H0B
残りの候補数: 1
提示した質問> 3 2 9
答え: 3H0B
残りの候補数: 1