{-# Language QuasiQuotes, ImportQualifiedPost, TemplateHaskell #-}
module Main (main) where
import Advent (format, stageTH)
import Data.Map (Map)
import Data.Map qualified as Map
data C = Cred | Cgreen | Cblue deriving (C -> C -> Bool
(C -> C -> Bool) -> (C -> C -> Bool) -> Eq C
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: C -> C -> Bool
== :: C -> C -> Bool
$c/= :: C -> C -> Bool
/= :: C -> C -> Bool
Eq, Eq C
Eq C =>
(C -> C -> Ordering)
-> (C -> C -> Bool)
-> (C -> C -> Bool)
-> (C -> C -> Bool)
-> (C -> C -> Bool)
-> (C -> C -> C)
-> (C -> C -> C)
-> Ord C
C -> C -> Bool
C -> C -> Ordering
C -> C -> C
forall a.
Eq a =>
(a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
$ccompare :: C -> C -> Ordering
compare :: C -> C -> Ordering
$c< :: C -> C -> Bool
< :: C -> C -> Bool
$c<= :: C -> C -> Bool
<= :: C -> C -> Bool
$c> :: C -> C -> Bool
> :: C -> C -> Bool
$c>= :: C -> C -> Bool
>= :: C -> C -> Bool
$cmax :: C -> C -> C
max :: C -> C -> C
$cmin :: C -> C -> C
min :: C -> C -> C
Ord, Int -> C -> ShowS
[C] -> ShowS
C -> String
(Int -> C -> ShowS) -> (C -> String) -> ([C] -> ShowS) -> Show C
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> C -> ShowS
showsPrec :: Int -> C -> ShowS
$cshow :: C -> String
show :: C -> String
$cshowList :: [C] -> ShowS
showList :: [C] -> ShowS
Show)
stageTH
main :: IO ()
IO ()
main =
do input <- [format|2023 2 (Game %d: (%d @C)&(, )&(; )%n)*|]
let summaries = [(Int
i, [[(Int, C)]] -> Map C Int
summarizeGame [[(Int, C)]]
rounds) | (Int
i, [[(Int, C)]]
rounds) <- [(Int, [[(Int, C)]])]
input]
print (sum [i | (i, summary) <- summaries, Map.isSubmapOfBy (<=) summary part1])
print (sum [product summary | (_, summary) <- summaries])
summarizeGame :: [[(Int, C)]] -> Map C Int
summarizeGame :: [[(Int, C)]] -> Map C Int
summarizeGame [[(Int, C)]]
rs = (Int -> Int -> Int) -> [Map C Int] -> Map C Int
forall (f :: * -> *) k a.
(Foldable f, Ord k) =>
(a -> a -> a) -> f (Map k a) -> Map k a
Map.unionsWith Int -> Int -> Int
forall a. Ord a => a -> a -> a
max [[(Int, C)] -> Map C Int
summarizeRound [(Int, C)]
r | [(Int, C)]
r <- [[(Int, C)]]
rs]
summarizeRound :: [(Int, C)] -> Map C Int
summarizeRound :: [(Int, C)] -> Map C Int
summarizeRound [(Int, C)]
r = [(C, Int)] -> Map C Int
forall k a. Ord k => [(k, a)] -> Map k a
Map.fromList [(C
color, Int
count) | (Int
count, C
color) <- [(Int, C)]
r]
part1 :: Map C Int
part1 :: Map C Int
part1 = [(C, Int)] -> Map C Int
forall k a. Ord k => [(k, a)] -> Map k a
Map.fromList [(C
Cred, Int
12), (C
Cgreen, Int
13), (C
Cblue, Int
14)]