adventofcode/2021/day04.hs

42 lines
1.4 KiB
Haskell

module Day04 where
import Data.List.Split ( splitOn )
import Data.Maybe (catMaybes, mapMaybe, listToMaybe)
import Data.List (transpose, sort)
type Board = [[Int]]
checkRowTime :: [Int] -> [Int] -> Maybe Int
checkRowTime values row = fmap maximum elemTimes
where
elemTimes = mapM (`lookup` times) row
times = zip values [0..]
checkBingoTime :: [Int] -> Board -> Maybe Int
checkBingoTime values board = listToMaybe $ sort $ catMaybes $ horTimes ++ verTimes
where
horTimes = map (checkRowTime values) board
verTimes = map (checkRowTime values) (transpose board)
calculateScore :: [Int] -> Int -> Board -> Int
calculateScore values time card = values!!time * sum unmarked
where
marked = take (time+1) values
unmarked = filter (`notElem` marked) $ concat card
main :: IO ()
main = do
firstLine <- getLine
let values = map (read :: String->Int) $ splitOn "," firstLine
_ <- getLine
input <- getContents
let cards = map (map (map (read::String->Int))) $ map (map words) $ splitOn [""] $ lines input
let cardsWithTime = mapMaybe (\card -> fmap (\t -> (t,card)) (checkBingoTime values card)) cards
putStr "part 1: "
let (time,card) = minimum cardsWithTime
print $ calculateScore values time card
putStr "part 2: "
let (time,card) = maximum cardsWithTime
print $ calculateScore values time card