diff options
Diffstat (limited to '')
-rw-r--r-- | 2020/11-Seating_System/first.hs | 43 |
1 files changed, 43 insertions, 0 deletions
diff --git a/2020/11-Seating_System/first.hs b/2020/11-Seating_System/first.hs new file mode 100644 index 0000000..d5871d5 --- /dev/null +++ b/2020/11-Seating_System/first.hs @@ -0,0 +1,43 @@ +module Main (main) where +import Control.Monad (when) +import Data.List (foldl') +import Data.Maybe (mapMaybe) +import qualified Data.Map as M +import System.Exit (die) + +exampleExpectedOutput = 37 + +type Seating = M.Map (Int, Int) Bool + +inputToList :: String -> [((Int, Int), Bool)] +inputToList = snd . foldl' nextSeat ((0, 0), []) + where + nextSeat :: ((Int, Int), [((Int, Int), Bool)]) -> Char -> ((Int, Int), [((Int, Int), Bool)]) + nextSeat ((x, y), acc) '\n' = ((0, y+1), acc) + nextSeat ((x, y), acc) '.' = ((x+1, y), acc) + nextSeat ((x, y), acc) 'L' = ((x+1, y), acc ++ [((x, y), False)]) + +parseInput :: String -> IO Seating +parseInput filename = do + input <- readFile filename + return $ M.fromList (inputToList input) + +compute :: Seating -> Int +compute seating + | seating == seating' = length $ M.filter id seating + | otherwise = compute seating' + where + seating' = M.mapWithKey next seating + next :: (Int, Int) -> Bool -> Bool + next (x, y) False = around (x, y) == [] + next (x, y) True = length (around (x,y)) < 4 + around :: (Int, Int) -> [Bool] + around (x, y) = filter id $ mapMaybe (\v -> M.lookup v seating) [(x-1, y-1), (x, y-1), (x+1, y-1), (x-1, y), (x+1, y), (x-1, y+1), (x, y+1), (x+1, y+1)] + +main :: IO () +main = do + example <- parseInput "example" + let exampleOutput = compute example + when (exampleOutput /= exampleExpectedOutput) (die $ "example failed: got " ++ show exampleOutput ++ " instead of " ++ show exampleExpectedOutput) + input <- parseInput "input" + print $ compute input |