Day 7
This commit is contained in:
@@ -52,3 +52,11 @@ executable day06
|
|||||||
build-depends: base ^>=4.15.1.0, MissingH
|
build-depends: base ^>=4.15.1.0, MissingH
|
||||||
hs-source-dirs: day06
|
hs-source-dirs: day06
|
||||||
default-language: Haskell2010
|
default-language: Haskell2010
|
||||||
|
|
||||||
|
executable day07
|
||||||
|
main-is: Main.hs
|
||||||
|
other-modules: Commons Part1 Part2
|
||||||
|
|
||||||
|
build-depends: base ^>=4.15.1.0, MissingH
|
||||||
|
hs-source-dirs: day07
|
||||||
|
default-language: Haskell2010
|
||||||
|
|||||||
53
day07/Commons.hs
Normal file
53
day07/Commons.hs
Normal file
@@ -0,0 +1,53 @@
|
|||||||
|
module Commons where
|
||||||
|
|
||||||
|
import Data.List.Utils (split)
|
||||||
|
import GHC.IO.Handle (isEOF)
|
||||||
|
import Data.Char (digitToInt, isDigit)
|
||||||
|
import Data.List (sortOn)
|
||||||
|
|
||||||
|
|
||||||
|
data Hand = Hand { values :: [Int], bid :: Int } deriving Show
|
||||||
|
data HandValue = HandValue { hand :: Hand, value :: Int } deriving Show
|
||||||
|
|
||||||
|
|
||||||
|
parseValues :: String -> [Int]
|
||||||
|
parseValues (v: t) | isDigit v = digitToInt v: parseValues t
|
||||||
|
| v == 'T' = 10: parseValues t
|
||||||
|
| v == 'J' = 11: parseValues t
|
||||||
|
| v == 'Q' = 12: parseValues t
|
||||||
|
| v == 'K' = 13: parseValues t
|
||||||
|
| v == 'A' = 14: parseValues t
|
||||||
|
parseValues [] = []
|
||||||
|
|
||||||
|
parseHand :: String -> Hand
|
||||||
|
parseHand handRaw = let valuesRaw: bidRaw: _ = split " " handRaw
|
||||||
|
in Hand {values = parseValues valuesRaw, bid = read bidRaw}
|
||||||
|
|
||||||
|
parse :: IO [Hand]
|
||||||
|
parse = do done <- isEOF
|
||||||
|
if done
|
||||||
|
then return []
|
||||||
|
else do line <- getLine
|
||||||
|
let hand = parseHand line
|
||||||
|
otherHands <- parse
|
||||||
|
return $ hand: otherHands
|
||||||
|
|
||||||
|
|
||||||
|
getHandValueTypeFromSorted :: [Int] -> Int
|
||||||
|
getHandValueTypeFromSorted [a, b, c, d, e] | a == e = 6
|
||||||
|
| a == d || b == e = 5
|
||||||
|
| a == c && d == e || a == b && c == e = 4
|
||||||
|
| a == c || b == d || c == e = 3
|
||||||
|
| a == b && (c == d || d == e) || b == c && d == e = 2
|
||||||
|
| a == b || b == c || c == d || d == e = 1
|
||||||
|
| otherwise = 0
|
||||||
|
|
||||||
|
getHandSecondValue :: [Int] -> Int
|
||||||
|
getHandSecondValue [a, b, c, d, e] = 100 * (100 * (100 * (100 * a + b) + c) + d) + e
|
||||||
|
|
||||||
|
sortHandValues :: [HandValue] -> [HandValue]
|
||||||
|
sortHandValues = sortOn value
|
||||||
|
|
||||||
|
getWinningsFromSorted :: Int -> [Hand] -> Int
|
||||||
|
getWinningsFromSorted _ [] = 0
|
||||||
|
getWinningsFromSorted i (hh: t) = i * bid hh + getWinningsFromSorted (i + 1) t
|
||||||
12
day07/Main.hs
Normal file
12
day07/Main.hs
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
module Main where
|
||||||
|
|
||||||
|
import Commons
|
||||||
|
import qualified Part1
|
||||||
|
import qualified Part2
|
||||||
|
|
||||||
|
|
||||||
|
main = do hands <- parse
|
||||||
|
let part1Res = Part1.getTotalWinnings hands
|
||||||
|
print part1Res
|
||||||
|
let part2Res = Part2.getTotalWinnings hands
|
||||||
|
print part2Res
|
||||||
15
day07/Part1.hs
Normal file
15
day07/Part1.hs
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
module Part1 where
|
||||||
|
|
||||||
|
import Commons
|
||||||
|
import Data.List (sort, sortOn)
|
||||||
|
|
||||||
|
|
||||||
|
getHandValue :: Hand -> HandValue
|
||||||
|
getHandValue hand = HandValue {hand = hand, value = 100 ^ 5 * (getHandValueTypeFromSorted . sort) (values hand)
|
||||||
|
+ getHandSecondValue (values hand)}
|
||||||
|
|
||||||
|
sortHands :: [Hand] -> [Hand]
|
||||||
|
sortHands = map hand . sortHandValues . map getHandValue
|
||||||
|
|
||||||
|
getTotalWinnings :: [Hand] -> Int
|
||||||
|
getTotalWinnings = getWinningsFromSorted 1 . sortHands
|
||||||
34
day07/Part2.hs
Normal file
34
day07/Part2.hs
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
module Part2 where
|
||||||
|
|
||||||
|
import Commons
|
||||||
|
import Data.List (sort, sortOn)
|
||||||
|
|
||||||
|
|
||||||
|
getHandValueTypeFromSortedJokers :: [Int] -> Int
|
||||||
|
getHandValueTypeFromSortedJokers [0, b, c, d, e] | e == 0 = 6
|
||||||
|
| d == 0 || b == e = 6
|
||||||
|
| c == 0 && d == e || b == 0 && c == e = 6
|
||||||
|
| c == 0 || b == d || c == e = 5
|
||||||
|
| b == 0 && (c == d || d == e) = 5
|
||||||
|
| b == c && d == e = 4
|
||||||
|
| b == 0 || b == c || c == d || d == e = 3
|
||||||
|
| otherwise = 1
|
||||||
|
getHandValueTypeFromSortedJokers values = getHandValueTypeFromSorted values
|
||||||
|
|
||||||
|
getHandValue :: Hand -> HandValue
|
||||||
|
getHandValue hand = HandValue {hand = hand, value = 100 ^ 5 * (getHandValueTypeFromSortedJokers . sort) (values hand)
|
||||||
|
+ getHandSecondValue (values hand)}
|
||||||
|
|
||||||
|
sortHands :: [Hand] -> [Hand]
|
||||||
|
sortHands = map hand . sortHandValues . map getHandValue
|
||||||
|
|
||||||
|
applyJokers :: [Int] -> [Int]
|
||||||
|
applyJokers [] = []
|
||||||
|
applyJokers (v: t) | v == 11 = 0: applyJokers t
|
||||||
|
| otherwise = v: applyJokers t
|
||||||
|
|
||||||
|
applyJokersToHands :: [Hand] -> [Hand]
|
||||||
|
applyJokersToHands = map (\ hand -> Hand {values = applyJokers (values hand), bid = bid hand})
|
||||||
|
|
||||||
|
getTotalWinnings :: [Hand] -> Int
|
||||||
|
getTotalWinnings = getWinningsFromSorted 1 . sortHands . applyJokersToHands
|
||||||
Reference in New Issue
Block a user