Skip to main content
Code Review

Return to Question

Commonmark migration
Source Link

The file, poker.txt, contains one-thousand random hands dealt to two players. Each line of the file contains ten cards (separated by a single space): the first five are Player 1's cards and the last five are Player 2's cards. You can assume that all hands are valid (no invalid characters or repeated cards), each player's hand is in no specific order, and in each hand there is a clear winner.

How many hands does Player 1 win?

The file, poker.txt, contains one-thousand random hands dealt to two players. Each line of the file contains ten cards (separated by a single space): the first five are Player 1's cards and the last five are Player 2's cards. You can assume that all hands are valid (no invalid characters or repeated cards), each player's hand is in no specific order, and in each hand there is a clear winner.

How many hands does Player 1 win?

The file, poker.txt, contains one-thousand random hands dealt to two players. Each line of the file contains ten cards (separated by a single space): the first five are Player 1's cards and the last five are Player 2's cards. You can assume that all hands are valid (no invalid characters or repeated cards), each player's hand is in no specific order, and in each hand there is a clear winner.

How many hands does Player 1 win?

Tweeted twitter.com/StackCodeReview/status/666238710044827649
deleted 11 characters in body
Source Link
Ben
  • 283
  • 1
  • 8
import Data.Monoid(mappend)
import Data.List(sortBy, sort, group, nub, elemIndex)
import Control.Arrow((&&&), (***))
import Data.Maybe(fromJust)
import Control.Monad(join)
type Hand = String
type Values = [Int]
data Ranking = HighCard | Pair | TwoPair | ThreeOfAKind | Straight | Flush | FullHouse | FourOfAKind | StraightFlush deriving (Eq, Ord)
data HandValue = HandValue Ranking Values
instance Eq HandValue where
 HandValue r1 v1 == HandValue r2 v2 = r1 == r2 && v1 == v2
instance Ord HandValue where
 HandValue r1 v1 `compare` HandValue r2 v2 = (r1 `compare` r2) `mappend` (v1 `compare` v2)
 
rateHand :: Hand -> HandValue
rateHand hand
 | straight && flush = HandValue StraightFlush ranks
 | flush = HandValue Flush ranks
 | straight = HandValue Straight ranks
 | otherwise = case map fst groups of
 [4, 1] -> HandValue FourOfAKind values
 [3, 2] -> HandValue FullHouse values
 [3, 1, 1] -> HandValue ThreeOfAKind values
 [2, 2, 1] -> HandValue TwoPair values
 [2, 1, 1, 1] -> HandValue Pair values
 otherwise -> HandValue HighCard values
 where
 sf = (`elem` "SCDH")
 ranks = sortBy (flip compare) $ map (fromJust . (`elemIndex` "23456789TJQKA")) $ filter (not . sf) hand
 suits = filter sf hand
 flush = length (nub suits) == 1
 straight = straight = ranks == reverse [last ranks..head ranks] || ranks == [12,3,2,1,0]
 groups = sortBy descSort . map (length &&& id) $ group ranks
 values = concatMap snd groups
 descSort (l1,v1) (l2,v2) = (l2 `compare` l1) `mappend` (v2 `compare` v1)
parseLine :: String -> Bool
parseLine line = uncurry (>) $ join (***) rateHand $ splitAt 10 $ filter (/= ' ') line
main :: IO ()
main = do
 pots <- lines <$> readFile "p054_poker.txt"
 print $ length $ filter parseLine pots
import Data.Monoid(mappend)
import Data.List(sortBy, sort, group, nub, elemIndex)
import Control.Arrow((&&&), (***))
import Data.Maybe(fromJust)
import Control.Monad(join)
type Hand = String
type Values = [Int]
data Ranking = HighCard | Pair | TwoPair | ThreeOfAKind | Straight | Flush | FullHouse | FourOfAKind | StraightFlush deriving (Eq, Ord)
data HandValue = HandValue Ranking Values
instance Eq HandValue where
 HandValue r1 v1 == HandValue r2 v2 = r1 == r2 && v1 == v2
instance Ord HandValue where
 HandValue r1 v1 `compare` HandValue r2 v2 = (r1 `compare` r2) `mappend` (v1 `compare` v2)
 
rateHand :: Hand -> HandValue
rateHand hand
 | straight && flush = HandValue StraightFlush ranks
 | flush = HandValue Flush ranks
 | straight = HandValue Straight ranks
 | otherwise = case map fst groups of
 [4, 1] -> HandValue FourOfAKind values
 [3, 2] -> HandValue FullHouse values
 [3, 1, 1] -> HandValue ThreeOfAKind values
 [2, 2, 1] -> HandValue TwoPair values
 [2, 1, 1, 1] -> HandValue Pair values
 otherwise -> HandValue HighCard values
 where
 sf = (`elem` "SCDH")
 ranks = sortBy (flip compare) $ map (fromJust . (`elemIndex` "23456789TJQKA")) $ filter (not . sf) hand
 suits = filter sf hand
 flush = length (nub suits) == 1
 straight = straight = ranks == reverse [last ranks..head ranks] || ranks == [12,3,2,1,0]
 groups = sortBy descSort . map (length &&& id) $ group ranks
 values = concatMap snd groups
 descSort (l1,v1) (l2,v2) = (l2 `compare` l1) `mappend` (v2 `compare` v1)
parseLine :: String -> Bool
parseLine line = uncurry (>) $ join (***) rateHand $ splitAt 10 $ filter (/= ' ') line
main :: IO ()
main = do
 pots <- lines <$> readFile "p054_poker.txt"
 print $ length $ filter parseLine pots
import Data.Monoid(mappend)
import Data.List(sortBy, sort, group, nub, elemIndex)
import Control.Arrow((&&&), (***))
import Data.Maybe(fromJust)
import Control.Monad(join)
type Hand = String
type Values = [Int]
data Ranking = HighCard | Pair | TwoPair | ThreeOfAKind | Straight | Flush | FullHouse | FourOfAKind | StraightFlush deriving (Eq, Ord)
data HandValue = HandValue Ranking Values
instance Eq HandValue where
 HandValue r1 v1 == HandValue r2 v2 = r1 == r2 && v1 == v2
instance Ord HandValue where
 HandValue r1 v1 `compare` HandValue r2 v2 = (r1 `compare` r2) `mappend` (v1 `compare` v2)
 
rateHand :: Hand -> HandValue
rateHand hand
 | straight && flush = HandValue StraightFlush ranks
 | flush = HandValue Flush ranks
 | straight = HandValue Straight ranks
 | otherwise = case map fst groups of
 [4, 1] -> HandValue FourOfAKind values
 [3, 2] -> HandValue FullHouse values
 [3, 1, 1] -> HandValue ThreeOfAKind values
 [2, 2, 1] -> HandValue TwoPair values
 [2, 1, 1, 1] -> HandValue Pair values
 otherwise -> HandValue HighCard values
 where
 sf = (`elem` "SCDH")
 ranks = sortBy (flip compare) $ map (fromJust . (`elemIndex` "23456789TJQKA")) $ filter (not . sf) hand
 suits = filter sf hand
 flush = length (nub suits) == 1
 straight = ranks == reverse [last ranks..head ranks] || ranks == [12,3,2,1,0]
 groups = sortBy descSort . map (length &&& id) $ group ranks
 values = concatMap snd groups
 descSort (l1,v1) (l2,v2) = (l2 `compare` l1) `mappend` (v2 `compare` v1)
parseLine :: String -> Bool
parseLine line = uncurry (>) $ join (***) rateHand $ splitAt 10 $ filter (/= ' ') line
main :: IO ()
main = do
 pots <- lines <$> readFile "p054_poker.txt"
 print $ length $ filter parseLine pots
added 61 characters in body
Source Link
Ben
  • 283
  • 1
  • 8

My implementation works perfectly and is very fast (100,000 lines in 10 sec in ghci, actual problem is instant), so I'm not necessarily looking for performance improvements; any kind of feedback is more than welcome.

My implementation works perfectly and is very fast, so I'm not necessarily looking for performance improvements; any kind of feedback is more than welcome.

My implementation works perfectly and is very fast (100,000 lines in 10 sec in ghci, actual problem is instant), so I'm not necessarily looking for performance improvements; any kind of feedback is more than welcome.

added 2 characters in body
Source Link
Ben
  • 283
  • 1
  • 8
Loading
edited tags
Link
200_success
  • 145.6k
  • 22
  • 190
  • 479
Loading
edited body
Source Link
Ben
  • 283
  • 1
  • 8
Loading
Source Link
Ben
  • 283
  • 1
  • 8
Loading
lang-hs

AltStyle によって変換されたページ (->オリジナル) /