Problem 54

場合わけが面倒だ。

import Data.Char
import Data.List
import Data.Ord
import Control.Arrow
type Card = (Int,Char)
trans [v,s] = (cardValue v,s)
cardValue c |isDigit c =digitToInt c
| c == 'T' = 10
| c == 'J' = 11
| c == 'Q' = 12
| c == 'K' = 13
| c == 'A' = 14
isRoyal cs = isFlush cs&& (minimum .map fst) cs == 10
isSFlush cs = isFlush cs && isStraight cs
isFourKind =(==4).snd.head.pair
isFullHouse cs = let [m,n] = take 2.map snd.pair $ cs in m==3 && n==2
isFlush ::[Card]->Bool
isFlush = (==1).length.group.map snd
isStraight cs=last ns - head ns ==4&&length ns ==5
where ns =nub.sort.map fst$cs
isThreeKind =(==3).snd.head.pair
isTwoPairs cs = let [m,n] = take 2.map snd.pair $ cs in m==2 && n==2
isOnePair =(==2).snd.head.pair
rank cs
| isRoyal cs     = [9]
| isSFlush cs    = [8]++[minimum.map fst$cs]
| isFourKind cs  = [7]++(map fst.pair$cs)
| isFullHouse cs = [6]++(map fst.pair$cs)
| isFlush cs     = [5]++[minimum.map fst$cs]
| isStraight cs  = [4]++[minimum.map fst$cs]
| isThreeKind cs = [3]++(map fst.pair$cs)
| isTwoPairs cs  = [2]++(map fst.pair$cs)
| isOnePair cs   = [1]++(map fst.pair$cs)
| otherwise      = []++(map fst.pair$cs)
pair ::[Card]->[(Int,Int)]
pair =reverse.sortBy(comparing snd).sortBy(comparing fst).map(head&&&length).group.sort.map fst
win cs ds = rank cs > rank ds
main = readFile "poker.txt">>=print.length.filter (uncurry win).map (splitAt 5.map trans.words).lines
More Reading
Newer// Problem 58
Older// Problem 55