This commit is contained in:
2023-12-04 10:31:36 +01:00
parent fd46f6dfa2
commit e746e22b0b
5 changed files with 90 additions and 0 deletions

View File

@@ -28,3 +28,11 @@ executable day03
build-depends: base ^>=4.15.1.0
hs-source-dirs: day03
default-language: Haskell2010
executable day04
main-is: Main.hs
other-modules: Commons Part1 Part2
build-depends: base ^>=4.15.1.0, MissingH
hs-source-dirs: day04
default-language: Haskell2010

28
day04/Commons.hs Normal file
View File

@@ -0,0 +1,28 @@
module Commons where
import Data.List.Utils (split)
import GHC.IO.Handle (isEOF)
data Card = Card { cid :: Int, nCopies :: Int, winningNumbers :: [Int], numbers :: [Int] } deriving (Show)
parseNumbers :: String -> [Int]
parseNumbers [] = []
parseNumbers (' ': n1: n2: t) = read [n1, n2]: parseNumbers t
parseCard :: String -> Card
parseCard ('C': 'a': 'r': 'd': ' ': i1: i2: i3: ':': t) = let (rawWN: rawN: _) = split " |" t
in Card {cid = read [i1, i2, i3],
nCopies = 1,
winningNumbers = parseNumbers rawWN,
numbers = parseNumbers rawN}
parse :: IO [Card]
parse = do done <- isEOF
if done
then return []
else do line <- getLine
let card = parseCard line
otherCards <- parse
return (card: otherCards)

12
day04/Main.hs Normal file
View File

@@ -0,0 +1,12 @@
module Main where
import Commons
import qualified Part1
import qualified Part2
main = do cards <- parse
let part1Res = sum (Part1.getAllPoints cards)
print part1Res
let part2Res = sum (Part2.getNCopies cards)
print part2Res

18
day04/Part1.hs Normal file
View File

@@ -0,0 +1,18 @@
module Part1 where
import Commons
getNWinningNumbers :: [Int] -> [Int] -> Int
getNWinningNumbers _ [] = 0
getNWinningNumbers winningNumbers (n: t) | n `elem` winningNumbers = 1 + getNWinningNumbers winningNumbers t
| otherwise = getNWinningNumbers winningNumbers t
getPoints :: Card -> Int
getPoints card = let nWinningNumbers = getNWinningNumbers (winningNumbers card) (numbers card)
in if nWinningNumbers == 0
then 0
else 2 ^ (nWinningNumbers - 1)
getAllPoints :: [Card] -> [Int]
getAllPoints = map getPoints

24
day04/Part2.hs Normal file
View File

@@ -0,0 +1,24 @@
module Part2 where
import Commons
getNWinningNumbers :: [Int] -> [Int] -> Int
getNWinningNumbers _ [] = 0
getNWinningNumbers winningNumbers (n: t) | n `elem` winningNumbers = 1 + getNWinningNumbers winningNumbers t
| otherwise = getNWinningNumbers winningNumbers t
updateNCopies :: Int -> Card -> [Card] -> [Card]
updateNCopies 0 card otherCards = otherCards
updateNCopies n card (c: t) = c {nCopies = nCopies card + nCopies c}: updateNCopies (n - 1) card t
updateCopies :: Card -> [Card] -> [Card]
updateCopies card otherCards = let nWinningNumbers = getNWinningNumbers (winningNumbers card) (numbers card)
in updateNCopies nWinningNumbers card otherCards
updateAllCopies :: [Card] -> [Card]
updateAllCopies [] = []
updateAllCopies (c: t) = c: updateAllCopies (updateCopies c t)
getNCopies :: [Card] -> [Int]
getNCopies cards = map nCopies (updateAllCopies cards)