Commit a3175189 authored by Neil Smith's avatar Neil Smith
Browse files

Done day 11

parent 1e9f01ce
# This YAML file describes your package. Stack will automatically generate a
# Cabal file when you run `stack build`. See the hpack website for help with
# this file: <https://github.com/sol/hpack>.
name: advent11
synopsis: Advent of Code
version: '0.0.1'
default-extensions:
- AllowAmbiguousTypes
- ApplicativeDo
- BangPatterns
- BlockArguments
- DataKinds
- DeriveFoldable
- DeriveFunctor
- DeriveGeneric
- DeriveTraversable
- EmptyCase
- FlexibleContexts
- FlexibleInstances
- FunctionalDependencies
- GADTs
- GeneralizedNewtypeDeriving
- ImplicitParams
- KindSignatures
- LambdaCase
- MonadComprehensions
- MonoLocalBinds
- MultiParamTypeClasses
- MultiWayIf
- NamedFieldPuns
- NegativeLiterals
- NumDecimals
# - OverloadedLists
- OverloadedStrings
- PartialTypeSignatures
- PatternGuards
- PatternSynonyms
- PolyKinds
- RankNTypes
- RecordWildCards
- ScopedTypeVariables
- TemplateHaskell
- TransformListComp
- TupleSections
- TypeApplications
- TypeFamilies
- TypeInType
- TypeOperators
- ViewPatterns
executables:
advent11:
main: advent11.hs
source-dirs: src
dependencies:
- base >= 2 && < 6
- containers
- mtl
- monad-loops
advent11naive:
main: advent11naive.hs
source-dirs: src
dependencies:
- base >= 2 && < 6
- containers
-- import Debug.Trace
import Prelude hiding (Left, Right)
import qualified Data.Map as M
import Data.Map ((!))
import qualified Data.Set as S
-- import Data.Sort
import Data.List
import Control.Monad.Reader
import Control.Monad.Loops
type Position = (Int, Int)
data Seat = Floor | Empty | Occupied deriving (Eq, Ord)
data Direction = Up | UpRight | Right | DownRight | Down | DownLeft | Left | UpLeft
deriving (Eq, Ord, Show, Enum)
type Seats = M.Map Position Seat
type Neighbourhood = M.Map Position (S.Set Position)
type Rule = Seats -> Neighbourhood -> Position -> Seat -> Seat
instance Show Seat where
show Floor = "."
show Empty = "L"
show Occupied = "#"
type CachedSeats a = Reader (Neighbourhood, Rule) a
main :: IO ()
main =
do text <- readFile "data/advent11.txt"
let (seats, maxCorner) = readGrid text
-- print $ M.size seats
-- print maxCorner
print $ part1 seats
print $ part2 seats
part1 seats = M.size $ M.filter (== Occupied) stableSeats
where cachedNeighbours = allNeighbourhoods seats
env = (cachedNeighbours, ruleA)
stableSeats = snd $ runReader (runSteps seats) env
part2 seats = M.size $ M.filter (== Occupied) stableSeats
where cachedNeighbours = allSightNeighbourhoods seats
env = (cachedNeighbours, ruleB)
stableSeats = snd $ runReader (runSteps seats) env
runSteps :: Seats -> CachedSeats (Seats, Seats)
runSteps seats = iterateUntilM (uncurry (==)) seatChanges (M.empty, seats)
seatChanges :: (Seats, Seats) -> CachedSeats (Seats, Seats)
seatChanges (_, seats0) =
do seats <- step seats0
return (seats0, seats)
step :: Seats -> CachedSeats Seats
step seats =
do (nbrs, rule) <- ask
return $ M.mapWithKey (rule seats nbrs) seats
ruleA :: Seats -> Neighbourhood -> Position -> Seat -> Seat
ruleA seats nbrs here thisSeat
| thisSeat == Empty && nOccs == 0 = Occupied
| thisSeat == Occupied && nOccs >= 4 = Empty
| otherwise = thisSeat
where nOccs = M.size $ occupiedNeighbours seats nbrs here
ruleB :: Seats -> Neighbourhood -> Position -> Seat -> Seat
ruleB seats nbrs here thisSeat
| thisSeat == Empty && nOccs == 0 = Occupied
| thisSeat == Occupied && nOccs >= 5 = Empty
| otherwise = thisSeat
where nOccs = M.size $ occupiedNeighbours seats nbrs here
neighbours (r, c) = S.delete (r, c) $ S.fromList [(r + dr, c + dc) | dr <- [-1, 0, 1], dc <- [-1, 0, 1]]
neighbourhood seats here = S.intersection (M.keysSet seats) (neighbours here)
allNeighbourhoods :: Seats -> Neighbourhood
allNeighbourhoods seats = M.mapWithKey (\h _ -> neighbourhood seats h) seats
occupiedNeighbours seats nbrs here = M.filter (== Occupied) $ M.restrictKeys seats (nbrs!here)
onSightLine :: Position -> Direction -> Position -> Bool
onSightLine (r0, c0) Down (r, c) = (c0 == c) && (r > r0)
onSightLine (r0, c0) Up (r, c) = (c0 == c) && (r < r0)
onSightLine (r0, c0) Right (r, c) = (r0 == r) && (c > c0)
onSightLine (r0, c0) Left (r, c) = (r0 == r) && (c < c0)
onSightLine (r0, c0) DownRight (r, c) = ((r - r0) > 0) && ((r - r0) == (c - c0))
onSightLine (r0, c0) UpLeft (r, c) = ((r - r0) < 0) && ((r - r0) == (c - c0))
onSightLine (r0, c0) DownLeft (r, c) = ((r - r0) > 0) && ((r - r0) == (c0 - c))
onSightLine (r0, c0) UpRight (r, c) = ((r - r0) < 0) && ((r - r0) == (c0 - c))
manhattan (r1, c1) (r2, c2) = abs (r1 - r2) + abs (c1 - c2)
closestInDirection seats here direction = take 1 sortedSeats
-- where seatsInDirection = M.keys $ M.filterWithKey (\o _ -> onSightLine here direction o) seats
where seatsInDirection = filter (onSightLine here direction) $ M.keys seats
sortedSeats = sortOn (manhattan here) seatsInDirection
closestInSight :: Seats -> Position -> (S.Set Position)
closestInSight seats here = S.fromList $ concatMap (closestInDirection seats here) [d | d <- [Up .. UpLeft]]
allSightNeighbourhoods :: Seats -> Neighbourhood
allSightNeighbourhoods seats = M.mapWithKey (\h _ -> closestInSight seats h) seats
-- occupiedInSight :: Seats -> Position -> Seats
-- occupiedInSight seats here = M.filter (== Occupied) $ M.restrictKeys seats $ closestInSight seats here
readGrid :: String -> (Seats, Position)
readGrid input = (seats, (maxR, maxC))
where seats = M.fromList $ concat
[ [((r, c), Empty) | (t, c) <- zip row [0..], t == 'L']
| (row, r) <- zip rows [0..] ]
rows = lines input
maxC = (length $ head rows) - 1
maxR = (length rows) - 1
showGrid seats (maxR, maxC) =
unlines $ [ concat [showSeat (r, c) | c <- [0..maxC] ] | r <- [0..maxR]]
where showSeat here = show $ M.findWithDefault Floor here seats
-- import Debug.Trace
import Prelude hiding (Left, Right)
import qualified Data.Map as M
import Data.Map ((!))
import qualified Data.Set as S
-- import Data.Sort
import Data.List
type Position = (Int, Int)
data Seat = Floor | Empty | Occupied deriving (Eq, Ord)
data Direction = Up | UpRight | Right | DownRight | Down | DownLeft | Left | UpLeft
deriving (Eq, Ord, Show, Enum)
type Seats = M.Map Position Seat
instance Show Seat where
show Floor = "."
show Empty = "L"
show Occupied = "#"
main :: IO ()
main =
do text <- readFile "data/advent11.txt"
let (seats, maxCorner) = readGrid text
print $ M.size seats
print maxCorner
print $ part1 seats
print $ part2 seats
-- print $ part2 trees maxCorner
part1 seats = M.size $ M.filter (== Occupied) $ runUntilSame ruleA seats
part2 seats = M.size $ M.filter (== Occupied) $ runUntilSame ruleB seats
step rule seats = M.mapWithKey (rule seats) seats
runSteps rule seats = iterate (step rule) seats
seatDifferences rule seats = zip (runSteps rule seats) (tail $ runSteps rule seats)
runUntilSame rule seats = fst $ head $ dropWhile (uncurry (/=)) $ seatDifferences rule seats
ruleA seats here thisSeat
| thisSeat == Empty && nOccs == 0 = Occupied
| thisSeat == Occupied && nOccs >= 4 = Empty
| otherwise = thisSeat
where nOccs = M.size $ occupiedNeighbours seats here
ruleB seats here thisSeat
| thisSeat == Empty && nOccs == 0 = Occupied
| thisSeat == Occupied && nOccs >= 5 = Empty
| otherwise = thisSeat
where nOccs = M.size $ occupiedInSight seats here
neighbours (r, c) = S.delete (r, c) $ S.fromList [(r + dr, c + dc) | dr <- [-1, 0, 1], dc <- [-1, 0, 1]]
neighbourhood seats here = M.restrictKeys seats (neighbours here)
occupiedNeighbours seats here = M.filter (== Occupied) $ neighbourhood seats here
onSightLine :: Position -> Direction -> Position -> Bool
onSightLine (r0, c0) Down (r, c) = (c0 == c) && (r > r0)
onSightLine (r0, c0) Up (r, c) = (c0 == c) && (r < r0)
onSightLine (r0, c0) Right (r, c) = (r0 == r) && (c > c0)
onSightLine (r0, c0) Left (r, c) = (r0 == r) && (c < c0)
onSightLine (r0, c0) DownRight (r, c) = ((r - r0) > 0) && ((r - r0) == (c - c0))
onSightLine (r0, c0) UpLeft (r, c) = ((r - r0) < 0) && ((r - r0) == (c - c0))
onSightLine (r0, c0) DownLeft (r, c) = ((r - r0) > 0) && ((r - r0) == (c0 - c))
onSightLine (r0, c0) UpRight (r, c) = ((r - r0) < 0) && ((r - r0) == (c0 - c))
manhattan (r1, c1) (r2, c2) = abs (r1 - r2) + abs (c1 - c2)
closestInDirection seats here direction = take 1 sortedSeats
-- where seatsInDirection = M.keys $ M.filterWithKey (\o _ -> onSightLine here direction o) seats
where seatsInDirection = filter (onSightLine here direction) $ M.keys seats
sortedSeats = sortOn (manhattan here) seatsInDirection
closestInSight :: Seats -> Position -> (S.Set Position)
closestInSight seats here = S.fromList $ concatMap (closestInDirection seats here) [d | d <- [Up .. UpLeft]]
occupiedInSight :: Seats -> Position -> Seats
occupiedInSight seats here = M.filter (== Occupied) $ M.restrictKeys seats $ closestInSight seats here
readGrid :: String -> (Seats, Position)
readGrid input = (seats, (maxR, maxC))
where seats = M.fromList $ concat
[ [((r, c), Empty) | (t, c) <- zip row [0..], t == 'L']
| (row, r) <- zip rows [0..] ]
rows = lines input
maxC = (length $ head rows) - 1
maxR = (length rows) - 1
showGrid seats (maxR, maxC) =
unlines $ [ concat [showSeat (r, c) | c <- [0..maxC] ] | r <- [0..maxR]]
where showSeat here = show $ M.findWithDefault Floor here seats
.LLLL.L.LLLL.LL.LLL.L.LLLLLLL.LLLLL.LLLLLLLLLLLLL.LLLL.LLL.LLLLL.LLLLLLLL.LLLLL.LLLLLLL.LLLLL
LLLLLLL.LLLLLLL.LLLLLLLLLLLL.LLLLLLLLLLLLL.LLLLLL.LLLL.LLL..LLLL.LLLLLLLL.LLLLL.LLLLLLL.LLLLL
LLLLLLLLLLLL.LL.LLLLL.LLLL.L.LLLL.LLLLLL.L.LLL.LL..LLL.LLLLLLLLLLLLLLLLLL.L.LLL.LLLLLLL.LLLLL
LLLLLLLLLLLLLLL.LLLLL.LLLLLL.LLLLLLL.LLLLL.LLLLLL.LLLL.LLLLLLLLL.LLLLLLLL.LLLLL.LLLLLLL.L.LLL
LL.LLLL.LLLLLLL.L.LLL.LLLLLL.L.LL.LLLLLLLL.LLLLLLLLL.LLLL.LLLLLL.LLLLLLLL.LL.LL.LLLLLLL.LLLLL
LLLLLLL.LLLLLLL.LLLLL.LLLLLLL.LLL.LLLLL.LLLLLLLLL.LLLL.LLLLLLLLL.LLLLLLLL.LLLL.L.LLLLLLLLLLLL
LLLLLLL.LLLLLLL.LLLLLLLLLLLL.LL.L.LLLLLLLL.LLLLLLLLLLL.LLLLLLLLL.LLLLLLLLLLLLLLLLLLLLLL.LLLL.
LLLLLLLLLLLLLLL.LLLLLLLLLLL..LLLL.LLLLLLLL.LLLLLL.LL.L.LLLLL.LLL.LLLLLLLLLLLLL.LLLLLLL.L.LLLL
....L..L.....L......LL...L.LL.......L...L.L......L.L.LLL....L..L....L.LL..LLL....LL..L..L...L
LLLLLLLLLLLLL.L.LLLLLLLLLLLL.LLLLLL.LLLLLL.LLLLLL.LLLLLLLLLLLLLL.LLLL.LLL.LLLLL.LLLLLLLLLLLL.
LLLLLLL.LLLLLLL.LLLLLLLLLL.L.LLLL.LLLLL.LL.LLLLLL.LLLLLLLLLLLLLL.LLLLLLLL.LLLLL.LLLLLLLLLLLLL
LLLLLLL.LLLLLLL.LLLLL.LLLLLL.LLLL.LLLLLLLLLLLLLLLLLLLLL.LLLLLLLL.LLLLLLLL.LLLLLLLLLLLLL.LLLLL
LLLLLLL.LLLLLLLLLLLLL.LLLLLL.LLLL.LLLLL.LL.LL.LLLLLLLL.LLLLLLLLLLLLLLLLLL..LLLL.LLLLLLLLLLLLL
LLLL.LL.LLLLLLLLLLLLL.LLLLLL.LLLL.LLLLLLLL.LLLLLL.LLLLLLLLLLLLLL.LLLLLLLL.LLLLL.LLLLLLL.L.LLL
LLLLLLL..LLLLLL.LLLLL..LLLLL.LLLL.LLLLLLLLLLL.LLL.LLL..LLLLLLLLL.LLLLLLLLLLLLLLLLLLLLLL..LLLL
...L...L..LL....L.......L...L.......LL........LL.....LL....L.....LL............L..LL....L....
LLLLLLL.LLLLLLL.LLLLL.LLLLLLLLLLL.LLLLLLLL.LLLLLL.LLLL..LLLLLLLL.LLLLLLLL.LLL.L.LLLLLLLLLLLLL
LLLLLLL.LLLLLLL.LLLLLLLLLLLL.L.LLLLLLLLLLL.LLLLL.LLLLLLL..LLLLLL.LLLLLL.LLLLLLLLLLLLL.L.LLLLL
LLLLLLL.LLLLLLLLLL.L..LLLLLLLLLLL.L.L.LLLLLLLLLLL.LLLL.LLLLL.LLL.LLLLLLLL.LLLLLLLLLLLLL.LLLLL
LLLLLLL.LLLLLLL.LLLLL.LLLLLL.LLLL.LLLLLLLLLLLLL.L.LLLL.LLLLLLLLL.LLLLLLLL..LLLL.LLLLLLLLLLLLL
LLLLLLLLLLLL.LL.LLLLL.LLLLLL.LLLLLLLLLLLLL..LLLLL.LLLL.LLLLL.LLL.LLLLLLLL.LL.LLLLLLLLLL...LLL
LLLLLLLLLLLLLLL.LLLLL.LLLLLL.LLLLLLLLLLLLLLLLLLLL.L.LLLLLLLLLLLL.LLLLLLLL.LLLLL.LLLLLLLLLLLLL
LLLLLLL.LLLLLLL.LLLLLLLLLLLL.L.LL.LLLLLL.LLLLLLLL.LLLLLLLLLLLLLL.LL.LLLLL.LLLLL.LLLLLLL.LLLLL
LLLLLLLLLLLLLLLLLLLLL.LLLLLL.LLLL.LLLLLLLLLLLL.LLLLLLLLLLLLLLLLL.LLLLLLLL.LLLLL.LLLLL.L.LLLLL
...........LL.....L.LL....L....L..LL..LL.L.LLLL........LL.L.LL..L......L...LL...LL..L.L......
LLLLLLL.LLLLLLL.LLLLL.LLLLLLLLLLL.LLLLL.LL.LLLLLL.LLLL.LLL.LLLLL..LLLLLLLLLLLLLLLLLLLLL.LLLLL
LLLLLLLLLLLLLLL.LLLLL.LLLLLLLLLLLLLLLL.LLLLLLLLLL.LLLL.LLLLLLLLLLLLLLLL.L.LLLLLLLLLLLLL.LLLLL
LLLLLLLLLLLLLLL.LLLLL.LLLLLLLLL.LLLLLLLLLL.LLLLLL.LLLL.LLLLLLLLL.LLLLLLL..LLLLL.LLLLLLLLLLLLL
LLLLLLL.LLLLLLLLLLLLLLLLLLLLLLLLL.LLLLLLLL.LLLLLLLLLLLLLLL.LLLLL.L..LLLLL.LLLLL.LLLLLLL.LLLLL
LLLLLL..LLLLLLL.LLLLL.LLLLLL.LLLL.LLLL.LLL.LLLLLLLLLLLLLLLLLLLLL.LLLLLLLL.LLLLL.LLLLLLL.LLLLL
LL.LL...L....LLL.L.L....LL.L.....L...LLL..LL.......L.......L.......L..L......LLL..L.LL..LL..L
LLLL.LL.LLLLL.L.LLLLLLLLLLLL.LLLL..LLLLLLL.LLLLLL.LLLL.LLLLLLLLL.LLLLLLLL.LLLLLLLLLLLLL.LLLLL
LLLLLLL.LLLLLLL.LLLLL.LLLLLL.LL.LLLLL.LLLLLLLLLLLLLLLL.LLLLLLL.L.LLLLLLLLLLLLLL.LLLLLLLL.LLLL
LLLLL.L.LLLLLLL.LLLLL.LLLLLLLLLLL.LLLLLLLL.LLLLL..LLLL.LLLLLLLLL.LLLLLLLL.LLLLLLLLLLLLL.LLLLL
LLLLLLL.LLLLLLLLLLLLLLLLLLLLL.L.LLLLLLLLLL.LLLLLL.LLLL.LLLLLLLLL.LLLLLLLLLLLLLL.LLLLLLL.LLLLL
L.LLLLLLLLLLLLL..LLLLLLLLLLL..LLL.LLLLLLLL.LLLLL...LLL.LLLLLLLLL.LLLLLLLLLLL.LL.LLLLLLLLLLLLL
.L......LL...L.L....L...L...........L.LL...L.LLLLL.....LL....L......L.LL..L..L.....L...L.L.LL
LLLLLLL.LLLLLLLLLLLLLLLLLLLL.LLLL.LLLL.LLL.LLLLLL.LLL..LLLLLLLLL.LLLLLLLLLLLLLL..LLLLLL.LLLLL
LLLLLLL.LLLLLLLLLLLLLLLLLLLLLLLLLLLLL.LLLL.LLLL.LLLLLLLLLL.LLLLL.LLLLLLLL.LLLLL.LLLLL.L.LLLLL
LLLLLLLLLLLLLLL.LLLLL.LLL.LL.LLLL.LLLLLLLLLLLLLLLLLLLL.LL.LLLLLL.LLLLLLLL.LLLLL.LLLLLLLLLLLLL
LLLLLLL.LLLLLLLLLLLLLLLLLLLL.LLLL.LLLLLLLL.L.LLLLL.LLL.LLLLLLLLL.LLLLLLLL.LLLLL.LLLLLLLLLLLLL
LL.L.LLLLL.LLLL.LLLLLLLLLLLL.LLLLLLLLLLLLLLLLLLLL.LLLLLLLLLLLLLL.LLLLLLLLLLLLLL.LLLLLLL.LLLLL
LLLL.LLLLLLLLLL.LLLLLLLLLLLLLLLLL.LLLLLLLLLLLLLLLLLLLL.LLLLLLLLL.L.LLLLLL.LLLLL.LLLLLLL.LLLLL
LLLLLLL.LLLLLLL.LLLLL.LLLLLL.LLLL.LLLLLLLL.LLLLLLLLLLL.LLLLL.LLLLL.LLLLLL.LL.LL.LLLLLLLLLLLLL
..L....L.L.LL.L.........L...LL.L....LL......LL..LL.L.L.....L..L..L..L..LL.L...L..L....L......
LLLLLLL.LLLLLLL.LLLLL.LLLLLL.LLL..LLLLLLLLLLLLLLLLLLLLL.LLL.LLLLLLLLLL.LL.LLLLL.LLLLLLL.LLLLL
LLLLLLL.L.LLLLLLLLLLLLLLLLLLLLLLL.LLLLLLL..LLLLLLLLLLLLLLLLLLLLL.LLLLLLLLLLLLLLLLLLLLLLLLLLLL
LLLLLLL.LLLLLLL.LLLLL.L.LLLL.L.LLLLLLLLLLL..LLLLLLLLLL.LL.LLLLLLLLLLLLLLL.LLLLL.LLLLLLL.LLLLL
LLLLLLL.LLLLLLL.LLLLL.LLLLLLLLLLLLLLLLLLLL.LLLLLL.LLLL.LLLLLL.LL.LLLLLLLL..L.LL.LLLLLLLLLLLLL
.L......L....L.L.L...LLLL......LL...LL...L...L......L..L...........L......L.......L....L.L...
LL.LLLLLLLLLLLLLLLLLLLLLLLLL.LLLL.LL.LLLLL.LLLLLLLLLLL.LLL.LLLLL.LLLLLLLL.LLLLL.LL.LLLL.LLLLL
L.LLLLL.LLLLLLL.LLLLL.LLLLLL.LL.LLLLLLLLLL.L.LLLLLLLLL.LLLLLLLLL.LLLLLLLL.LLLLLLL.LLLLLLLLLLL
LLLLLLL.LLLLLLL.LLLLL.LLLLLLLLLLL.LLLLL.LLLLLLLL.LLLLLLLLLLLLLLL.LLL.LLLL.LLLLLLLLLLLLL.LLLLL
LLLLLLLLLLLLLLLLL.LLLLLLLLLL.LLLL.LLLLLLLLLLLLLLL.L.LLLLLLLLLLLL.LLLLL.LLLLLLLL.LLLLLLL.LLLLL
.LLLLLL.LLLLLLL.LLLLLLLLLLLL.LLLL.LLLLLLLLLLL.LLLLLLLLLLLLLLLLL.LLLLLLLLL.LLLLL.L.LLLLL.LLLLL
LLLLLLL.LLLLLLLLLLLLLLLLLL.L.LLLL.LLLLLLLLLLL.LLL.LLLL.LLL.LLLLL.LLL.LLLLLLLLLL.LLLLLLL..LLLL
.L.....L...L....L.LL............LL..L.LL.....LLL..L.............L...........L...L.L.L........
LLLLLLLLLLLLL.L.LLLLLLLLLLLL.LLLLLLLLLLLLLLLLLLLL.LLLL.LLLLLLLLL.LLL.LLLL.LLLLLLLLLLLLL.LLLLL
LLLLLLL..LLLLLL.LLLLLLLLLLLLLLLLLLLLLLLLLL.LLLLLL.LLLL.LLLLLLLLL.LLLLLLLLLLLLLL.LLLLLLL.LLLLL
LL.LLLLLLLLLLLL.LLLLL.LLL.LL.LLL..LLLLLLLL.L.LLLL.LLLLLLLLLLLLLL.LLLLLL.L.LLLLLLLLLLLL.L.LLLL
LLL.LLL.LLLLLLLLLLLL..LLLLLL.LLLL.LLLLLLLLLLLL.LLLLLLLLLLLLLLLLL.LLLLLLLLLLLLLL.LLLLLLL.LLLLL
LLLLLLL.LLLLLLL.LLLLL.LLLLLL.LLLLLLLLLLLLL.LLLLLL.LLLLLLLLLLLLLLLLLLLLL.L.LLLLL.LLLLLLL.LLLLL
LLLLLLL.LLLLLLL.LLLLLLLLLLLL.LLLL.LL.L.LLLLLLLLLL.LLLL.LLLLLLLLL.LLLLLLLLLLLLLL.LLLLLLLLLLLLL
LLLLLLLLLLLLLLLLLLLLL.LLLLLL.LLLLLLLLLLLLL..LLLL..LLLLLLLLLLLLLL.LLLLLLLLLLLLLLLLLLLLLL.LLLLL
LLLLLLL.LLLLLLL.LLLLL.LLLLLLLLLLL.LLLLLLLL.LLLLLL.LLLLLLLLLLLLLL.LLLLLLLL.LLLLL.LLLLLLL.LL.LL
.LLLLLL.LL.LLLLLLLLLLLLLL.LLLLLLLLLLLLLLLL.LLLLLL.LLLLLLLLLLLLLL.LLLLLLLLLL.LLL.LLLLLLL.LLLLL
LL.L.L...L...L...LLL.......LLL..L.L...L.......L......L.LL.......L..LLL.L..L.L.LL..L..L.L.LLL.
LLLLLLL.LLLLLL..LLLLL.LLLLLL.LLLL.LLLLLLLL.LLLLLL.LLLL.LLLLLLLLLLLLLLLLLL.LLLLLLLLLLLLL.LLLLL
LLLLLLL.LLLLLLL.LLLLL.LLLLLL.LLLLLLLLLLLLL.LLLLLL.LLLL.LLLLLLLLLLLLLLLLLL.LLLLL.LLLLLLL.LLLLL
LLLLLLL.LLLLLLL.LLLLLLLLLLLL.LLLL.LLLLLLLL.LLLLLL.LLLL.LLLLLLLLL.LLLLLLLLLLLLLL.LLLLLLLL.LLLL
LLLLLLLLLLLLLLL.LL.LL.LLLLLL.LLLL.LLLLLLLL.LLLLLLLLLLL.LLLL.LLLL.LLLLLLLL.LLLLLLLLLLLLLLLLLLL
LLLLLLL.LL.LLLL..LLL.LLLLLLLL.L.L.LLLLLLLL.LLLLLL.L.LL.LLLLLL.LL.LLLLLLLL.LLLLL.LLLLLLL.LLLLL
LLLLLLL.LLLLLLLLLLLLL.LLLLLL.LLLL.LLLLLLLL.LLLLLLLLLLL.LLLLLLLLL.LLLLL.LL.LLLLLLLLL.LLL.LLLL.
L.LLLLLLLLLLLLLLLLLLL.LLLL.L.LLLL.L.LLLL.L.LLLLLL.LLLL.LLLLLL.L.LLLLLLLLLLLLLLLLLLLLLLL.LL.LL
.LLLLLL.LLLLLLLLLLLLL.LLLLLL.LLLL.LLLL.LLL.LLLLLLLLLLL.LLLLLL.LLLLLLLLLLLLLLLLL.LLLLL.L.LLLLL
LL....L....L..L.L.....L.L...L...L.....L.....L....LLL..L.L..L..L.LL.L...L.LLL.......L....L.LL.
LLLLLLLLLLLLLLLLLLLLLLLLLLLL.LLLLLLLLLLLLL.LLLLLLLLLLL.LLL.LLLLLLLLLLLLLL.LLLLL.LLLLLLL.LLLLL
LLLLLLL.LLL.LLLLLLL.LLLL.LLL.LLLLLLLLLLLLLLLLLLLLLLLLL.LLLLLLLLL.LLLLLLLL.L..LLLLLLLLLL.LLLLL
LLLLLLLLLLLLLLL.LLLLL.LLLLLLLLLLL.LLLLLLLL.LLLLLLLLLLL.LLLLLLLLL.L.LLL.LLLLLLLL.LLLLLLL.LLLLL
LLLLLLL.LLLLLLLLLLLLL.LLLLLL.LLLLL.LLLLLLL.LLLLLL.LLLL.LLLLLL.LLLLLLLLLLL.LLLLL.LLLLLLLLLLLLL
LLLL.LL.LLLLLLLLLLLLL.LLLLLL.LLLL.LLLLLLLL.LLLLLLLLLLL.LLLLLLL.L.LLLLLLLL.LLLLL.LLLLLLL.LLLLL
LLLLLLL.LLLLLL.LLLLLL.LLLLLLLLLL..LLLLLLLL.LLLLLL.LLLL.LLL.LLLLL.LLLLLLLLLLLLLL.LLL.LLL.LLLLL
LLLLLLLLLLLLLLL..LLLLLLLLLLLLLLLLLLLL..LLL.LLLLLL.LL.L.LLL.LLLLLLLLL..LLL.LLLLL.LLLLLLL.LLLLL
..L..L..L.L.......L..LL...L.L..LL...L............L.L...L.....L...LL..LL......L.L...L.....L..L
LLLLL.LLLLLLLLLLLLLLL.LLLLLL.LLLL.LL.LLLLLLLLLLLL.LLLLLLLLLLLLLL.LLLLLLLL.LLLLL.LLLLLLLLLLLLL
L.LLLLL.LLLLLLL.LLLLLLL.LLLL.LLLL.LLLLLLLLLLLLLLL.LLLLLLLLLLLLLL.LLLLLLLL.L.LLL.LL.LLL.LLLLLL
LLLLLLL.LLLLLLLLL.LLLLLLLLLLL.L.L.LLLLLLLL.LLLLLL.LLLL.LLLLLLLLLLLLLLLLLL.L.LLL.LLL.LL..LLLLL
LLLLLLL.LLLLLLL.LLLLLLLLLLLL.LLLLLLLLLLLLL.LLLLLL.LLLL.LLLL.LLLL.LLLLLLLL.LLLLL.LLL..LL.LLLLL
LLLLLLL.LLLLLLL.LLLLLLLLLLLL.LLLL.LLLLLLLL.LLLL.LLLLLL.LLLLLLLLLLLLLLLLLLLLLLLL.LLLLLLLLLL.LL
LLLLLL.LLLLLLLL.LLL...LLLLLL.LLLL.LLLLLLLL.LLLLLL.LLLLLLLLLL.L.L.LLLLLLLL.LLLLL.LLLLLLL.L.LL.
LL.LL.L.LLLLLLLLLLLLL.L.LLLLLLLLLLLLLLLLLL.LLLLLL..LLL.LLLLLLLLLLLLLLLLL..LLLLL.LLLLLLL.LLLLL
LLLLLLLLLLLLLLL.LLL.LL.LLLLL.LLLL.LLLLLLLL.LLLLLLLLLLL.LLLLLLLLL.LLLLLLLLL.LL.L.LLLLLLLLLLLLL
LLLLLLL.LLLL.LL.LLLLL.LLLLLL.LLLL.L.LLLLLLLLLLLLLLLLLLLLLLLLLLL..LLLLLLLLL.LLLLLLLLLLLL.LLLLL
L.LLLLL.LLLLLLL.LLLLL.LLLLLLLLLLL.LLLLLLLL.LLLLLL.LLLL.LLLLLLLLLLLLLLLL.L.LLLLLLLLLLLLL..LLLL
LLLLLLL.LLLLLLLL.LLLLLLLLLLL.LLLLLLLLL.LLL.LLLLLLLLLL..LL.LLLLLL.LLLLLLLL.LLLLL.LLLLLLLLLLLLL
\ No newline at end of file
L.LL.LL.LL
LLLLLLL.LL
L.L.L..L..
LLLL.LL.LL
L.LL.LL.LL
L.LLLLL.LL
..L.L.....
LLLLLLLLLL
L.LLLLLL.L
L.LLLLL.LL
\ No newline at end of file
<!DOCTYPE html>
<html lang="en-us">
<head>
<meta charset="utf-8"/>
<title>Day 11 - Advent of Code 2020</title>
<!--[if lt IE 9]><script src="/static/html5.js"></script><![endif]-->
<link href='//fonts.googleapis.com/css?family=Source+Code+Pro:300&subset=latin,latin-ext' rel='stylesheet' type='text/css'/>
<link rel="stylesheet" type="text/css" href="/static/style.css?25"/>
<link rel="stylesheet alternate" type="text/css" href="/static/highcontrast.css?0" title="High Contrast"/>
<link rel="shortcut icon" href="/favicon.png"/>
</head><!--
Oh, hello! Funny seeing you here.
I appreciate your enthusiasm, but you aren't going to find much down here.
There certainly aren't clues to any of the puzzles. The best surprises don't
even appear in the source until you unlock them for real.
Please be careful with automated requests; I'm not a massive company, and I can
only take so much traffic. Please be considerate so that everyone gets to play.
If you're curious about how Advent of Code works, it's running on some custom
Perl code. Other than a few integrations (auth, analytics, social media), I
built the whole thing myself, including the design, animations, prose, and all
of the puzzles.
The puzzles are most of the work; preparing a new calendar and a new set of
puzzles each year takes all of my free time for 4-5 months. A lot of effort
went into building this thing - I hope you're enjoying playing it as much as I
enjoyed making it for you!
If you'd like to hang out, I'm @ericwastl on Twitter.
- Eric Wastl
-->
<body>
<header><div><h1 class="title-global"><a href="/">Advent of Code</a></h1><nav><ul><li><a href="/2020/about">[About]</a></li><li><a href="/2020/events">[Events]</a></li><li><a href="https://teespring.com/stores/advent-of-code" target="_blank">[Shop]</a></li><li><a href="/2020/settings">[Settings]</a></li><li><a href="/2020/auth/logout">[Log Out]</a></li></ul></nav><div class="user">Neil Smith <a href="/2020/support" class="supporter-badge" title="Advent of Code Supporter">(AoC++)</a> <span class="star-count">22*</span></div></div><div><h1 class="title-event">&nbsp;&nbsp;&nbsp;<span class="title-event-wrap">int y=</span><a href="/2020">2020</a><span class="title-event-wrap">;</span></h1><nav><ul><li><a href="/2020">[Calendar]</a></li><li><a href="/2020/support">[AoC++]</a></li><li><a href="/2020/sponsors">[Sponsors]</a></li><li><a href="/2020/leaderboard">[Leaderboard]</a></li><li><a href="/2020/stats">[Stats]</a></li></ul></nav></div></header>
<div id="sidebar">
<div id="sponsor"><div class="quiet">Our <a href="/2020/sponsors">sponsors</a> help make Advent of Code possible:</div><div class="sponsor"><a href="https://www.twilio.com/quest?utm_source=advent-of-code-20&amp;utm_medium=website" target="_blank" onclick="if(ga)ga('send','event','sponsor','sidebar',this.href);" rel="noopener">TwilioQuest</a> - Learn to code and lead your intrepid crew on a mission to save The Cloud in TwilioQuest, a PC role-playing game inspired by classics of the 16-bit era. Free forever, and available now for Windows, Mac, and Linux.</div></div>
</div><!--/sidebar-->
<main>
<script>window.addEventListener('click', function(e,s,r){if(e.target.nodeName==='CODE'&&e.detail===3){s=window.getSelection();s.removeAllRanges();r=document.createRange();r.selectNodeContents(e.target);s.addRange(r);}});</script>
<article class="day-desc"><h2>--- Day 11: Seating System ---</h2><p>Your plane lands with plenty of time to spare. The final leg of your journey is a ferry that goes directly to the tropical island where you can finally start your vacation. As you reach the waiting area to board the ferry, you realize you're so early, nobody else has even arrived yet!</p>
<p>By modeling the process people use to choose (or abandon) their seat in the waiting area, you're pretty sure you can predict the best place to sit. You make a quick map of the seat layout (your puzzle input).</p>
<p>The seat layout fits neatly on a grid. Each position is either floor (<code>.</code>), an empty seat (<code>L</code>), or an occupied seat (<code>#</code>). For example, the initial seat layout might look like this:</p>
<pre><code>L.LL.LL.LL
LLLLLLL.LL
L.L.L..L..
LLLL.LL.LL
L.LL.LL.LL
L.LLLLL.LL
..L.L.....
LLLLLLLLLL
L.LLLLLL.L
L.LLLLL.LL
</code></pre>
<p>Now, you just need to model the people who will be arriving shortly. Fortunately, people are entirely predictable and always follow a simple set of rules. All decisions are based on the <em>number of occupied seats</em> adjacent to a given seat (one of the eight positions immediately up, down, left, right, or diagonal from the seat). The following rules are applied to every seat simultaneously:</p>
<ul>
<li>If a seat is <em>empty</em> (<code>L</code>) and there are <em>no</em> occupied seats adjacent to it, the seat becomes <em>occupied</em>.</li>
<li>If a seat is <em>occupied</em> (<code>#</code>) and <em>four or more</em> seats adjacent to it are also occupied, the seat becomes <em>empty</em>.</li>
<li>Otherwise, the seat's state does not change.</li>
</ul>
<p><span title="Floor... floor never changes.">Floor (<code>.</code>) never changes</span>; seats don't move, and nobody sits on the floor.</p>
<p>After one round of these rules, every seat in the example layout becomes occupied:</p>
<pre><code>#.##.##.##
#######.##
#.#.#..#..
####.##.##
#.##.##.##
#.#####.##
..#.#.....
##########
#.######.#
#.#####.##
</code></pre>
<p>After a second round, the seats with four or more occupied adjacent seats become empty again:</p>
<pre><code>#.LL.L#.##
#LLLLLL.L#
L.L.L..L..
#LLL.LL.L#
#.LL.LL.LL
#.LLLL#.##
..L.L.....
#LLLLLLLL#
#.LLLLLL.L
#.#LLLL.##
</code></pre>
<p>This process continues for three more rounds:</p>
<pre><code>#.##.L#.##
#L###LL.L#
L.#.#..#..
#L##.##.L#
#.##.LL.LL
#.###L#.##
..#.#.....
#L######L#
#.LL###L.L
#.#L###.##
</code></pre>
<pre><code>#.#L.L#.##
#LLL#LL.L#
L.L.L..#..
#LLL.##.L#
#.LL.LL.LL
#.LL#L#.##
..L.L.....
#L#LLLL#L#
#.LLLLLL.L
#.#L#L#.##
</code></pre>
<pre><code>#.#L.L#.##
#LLL#LL.L#
L.#.L..#..
#L##.##.L#
#.#L.LL.LL
#.#L#L#.##
..L.L.....
#L#L##L#L#
#.LLLLLL.L
#.#L#L#.##
</code></pre>
<p>At this point, something interesting happens: the chaos stabilizes and further applications of these rules cause no seats to change state! Once people stop moving around, you count <em><code>37</code></em> occupied seats.</p>
<p>Simulate your seating area by applying the seating rules repeatedly until no seats change state. <em>How many seats end up occupied?</em></p>
</article>
<p>Your puzzle answer was <code>2270</code>.</p><article class="day-desc"><h2 id="part2">--- Part Two ---</h2><p>As soon as people start to arrive, you realize your mistake. People don't just care about adjacent seats - they care about <em>the first seat they can see</em> in each of those eight directions!</p>
<p>Now, instead of considering just the eight immediately adjacent seats, consider the <em>first seat</em> in each of those eight directions. For example, the empty seat below would see <em>eight</em> occupied seats:</p>
<pre><code>.......#.
...#.....
.#.......
.........
..#L....#
....#....
.........
#........
...#.....
</code></pre>