2023-07 in haskell
This commit is contained in:
parent
e1537be332
commit
70860aea14
4 changed files with 1245 additions and 0 deletions
5
2023/07-Camel_Cards/example
Normal file
5
2023/07-Camel_Cards/example
Normal file
|
@ -0,0 +1,5 @@
|
|||
32T3K 765
|
||||
T55J5 684
|
||||
KK677 28
|
||||
KTJJT 220
|
||||
QQQJA 483
|
110
2023/07-Camel_Cards/first.hs
Normal file
110
2023/07-Camel_Cards/first.hs
Normal file
|
@ -0,0 +1,110 @@
|
|||
-- requires cabal install --lib megaparsec parser-combinators
|
||||
module Main (main) where
|
||||
|
||||
import Control.Applicative.Permutations
|
||||
import Control.Monad (void, when)
|
||||
import Data.Char qualified as C
|
||||
import Data.Either
|
||||
import Data.Functor
|
||||
import Data.List qualified as L
|
||||
import Data.Map qualified as M
|
||||
import Data.Maybe
|
||||
import Data.Set qualified as S
|
||||
import Data.Void (Void)
|
||||
import Text.Megaparsec
|
||||
import Text.Megaparsec.Char
|
||||
|
||||
import Debug.Trace
|
||||
|
||||
exampleExpectedOutput = 6440
|
||||
|
||||
data Card = Two | Three | Four | Five | Six | Seven | Eight | Nine | T | J | Q | K | A deriving (Eq, Ord)
|
||||
|
||||
instance Show Card where
|
||||
show Two = "2"
|
||||
show Three = "3"
|
||||
show Four = "4"
|
||||
show Five = "5"
|
||||
show Six = "6"
|
||||
show Seven = "7"
|
||||
show Eight = "8"
|
||||
show Nine = "9"
|
||||
show T = "T"
|
||||
show J = "J"
|
||||
show Q = "Q"
|
||||
show K = "K"
|
||||
show A = "A"
|
||||
|
||||
data Rank = HighCard
|
||||
| Pair
|
||||
| Pairs
|
||||
| Brelan
|
||||
| FullHouse
|
||||
| Quartet
|
||||
| Quintet
|
||||
deriving (Eq, Ord, Show)
|
||||
|
||||
data Hand = Hand Rank [Card] Int deriving (Eq, Show)
|
||||
|
||||
compareCards :: [Card] -> [Card] -> Ordering
|
||||
compareCards (x:xs) (y:ys) | x == y = compareCards xs ys
|
||||
| otherwise = x `compare` y
|
||||
instance Ord Hand where
|
||||
(Hand a x _) `compare` (Hand b y _) | a == b = compareCards x y
|
||||
| otherwise = a `compare` b
|
||||
|
||||
type Input = [Hand]
|
||||
|
||||
type Parser = Parsec Void String
|
||||
|
||||
parseCard :: Parser Card
|
||||
parseCard = char '2' $> Two
|
||||
<|> char '3' $> Three
|
||||
<|> char '4' $> Four
|
||||
<|> char '5' $> Five
|
||||
<|> char '6' $> Six
|
||||
<|> char '7' $> Seven
|
||||
<|> char '8' $> Eight
|
||||
<|> char '9' $> Nine
|
||||
<|> char 'T' $> T
|
||||
<|> char 'J' $> J
|
||||
<|> char 'Q' $> Q
|
||||
<|> char 'K' $> K
|
||||
<|> char 'A' $> A
|
||||
|
||||
evalRank :: [Card] -> Rank
|
||||
evalRank n@(a:b:c:d:e:_) | not (a<=b && b<=c && c<=d && d<=e) = evalRank $ L.sort n
|
||||
| a==b && b==c && c==d && d==e = Quintet
|
||||
| (a==b && b==c && c==d) || (b==c && c==d && d==e) = Quartet
|
||||
| a==b && (b==c || c==d) && d==e = FullHouse
|
||||
| (a==b && b==c) || (b==c && c==d) || (c==d && d==e) = Brelan
|
||||
| (a==b && (c==d || d==e)) || (b==c && d==e) = Pairs
|
||||
| a==b || b==c || c==d || d==e = Pair
|
||||
| otherwise = HighCard
|
||||
|
||||
parseHand :: Parser Hand
|
||||
parseHand = do
|
||||
cards <- some parseCard <* char ' '
|
||||
bid <- read <$> (some digitChar <* eol)
|
||||
return $ Hand (evalRank cards) cards bid
|
||||
|
||||
parseInput' :: Parser Input
|
||||
parseInput' = some parseHand <* eof
|
||||
|
||||
parseInput :: String -> IO Input
|
||||
parseInput filename = do
|
||||
input <- readFile filename
|
||||
case runParser parseInput' filename input of
|
||||
Left bundle -> error $ errorBundlePretty bundle
|
||||
Right input' -> return input'
|
||||
|
||||
compute :: Input -> Int
|
||||
compute = sum . zipWith (*) [1..] . map (\(Hand _ _ bid) -> bid) . L.sort
|
||||
|
||||
main :: IO ()
|
||||
main = do
|
||||
example <- parseInput "example"
|
||||
let exampleOutput = compute example
|
||||
when (exampleOutput /= exampleExpectedOutput) (error $ "example failed: got " ++ show exampleOutput ++ " instead of " ++ show exampleExpectedOutput)
|
||||
input <- parseInput "input"
|
||||
print $ compute input
|
1000
2023/07-Camel_Cards/input
Normal file
1000
2023/07-Camel_Cards/input
Normal file
File diff suppressed because it is too large
Load diff
130
2023/07-Camel_Cards/second.hs
Normal file
130
2023/07-Camel_Cards/second.hs
Normal file
|
@ -0,0 +1,130 @@
|
|||
-- requires cabal install --lib megaparsec parser-combinators
|
||||
module Main (main) where
|
||||
|
||||
import Control.Applicative.Permutations
|
||||
import Control.Monad (void, when)
|
||||
import Data.Char qualified as C
|
||||
import Data.Either
|
||||
import Data.Functor
|
||||
import Data.List qualified as L
|
||||
import Data.Map qualified as M
|
||||
import Data.Maybe
|
||||
import Data.Set qualified as S
|
||||
import Data.Void (Void)
|
||||
import Text.Megaparsec
|
||||
import Text.Megaparsec.Char
|
||||
|
||||
import Debug.Trace
|
||||
|
||||
exampleExpectedOutput = 5905
|
||||
|
||||
data Card = J | Two | Three | Four | Five | Six | Seven | Eight | Nine | T | Q | K | A
|
||||
|
||||
instance Eq Card where
|
||||
J == _ = True
|
||||
_ == J = True
|
||||
a == b = show a == show b
|
||||
|
||||
instance Ord Card where
|
||||
a `compare` b = show a `compare` show b
|
||||
a <= b = show a <= show b
|
||||
|
||||
-- Dirty hack so that it sorts nicely in ascii
|
||||
instance Show Card where
|
||||
show J = "0"
|
||||
show Two = "2"
|
||||
show Three = "3"
|
||||
show Four = "4"
|
||||
show Five = "5"
|
||||
show Six = "6"
|
||||
show Seven = "7"
|
||||
show Eight = "8"
|
||||
show Nine = "9"
|
||||
show T = "A"
|
||||
show Q = "B"
|
||||
show K = "C"
|
||||
show A = "D"
|
||||
|
||||
data Rank = HighCard
|
||||
| Pair
|
||||
| Pairs
|
||||
| Brelan
|
||||
| FullHouse
|
||||
| Quartet
|
||||
| Quintet
|
||||
deriving (Eq, Ord, Show)
|
||||
|
||||
data Hand = Hand Rank [Card] Int deriving (Eq, Show)
|
||||
|
||||
compareCards :: [Card] -> [Card] -> Ordering
|
||||
compareCards x y = concatMap show x `compare` concatMap show y
|
||||
|
||||
instance Ord Hand where
|
||||
(Hand a x _) `compare` (Hand b y _) | a == b = compareCards x y
|
||||
| otherwise = a `compare` b
|
||||
|
||||
type Input = [Hand]
|
||||
|
||||
type Parser = Parsec Void String
|
||||
|
||||
parseCard :: Parser Card
|
||||
parseCard = char '2' $> Two
|
||||
<|> char '3' $> Three
|
||||
<|> char '4' $> Four
|
||||
<|> char '5' $> Five
|
||||
<|> char '6' $> Six
|
||||
<|> char '7' $> Seven
|
||||
<|> char '8' $> Eight
|
||||
<|> char '9' $> Nine
|
||||
<|> char 'T' $> T
|
||||
<|> char 'J' $> J
|
||||
<|> char 'Q' $> Q
|
||||
<|> char 'K' $> K
|
||||
<|> char 'A' $> A
|
||||
|
||||
evalRank :: [Card] -> Rank
|
||||
evalRank [J, J, J, J, _] = Quintet
|
||||
evalRank [J, J, J, d, e] | d==e = Quintet
|
||||
| otherwise = Quartet
|
||||
evalRank [J, J, c, d, e] | c==d && d==e = Quintet
|
||||
| c==d || d==e = Quartet
|
||||
| otherwise = Brelan
|
||||
evalRank [J, b, c, d, e] | b==c && c==d && d==e = Quintet
|
||||
| (b==c || d==e) && c==d = Quartet
|
||||
| b==c && d==e = FullHouse
|
||||
| b==c || c==d || d==e = Brelan
|
||||
| otherwise = Pair
|
||||
evalRank [a, b, c, d, e] | a==b && a==c && a==d && a==e = Quintet
|
||||
| (a==b && a==c && a==d) || (b==c && b==d && b==e) = Quartet
|
||||
| a==b && (b==c || c==d) && d==e = FullHouse
|
||||
| (a==b && b==c) || (b==c && c==d) || (c==d && d==e) = Brelan
|
||||
| (a==b && (c==d || d==e)) || (b==c && d==e) = Pairs
|
||||
| a==b || b==c || c==d || d==e = Pair
|
||||
| otherwise = HighCard
|
||||
|
||||
parseHand :: Parser Hand
|
||||
parseHand = do
|
||||
cards <- some parseCard <* char ' '
|
||||
bid <- read <$> (some digitChar <* eol)
|
||||
return $ Hand (evalRank $ L.sort cards) cards bid
|
||||
|
||||
parseInput' :: Parser Input
|
||||
parseInput' = some parseHand <* eof
|
||||
|
||||
parseInput :: String -> IO Input
|
||||
parseInput filename = do
|
||||
input <- readFile filename
|
||||
case runParser parseInput' filename input of
|
||||
Left bundle -> error $ errorBundlePretty bundle
|
||||
Right input' -> return input'
|
||||
|
||||
compute :: Input -> Int
|
||||
compute = sum . zipWith (*) [1..] . map (\(Hand _ _ bid) -> bid) . L.sort
|
||||
|
||||
main :: IO ()
|
||||
main = do
|
||||
example <- parseInput "example"
|
||||
let exampleOutput = compute example
|
||||
when (exampleOutput /= exampleExpectedOutput) (error $ "example failed: got " ++ show exampleOutput ++ " instead of " ++ show exampleExpectedOutput)
|
||||
input <- parseInput "input"
|
||||
print $ compute input
|
Loading…
Add table
Reference in a new issue