2023 day 2 in Haskell

This commit is contained in:
Adam Ruzicka 2023-12-02 14:16:13 +01:00
parent 9052086822
commit a7ef2ed543
2 changed files with 73 additions and 0 deletions

68
2023/02/day2.hs Normal file
View File

@ -0,0 +1,68 @@
{-# LANGUAGE OverloadedStrings #-}
import Data.Text qualified as T
import Text.Printf (printf)
type Set = (Integer, Integer, Integer)
type Game = (Integer, [Set])
emptySet = (0, 0, 0)
part1 :: [Game] -> Integer
part1 = sum . map fst . filter (all setWithinLimits . snd)
part2 :: [Game] -> Integer
part2 = sum . map (setPower . minimumSet . snd)
minimumSet :: [Set] -> Set
minimumSet ss = (maximum $ map first ss, maximum $ map second ss, maximum $ map third ss)
where
first (r, _, _) = r
second (_, g, _) = g
third (_, _, b) = b
setWithinLimits (r, g, b) = r <= 12 && g <= 13 && b <= 14
parseGame :: T.Text -> Game
parseGame s = (parseId $ head parts, parseSets $ last parts)
where
parts = T.splitOn ":" s
parseId :: T.Text -> Integer
parseId = read . T.unpack . last . T.words
parseSets :: T.Text -> [Set]
parseSets = map parseSet . T.splitOn ";"
parseSet :: T.Text -> Set
parseSet = sumSets . map parseDraw . T.splitOn ","
addSets :: Set -> Set -> Set
addSets (r1, g1, b1) (r2, g2, b2) = (r1 + r2, g1 + g2, b1 + b2)
sumSets :: [Set] -> Set
sumSets = foldl addSets emptySet
setPower :: Set -> Integer
setPower (r, g, b) = r * g * b
parseDraw :: T.Text -> Set
parseDraw s = setOf count color
where
setOf n "red" = (n, 0, 0)
setOf n "green" = (0, n, 0)
setOf n "blue" = (0, 0, n)
parts = T.words s
color = last parts
count = read $ T.unpack $ head parts
parseInput :: T.Text -> [Game]
parseInput = map parseGame . T.lines
main :: IO ()
main = do
contents <- getContents
let parsed = parseInput $ T.pack contents
putStr $ printf "Part 1: %d\n" $ part1 parsed
putStr $ printf "Part 2: %d\n" $ part2 parsed

5
2023/02/example Normal file
View File

@ -0,0 +1,5 @@
Game 1: 3 blue, 4 red; 1 red, 2 green, 6 blue; 2 green
Game 2: 1 blue, 2 green; 3 green, 4 blue, 1 red; 1 green, 1 blue
Game 3: 8 green, 6 blue, 20 red; 5 blue, 4 red, 13 green; 5 green, 1 red
Game 4: 1 green, 3 red, 6 blue; 3 green, 6 red; 3 green, 15 blue, 14 red
Game 5: 6 red, 1 blue, 3 green; 2 blue, 1 red, 2 green