diff options
author | Julien Dessaux | 2023-03-21 23:27:16 +0100 |
---|---|---|
committer | Julien Dessaux | 2023-03-21 23:27:16 +0100 |
commit | 2f64de03d805ba6eaf8cdf5929dc5b4348841c1c (patch) | |
tree | ab07c14a72ec478532346cd2752929773ee35046 /2020/11-Seating_System/first.hs | |
parent | 2020-10 in haskell (diff) | |
download | advent-of-code-2f64de03d805ba6eaf8cdf5929dc5b4348841c1c.tar.gz advent-of-code-2f64de03d805ba6eaf8cdf5929dc5b4348841c1c.tar.bz2 advent-of-code-2f64de03d805ba6eaf8cdf5929dc5b4348841c1c.zip |
2020-11 in haskell
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 |