[hs] Solve 2020_11 part 1
This commit is contained in:
parent
3c49a0986a
commit
0d7682c9bb
2 changed files with 62 additions and 0 deletions
|
|
@ -13,6 +13,7 @@ import qualified Aoc.Y2020.D07 as D07
|
||||||
import qualified Aoc.Y2020.D08 as D08
|
import qualified Aoc.Y2020.D08 as D08
|
||||||
import qualified Aoc.Y2020.D09 as D09
|
import qualified Aoc.Y2020.D09 as D09
|
||||||
import qualified Aoc.Y2020.D10 as D10
|
import qualified Aoc.Y2020.D10 as D10
|
||||||
|
import qualified Aoc.Y2020.D11 as D11
|
||||||
|
|
||||||
year :: Year
|
year :: Year
|
||||||
year = Year 2020
|
year = Year 2020
|
||||||
|
|
@ -26,4 +27,5 @@ year = Year 2020
|
||||||
, ( 8, D08.day)
|
, ( 8, D08.day)
|
||||||
, ( 9, D09.day)
|
, ( 9, D09.day)
|
||||||
, (10, D10.day)
|
, (10, D10.day)
|
||||||
|
, (11, D11.day)
|
||||||
]
|
]
|
||||||
|
|
|
||||||
60
hs/src/Aoc/Y2020/D11.hs
Normal file
60
hs/src/Aoc/Y2020/D11.hs
Normal file
|
|
@ -0,0 +1,60 @@
|
||||||
|
{-# LANGUAGE TupleSections #-}
|
||||||
|
|
||||||
|
module Aoc.Y2020.D11
|
||||||
|
( day
|
||||||
|
) where
|
||||||
|
|
||||||
|
import Data.Maybe
|
||||||
|
|
||||||
|
import qualified Data.Map.Strict as Map
|
||||||
|
|
||||||
|
import Aoc.Day
|
||||||
|
import Aoc.Parse
|
||||||
|
|
||||||
|
data Seat = Empty | Occupied
|
||||||
|
deriving (Show, Eq)
|
||||||
|
|
||||||
|
isOccupied :: Seat -> Bool
|
||||||
|
isOccupied Occupied = True
|
||||||
|
isOccupied Empty = False
|
||||||
|
|
||||||
|
isEmpty :: Seat -> Bool
|
||||||
|
isEmpty = not . isOccupied
|
||||||
|
|
||||||
|
type Field = Map.Map (Int, Int) Seat
|
||||||
|
|
||||||
|
parser :: Parser Field
|
||||||
|
parser = do
|
||||||
|
ls <- concat . zipWith (\y -> zipWith (curry (y,)) [0..]) [0..] <$> pLines
|
||||||
|
pure $ Map.fromList [((x, y), s) | (y, (x, Just s)) <- ls]
|
||||||
|
where
|
||||||
|
pSeat = (Nothing <$ char '.') <|> (Just Empty <$ char 'L')
|
||||||
|
pLines = manyLines $ many pSeat
|
||||||
|
|
||||||
|
step :: Map.Map (Int, Int) Seat -> Map.Map (Int, Int) Seat
|
||||||
|
step field = Map.fromList $ map (\(xy, s) -> (xy, stepSeat field xy s)) $ Map.toList field
|
||||||
|
|
||||||
|
stepSeat :: Map.Map (Int, Int) Seat -> (Int, Int) -> Seat -> Seat
|
||||||
|
stepSeat field (x, y) s
|
||||||
|
| s == Empty && occupied == 0 = Occupied
|
||||||
|
| s == Occupied && occupied >= 4 = Empty
|
||||||
|
| otherwise = s
|
||||||
|
where
|
||||||
|
adjacent = mapMaybe (field Map.!?) $ filter (/= (x, y)) $ (,) <$> [x-1,x,x+1] <*> [y-1,y,y+1]
|
||||||
|
occupied = length $ filter isOccupied adjacent
|
||||||
|
|
||||||
|
iterateUntilSettled :: (Eq a) => (a -> a) -> a -> a
|
||||||
|
iterateUntilSettled f a
|
||||||
|
| a == a' = a
|
||||||
|
| otherwise = iterateUntilSettled f a'
|
||||||
|
where
|
||||||
|
a' = f a
|
||||||
|
|
||||||
|
solver :: Field -> IO ()
|
||||||
|
solver field = do
|
||||||
|
putStrLn ">> Part 1"
|
||||||
|
let field' = iterateUntilSettled step field
|
||||||
|
print $ length $ filter isOccupied $ Map.elems field'
|
||||||
|
|
||||||
|
day :: Day
|
||||||
|
day = dayParse parser solver
|
||||||
Loading…
Add table
Add a link
Reference in a new issue