2010年10月4日月曜日

Walker の箱詰めパズル

10 種類のワインを合計 120 本買った。 家には 12 本入りのケースが 10 箱ある。 もしワインの各種類が 12 本ずつだったならば、 各ケースに一種類ずつ丁度納めることができたのだが、 残念ながらワインは種類によって 5 本しかなかったり、 20 本以上あったりと、本数がまちまちだ。 そこで各ケースに一種類だけ、というのは諦めて、 二種類までは入れて良いことにすれば、 全てのワインをケースに納めることができるだろうか? 解答はあとで。

8 時半くらいに起床。 珈琲、パン、ヨーグルト、ブルーベリーの朝食のあと、 適当にお弁当を詰めて出勤。午前、午後とお仕事。 昼食は持参のお弁当。 しらす散らし鮨、ニラ玉、鶏肝の生姜煮、きんぴらごぼう、蕪の酢漬け。

与えられた離散確率分布を持つ乱数を発生させる必要があって、 午後は実装を考えていた。 私は(今はやくざでも)根はまっとうな数学者なので、 「与えられた確率分布の分布関数の逆関数に一様乱数を代入すればよい、以上。」 という認識しかなかった。 しかし、実装を始めてみると意外と面倒臭い。 それで、ふとクヌース本を参照してみると、 A.J.Walker という人が提案した「独創的な」方法があって、 とても高速だと書かれていた。 一様乱数に対して大小関係を一度判定するだけで、 望みの乱数が発生させられる、という信じ難い主張のあと、 そのアルゴリズムについては演習問題 x.x.x 番を参照のこと、 とある。 そしてその演習問題を見てみると、 上記と同じパズルが(ワインではなく、色つきの立方体の話で)書かれていて、 一瞬、演習問題の番号の誤植かと思った。 しかし、しばらく考えてのち、まさに目からウロコが落ちる、 アーハー体験をしたのだった。

17 時くらいに退社。 帰宅してまず、レバニラ炒めでローヌの赤ワインを一杯だけ。 お、素晴しい相性だ。どうでしょう、レバニラ炒めにローヌ赤。 そのあと、昨日のしらす散らし鮨で「吉田蔵」純米を冷やで半合ほど。 冷や、って言ったら、常温のことですよね。

パズルの解答。可能である。 実際、k 種類のワイン、n 本入りのケースが k 個、 ワインが合計で k かける n 本あるとき、 各種類が何本であろうが常に、各ケースに二種類以下になるようにできる。 次のようにすればよい。 まず、一番本数の少ない種類のワインを全部一つめのケースに詰める。 そして、一番本数の多い種類のワインで、そのケースの残りを埋める。 ここで状況を見てみると、 一つめのケースには確かに二種類以下のワインが詰められた。 そして、残りのケースとワインは、 数は一つずつ減ったが元の問題と同じ状況になっている。 だから、上の手続を繰り返していけば、 二種類以下のワインが詰められたケースが次々に出来て、 最終的に一箱と一種類だけのワインが残り、すべて解決。