|
|
@ -1,47 +1,64 @@ |
|
|
|
module Main where |
|
|
|
|
|
|
|
import Data.List.Split (chunksOf, splitOn) |
|
|
|
import Debug.Trace (traceShowId) |
|
|
|
import Data.List (transpose) |
|
|
|
|
|
|
|
main :: IO () |
|
|
|
main = interact solution |
|
|
|
|
|
|
|
type Board = [[Int]] |
|
|
|
type BoardMask = [[Bool]] |
|
|
|
type Board = [(Bool, Int)] |
|
|
|
|
|
|
|
scnd :: (b -> c) -> (a, b) -> (a, c) |
|
|
|
scnd f (a, b) = (a, f b) |
|
|
|
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) |
|
|
|
|
|
|
|
frst :: (a -> c) -> (a, b) -> (c, b) |
|
|
|
frst f (a, b) = (f a, b) |
|
|
|
first :: (a -> c) -> (a, b) -> (c, b) |
|
|
|
first f (a, b) = (f a, b) |
|
|
|
|
|
|
|
solution :: String -> String |
|
|
|
solution = |
|
|
|
show |
|
|
|
-- ([Int], [Boards]) |
|
|
|
. scnd toBoards |
|
|
|
. scnd (map (map (read :: String -> Int))) |
|
|
|
. scnd (filter (not . null)) |
|
|
|
. scnd (map words) |
|
|
|
. frst (map (read :: String -> Int)) |
|
|
|
. frst splitcomma |
|
|
|
. (\x -> (head x, tail x)) |
|
|
|
. lines |
|
|
|
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 |
|
|
|
splitcomma :: String -> [String] -- "stole" the implementation from `words` |
|
|
|
splitcomma s = case dropWhile (==',') s of |
|
|
|
"" -> [] |
|
|
|
s' -> w : splitcomma s'' |
|
|
|
where |
|
|
|
(w, s'') = break (==',') s' |
|
|
|
|
|
|
|
toBoards :: [[Int]] -> [Board] |
|
|
|
toBoards [] = [] |
|
|
|
toBoards (a:b:c:d:e:r) = [a,b,c,d,e]:toBoards r |
|
|
|
|
|
|
|
calculateScore :: Int -> -- ^ winning number |
|
|
|
Board -> -- ^ winning board |
|
|
|
BoardMask -> -- ^ drawn numbers |
|
|
|
Int |
|
|
|
calculateScore = undefined |
|
|
|
|
|
|
|
checkWinning :: BoardMask -> Bool |
|
|
|
checkWinning = undefined |
|
|
|
getWinning' :: [Board] -> Board |
|
|
|
getWinning' (b:bs) |
|
|
|
| hasWon b = b |
|
|
|
| otherwise = getWinning' bs |
|
|
|
getWinning' [] = error "Wtf" |
|
|
|
|