day2.hs (2271B)
1 -- AOC 2023: Day 2 2 -- 3 -- There is a game where you want to determine the number of each 4 -- colour of cube in bag. The bag contains red, green, and blue 5 -- cubes. 6 -- 7 -- Task 1: Grab a random handful of cubes and count each colour. 8 -- Do this a few times per game and perform many games. This will 9 -- result in a list of data such as: 10 -- 11 -- Game 1: 3 blue, 4 red; 1 red, 2 green, 6 blue; 2 green 12 -- ... 13 -- Game N: 6 red, 1 blue, 3 green; 2 blue, 1 red, 2 green 14 -- 15 -- After this data was collected you are told that the bag 16 -- contained only 12 red, 13 green, and 14 blue cubes. Provide 17 -- the sum of all the valid game's numbers. 18 -- 19 -- Task 2: The power of a set of cubes is the minimum number of 20 -- each colour needed to make a game valid. Provide the sum of 21 -- the powers of all games. 22 -- 23 {-# LANGUAGE OverloadedStrings #-} 24 25 import qualified Data.Text as T 26 import qualified Data.Text.IO as TI 27 import Text.Printf (printf) 28 29 splitgame :: T.Text -> (Int, [(Int, T.Text)]) 30 splitgame st = 31 let (gn, t) = T.breakOn ": " st 32 n = read $ T.unpack $ snd $ T.break (== ' ') gn :: Int 33 tuples = 34 map to_int_text . map (T.break (== ' ')) $ 35 T.splitOn ", " $ T.replace ": " "" $ T.replace ";" "," t 36 in (n, tuples) 37 38 to_int_text :: (T.Text, T.Text) -> (Int, T.Text) 39 to_int_text (f, s) = (read (T.unpack f) :: Int, s) 40 41 get_colour_list :: T.Text -> [(Int, T.Text)] -> [Int] 42 get_colour_list c l = map fst $ filter ((== c) . snd) l 43 44 get_rgb_triple :: [(Int, T.Text)] -> ([Int], [Int], [Int]) 45 get_rgb_triple l = 46 let r = get_colour_list " red" l 47 g = get_colour_list " green" l 48 b = get_colour_list " blue" l 49 in (r, g, b) 50 51 isvalidgame :: (Int, [(Int, T.Text)]) -> Int 52 isvalidgame (n, t) = 53 let (r, g, b) = get_rgb_triple t 54 in if (null $ filter (> 12) r) && 55 (null $ filter (> 13) g) && (null $ filter (> 14) b) 56 then n 57 else 0 58 59 gamepower :: (Int, [(Int, T.Text)]) -> Int 60 gamepower (_, t) = 61 let (r, g, b) = get_rgb_triple t 62 in (foldr1 max r) * (foldr1 max g) * (foldr1 max b) 63 64 main = do 65 contents <- TI.getContents 66 let games = map splitgame $ T.lines contents 67 printf "Task 1: %8d\n" (sum $ map isvalidgame games) 68 printf "Task 2: %8d\n" (sum $ map gamepower games)