You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
64 lines
1.6 KiB
64 lines
1.6 KiB
module Main where
|
|
|
|
import Data.List.Split (chunksOf, splitOn)
|
|
import Debug.Trace (traceShowId)
|
|
import Data.List (transpose)
|
|
|
|
main :: IO ()
|
|
main = interact solution
|
|
|
|
type Board = [(Bool, Int)]
|
|
|
|
second :: (b -> c) -> (a, b) -> (a, c)
|
|
second f (a, b) = (a, f b)
|
|
second2 :: (a -> b -> c) -> (a, b) -> (a, c)
|
|
second2 f (a, b) = (a, f a b)
|
|
|
|
first :: (a -> c) -> (a, b) -> (c, b)
|
|
first f (a, b) = (f a, b)
|
|
|
|
solution :: String -> String
|
|
solution = show
|
|
. second2 applydraws
|
|
. second ( chunksOf 25
|
|
. zip (repeat False)
|
|
. map (read :: String -> Int)
|
|
. concatMap words
|
|
)
|
|
. first ( map (read :: String -> Int)
|
|
. splitOn ","
|
|
)
|
|
. (\x -> (head x, tail x))
|
|
. lines
|
|
|
|
select :: Int -> Board -> Board
|
|
select n = map (\(d, p) -> ((n == p) || d, p))
|
|
|
|
hasWon :: Board -> Bool
|
|
hasWon b = any and r || any and (transpose r)
|
|
where r = chunksOf 5 (map fst b)
|
|
|
|
score :: Int -> Board -> Int
|
|
score lastn b = lastn * boardleft b
|
|
where boardleft = sum . map snd . filter (not . fst)
|
|
|
|
applydraw :: Int -> [Board] -> [Board]
|
|
applydraw n = map (select n)
|
|
|
|
applydraws ::[Int] -> [Board] -> [(Int, [Board])]
|
|
applydraws [] _ = []
|
|
applydraws (n:ns) b = (n, nb) : applydraws ns nb
|
|
where
|
|
nb = applydraw n b
|
|
|
|
getWinning :: [[Board]] -- ^ Mapped boards
|
|
-> Board
|
|
getWinning [] = error "WTF"
|
|
getWinning (bs:r) = if any hasWon bs then getWinning' bs else getWinning r
|
|
where
|
|
getWinning' :: [Board] -> Board
|
|
getWinning' (b:bs)
|
|
| hasWon b = b
|
|
| otherwise = getWinning' bs
|
|
getWinning' [] = error "Wtf"
|
|
|