のてすきあ − 完全独習非プログラマー −

Haskell で Project Euler を解く素人遊び

Problem 54

与えられたカードの組み合わせ(1,000通り)でポーカーの勝負をした際に、Player 1 が勝つ組み合わせはいくつあるか。

 これまで50問以上を解いてきて、Project Euler はプログラミング素人でも日本の高校数学程度の素養があればなんとかなる…と思っていた。が、この問題は完全にプログラミングの問題じゃないか。これほど途方に暮れた問題は初である。だってポーカーって。何をどうすれば良いのかしばし悩む…。

 順番に考える。まず非プログラマーとして何が難しいか。それは手役の評価である。単純な数字の大小を比較するのではなく、数の大きさに関係なく手役で比較しなければならない。数じゃないものをどうやって比較判定すれば良いのか…。

 …。
 あ、そうか。data だ。Haskellでは型を自由に作れるし、その際に宣言する値コンストラクタはOrd型のインスタンスにすることができるのだった。という事は、新しく手役型(Hand型)を作り、その値コンストラクタに上がり役(ワンペアとかフラッシュとか)をあてがってやることで、手役同士に大小関係を定義できるのではないか。

 そこまで考えれば、あとは手役を1つずつ定義していくことでなんとかなりそうである。実際にはカードをsortしておくと便利とか、同じ手役のときの大小関係の定義付けとか、細々とした面倒な比較があるが、そのへんは定義というかゲームのルールに従って比較する手順を地道に実装していけば良い。

 同じ手役のときの比較のために、Hand型は [手役] + [手札] という形にした。さらに手札を比較するために、単純なsortではなく、ペアを作っているものが優先されるような自作のソート(sortWithValues)を使って手札を並べるなどの工夫をした。


 いや、しかし、これは解けて本当に嬉しい。よくやった自分。

 

やったー☆ 解けてめっちゃ嬉しい☆☆☆