WOO logo

7つのカードの位置を1つの数字に変換する

このニュースレターが発行される頃には、皆既日食の4日前になります。皆様、そして皆既日食の軌道上で観測できる体力と経済力のある皆様にも、きっと興奮していただけることでしょう。残念ながら、私が観測予定のテキサス州では、当日は雷雨の予報が出ています。それでも、晴れることを願っています。

本題に入る前に、前回のイースターに関するトリビアのニュースレターに、驚くほど多くの反響がありました。聖書に詳しい方もいらっしゃるようで、私の回答に疑問を呈してくださりました。その中で特に反論されたのは、密接に関連した2つの質問です。

問8:ユダは後に、イエスを裏切るために支払われた金を祭司たちに返しました。祭司たちはその金をどうしたでしょうか?

答え8: 彼らは陶工の畑を買いました。そこは引き取り手のいない遺体が埋葬される場所です。(マタイ27:6-8)

使徒行伝には、銀貨30枚がどうなったかについて別の記述があることを指摘されました。ユダが陶器師の畑を自分で買ったと書かれています(使徒行伝1:18)。

質問9: ユダはどうやって自殺したのですか?

答え9:絞首刑(マタイ27:3-5)

使徒行伝にはまた別の解釈があるようです。どう解釈したらいいのかよくわからないので、聖書の言葉に任せましょう。「ユダは悪事の償いとして畑を買いましたが、そこで頭から落ちてしまい、体が裂けて内臓が全部飛び出しました。」―使徒行伝1章18節。

私の解釈では、ユダは病気になり、腫れて腫れ上がり、腫れ上がった。やがて衰弱し、倒れて腸が破裂した。この転倒は故意だった可能性もある。

調べてみると、聖書の無謬性を主張する人たちの中には、この二つの物語を一つの複雑な物語にまとめようと躍起になっている人たちがいることが分かりました。しかし、そのような説明にはうんざりするばかりです。

さて、それでは今週の本題、7枚のカードでポーカーの役を成立させるための効率的なコーディングについてお話しましょう。コンピューターの速度を考えると、これは大した問題ではないように思えるかもしれません。しかし、究極のテキサスホールデムでは、カードの出目が56兆通りも存在するという分析が必要です。それぞれの展開には、7枚のカードを使ったポーカーハンドを2つ決める必要があります。近道がなければ、何年もかかるかもしれません。

52枚のカードから7枚のカードを選ぶ方法は、combin(52,7) = 133,784,560通りあります。時間節約に効果的なテクニックとして、すべての組み合わせを一度スコア化し、そのスコアを配列に保存することが挙げられます。しかし、7枚の個々のカードから配列内の特定の位置を取得するにはどうすればよいでしょうか?

答えを出す前に、52^7 の 7 次元配列を使うことを提案する人もいるかもしれません。そのような配列には 1,028,071,702,528 個の整数を格納する必要があります。デスクトップコンピュータでこれほどのメモリ割り当てが可能だとは思えません。7 枚のカードを何らかの方法で 0 から 133,784,559 までの整数にマッピングする必要があります。私の C++ コンパイラは、そのようなサイズの配列でも問題なく動作します。

まず、各カードに0から51までの整数を割り当てます。これは好きな方法で構いません。個人的には、2を0から3、3を4から7、そしてエースを48から51まで割り当てます。カードを4で割ったときの余りが常に同じスーツになるようにすることが重要です。例えば、ハートはすべて0、スペースは1、クラブは2、ダイヤは3といった具合です。

私の関数は、カードの最小セット 0、1、2、3、4、5、6 を数字 0 にマッピングします。同様に、最大セット 45、46、47、48、49、50、51 は最大値 133,784,559 にマッピングされます。

例として、5、10、15、20、25、30、35 の番号が付けられたカードのセットを検討し、そのセットをどの整数にマッピングするかを決定します。

まず、最も小さい数字の5のカードを考えてみましょう。0から4の数字のカードが少なくとも1枚含まれる組み合わせは数多くあります。残りの47枚から7枚を選ぶ方法は、combin(47,7) = 62,891,499通りです。前述のように、52枚から7枚を選ぶ方法は、combin(52,7) = 133,784,560通りあります。つまり、0から4の数字のカードが少なくとも1枚含まれる組み合わせは、133,784,560 - 62,891,499 = 70,893,061通りあります。

次に、2枚目のカードの値が10の場合を考えてみましょう。6から9の範囲のカードが少なくとも1枚含まれる組み合わせは、さらにスキップできます。デッキに残っている42枚のカードのうち、残りの6枚を選ぶ方法はcombin(42,6) = 5,245,786通りあります。これは、最初のカードの値が5より大きい残りの6枚のカードを選ぶ方法はcombin(46,6) = 9,366,819通りあることを表しています。つまり、6から9の範囲のカードが少なくとも1枚含まれる組み合わせは、9,366,819 - 5,245,786 = 4,121,033通りあります。

次に、値が 15 である 3 枚目のカードについて考えます。11 から 14 の範囲のカードが少なくとも 1 枚含まれる組み合わせは、さらにスキップできます。デッキに残っている 37 枚のカードから残りの 5 枚のカードを選択する方法の数は、combin(37,5) = 435,897 です。これは、2枚目のカードの10を超える他の5枚のカードを選ぶ組み合わせ方の組み合わせ方(combin(41,5)=749,398通り)のうちの1つです。したがって、11から14までの値が少なくとも1つ含まれるカードの組み合わせについては、749,398-435,897=313,501通りの数字をスキップすることができます。

次に、20の値を持つ4枚目のカードを考えてみましょう。16から19の範囲のカードが少なくとも1枚含まれる組み合わせは、さらにスキップできます。デッキに残っている32枚のカードのうち、残りの4枚を選ぶ方法はcombin(32,4) = 35,960通りです。これは、3枚目のカードの15を超える残りの4枚のカードを選ぶ方法はcombin(36,4) = 58,905通りあることを表しています。つまり、16から19の範囲のカードが少なくとも1枚含まれる組み合わせは、58,905 - 35,960 = 22,945通りあります。

次に、25の値を持つ5枚目のカードを考えてみましょう。21から24の範囲のカードが少なくとも1枚含まれる組み合わせは、さらにスキップできます。デッキに残っている27枚のカードのうち、残りの3枚を選ぶ方法はcombin(27,3) = 2,925通りです。これは、4枚目のカードの20を超える他の3枚のカードを選ぶ方法はcombin(31,3) = 4,495通りあるうちの4,495通りです。つまり、21から24の範囲のカードが少なくとも1枚含まれる組み合わせは、4,495-2,925=1,570通りスキップできます。

次に、6枚目のカードの値が30の場合を考えてみましょう。26から29の範囲のカードが少なくとも1枚含まれる組み合わせは、さらにスキップできます。デッキに残っている22枚のカードのうち、残りの2枚を選ぶ方法はcombin(22,2) = 231通りです。これは、5枚目のカードの値が20を超える残りの2枚のカードを選ぶ方法はcombin(26,3) = 325通りあるうちの325通りです。つまり、26から29の範囲のカードが少なくとも1枚含まれる組み合わせは、325-231=94通りスキップできます。

残りは1枚になりました。6枚目のカードは30より大きいはずです。実際、35であることは分かっています。ですから、7枚目のカードでは31から34までの4枚のカードを飛ばすことができます。

合計すると、70,893,061+4,121,033+313,501+22,945+1,570+94+4 = 75,352,208 枚のカードをスキップしました。

すべての優れたプログラマーが行うように、0 から番号付けを開始するため、数値 5、10、15、20、25、30、35 のセットに 75,352,208 という値を割り当てることができます。

もちろん、この同じロジックは、あらゆるサイズのデッキやそこから任意の数のカードを選択する場合にも適用されます。

来週は、2024 年 4 月 8 日の皆既日食について、少なくとも予備的なレポートをお届けする予定です。