{-# OPTIONS_GHC -Wno-tabs #-}
import Data.List
type Card = [[(Bool, Int)]]
makeCard :: [[a]] -> [[(Bool, a)]]
makeCard [] = []
makeCard (a : as) = map (\x -> (False, x)) a : makeCard as
horiz :: [[(a, b)]] -> [[a]]
horiz = (map . map) fst
vert :: [[(a, b)]] -> [[a]]
vert = transpose . (map . map) fst
trimColumn :: [[a]] -> [[a]]
trimColumn [] = []
trimColumn a = transpose . tail . transpose $ a
diagL :: [[(a, b)]] -> [a]
diagL [] = []
diagL a = (fst . head . head) a : (diagL $ (trimColumn . tail) a)
diagR :: [[(a, b)]] -> [a]
diagR [] = []
diagR a = (fst . head . last) a : (diagR $ (trimColumn . init) a)
bingos :: [[(a, b)]] -> [[a]]
bingos a = diagL a : diagR a : horiz a ++ vert a
markLine :: [(Bool, Int)] -> Int -> [(Bool, Int)]
markLine (x : xs) i
| i == snd x = (True, snd x) : xs
| otherwise = x : markLine xs i
mark :: Card -> Int -> Card
mark c i = map (flip markLine i) c
marks :: Card -> [Int] -> Card
marks c [] = c
marks c (i : is) = marks (mark c i) is
hasBingo :: Card -> Bool
hasBingo c = elem [True, True, True, True, True] (bingos c)
won :: [Bool] -> Int
won a = go 0 a
where
go :: Int -> [Bool] -> Int
go i (b : bs)
| b = i
| otherwise = go (i + 1) bs
entry :: [[[Int]]] -> [Int] -> Int
entry cs is = won . map hasBingo . map (flip marks is) $ map makeCard cs
post a comment