2009 年度「計算機基礎論3B」 2010-01-22

§39 exclusive or と三山崩しの種明かし

(39.1) 二進法による自然数(および 0)の表現法は、既知とする。 たとえば、十進法の 5 は二進法では 101 となる。

(39.2) ※ 「二進数」というものも存在するが、これは普通の数とは異なる数学的対象である。 世間では二進法で表現された数のことを間違って“二進数”と呼んでいることがあるが、 数学科の諸君は混同しないように。

(39.3) exclusive or は、集合 {0, 1} の上の二項演算で、 二元体 F2 の加法と同じである。 (位数 2 の群 Z/2Z の演算と同じ、といってもよい。)

(39.4) C言語では、int 型変数 a, b に自然数(または 0)が格納されているとき、 a ^ b は 「a, b に格納されている数を二進法で表し、 ケタごとに exclusive or をとって得られる数」になる、という約束である。 この「^」は、加減乗除と同じく、二項演算子である。 (これを使ったプログラミングは割愛。)

(39.5) 三山崩しの必勝法は、前回は巨大な表だったが、 exclusive or を用いると、以下のように簡単にまとめられる。

(39.6) 次の事実を用いる。 「三つの山の石の個数を a[0], a[1], a[2] とする。 もしも a[0] ^ a[1] ^ a[2] が 0 の状態で相手の番になると、 相手がどう石をとってもこの式の値は 0 でなくなり、 次に自分はうまく石をとることでこの式の値を 0 にできる。すなわち、 またこの式を 0 にして相手の番にできる」。

(39.7) 証明: たとえば、三つの山の石の数が 3, 5, 6 のとき、

               a[0]   0011
               a[1]   0101
               a[2]   0110
---------------------------
 a[0] ^ a[1] ^ a[2]   0000
なので a[0] ^ a[1] ^ a[2] は 0 である。相手が石をとると、 a[0], a[1], a[2] のうちのどれか一つについて、 あるケタの数が変わる。すると、 a[0] ^ a[1] ^ a[2] のそのケタが変わるから、1 が出てくる。

(39.8) a[0] ^ a[1] ^ a[2] が 0 でない状態で自分の番になったとする。 その値を x としよう。 x がどんな値でも x ^ x は 0 であることに注意すると、 (a[0] ^ a[1] ^ a[2]) ^ x は 0 であることがわかる。 「^」は交換法則、結合法則を満たすので、 この式は (a[0] ^ x) ^ a[1] ^ a[2] に等しいから、 もしも a[0] ^ xa[0] より小さいなら、 自分は第 0 の山から a[0] - (a[0] ^ x) 個の石をとって、 a[0]a[0] ^ x にすればよい。 よって、あとは次を示せばよいことになる。

(39.9) i が 0, 1, 2 のうちどれかは、a[i] ^ xa[i] より小さい。 このことは、次のように示される。 x を二進表記したとき、一番左の 1 のあるケタは、 a[0], a[1], a[2] のうちどれかが 1 となっている。 そのような a[i] を選べば、 a[i] ^ x のそのケタは 1 から 0 に変わり、 それより左のケタは変わらないので、 a[i] ^ xa[i] よりも小さくなる。 [証明終わり]

(39.10) このようにして石をとってゆくとき、 三つの石の個数の和はどんどん小さくなってゆくから、いつか 0 になる。 そのとき、a[0] ^ a[1] ^ a[2] の値は 0 であるから、 相手の番である。 ということは、自分の勝ちである。

(39.11) ※ 山が一つで、そこから1〜3個の石をとり合うゲームだと、 mod 4 で 0 にして相手に渡すのが必勝法となる。 ある意味で、それと似ている。


岩瀬順一