mirror of
https://github.com/mx42/adventofcode.git
synced 2026-01-14 13:59:51 +01:00
Add 2020 day 17
This commit is contained in:
8
haskellAoC/inputs/2020/17
Normal file
8
haskellAoC/inputs/2020/17
Normal file
@@ -0,0 +1,8 @@
|
||||
...#...#
|
||||
#######.
|
||||
....###.
|
||||
.#..#...
|
||||
#.#.....
|
||||
.##.....
|
||||
#.####..
|
||||
#....##.
|
||||
86
haskellAoC/src/Y2020/Day17.hs
Normal file
86
haskellAoC/src/Y2020/Day17.hs
Normal file
@@ -0,0 +1,86 @@
|
||||
module Y2020.Day17 (y20day17) where
|
||||
|
||||
import qualified Data.HashMap.Strict as M
|
||||
|
||||
type Bounds = (Int, Int)
|
||||
type Coords = (Int, Int, Int, Int)
|
||||
type Board = M.HashMap Coords Bool
|
||||
|
||||
data State = State {
|
||||
_cycle :: Int -- cycle number, for reference
|
||||
, _map :: Board -- map of coords -> activity
|
||||
, _xs :: Bounds -- min and max rows with active stuff
|
||||
, _ys :: Bounds -- min and max cols with active stuff
|
||||
, _zs :: Bounds -- min and max layers with active stuff
|
||||
, _ws :: Bounds -- min and max ??? with active stuff
|
||||
} deriving (Show)
|
||||
|
||||
parseInput :: (Int, String) -> [(Coords, Bool)]
|
||||
parseInput (y, str) = map (\(x, b) -> ((x, y, 0, 0), b)) $ map parseChars $ zip (iterate (+1) 0) str
|
||||
where parseChars (x, '#') = (x, True)
|
||||
parseChars (x, _) = (x, False)
|
||||
|
||||
getBounds :: Board -> (Bounds, Bounds, Bounds, Bounds)
|
||||
getBounds board = foldl accumFn ((0, 0), (0, 0), (0, 0), (0, 0)) (M.keys board)
|
||||
where accumFn ((minx, maxx), (miny, maxy), (minz, maxz), (minw, maxw)) (x, y, z, w) =
|
||||
(
|
||||
(min minx x, max maxx x),
|
||||
(min miny y, max maxy y),
|
||||
(min minz z, max maxz z),
|
||||
(min minw w, max maxw w)
|
||||
)
|
||||
|
||||
|
||||
countActiveNeighbors :: Board -> Coords -> Int
|
||||
countActiveNeighbors b c = length $
|
||||
filter (== True) $
|
||||
map (\k -> M.lookupDefault False k b) $
|
||||
getNeighbors c
|
||||
where getNeighbors (x, y, z, w) = filter (\n -> n /= c) $
|
||||
[(x', y', z', w') |
|
||||
x' <- [x - 1, x, x + 1],
|
||||
y' <- [y - 1, y, y + 1],
|
||||
z' <- [z - 1, z, z + 1],
|
||||
w' <- [w - 1, w, w + 1]]
|
||||
|
||||
newCycle :: Bool -> State -> State
|
||||
newCycle wActive (State c b xb yb zb wb) = State c' b' xb' yb' zb' wb'
|
||||
where c' = c + 1
|
||||
(xb', yb', zb', wb') = getBounds b'
|
||||
b' = M.fromList $
|
||||
filter (\(_, s) -> s == True) $
|
||||
map (\coords -> (coords, activeness coords)) $
|
||||
getCoordsList wActive
|
||||
getCoordsList False = [(x, y, z, 0) |
|
||||
x <- [(fst xb - 1)..(snd xb + 1)],
|
||||
y <- [(fst yb - 1)..(snd yb + 1)],
|
||||
z <- [(fst zb - 1)..(snd zb + 1)]]
|
||||
getCoordsList True = [(x, y, z, w) |
|
||||
x <- [(fst xb - 1)..(snd xb + 1)],
|
||||
y <- [(fst yb - 1)..(snd yb + 1)],
|
||||
z <- [(fst zb - 1)..(snd zb + 1)],
|
||||
w <- [(fst wb - 1)..(snd wb + 1)]]
|
||||
oldState coords = M.lookupDefault False coords b
|
||||
neighbors coords = countActiveNeighbors b coords
|
||||
activeness coords = case (oldState coords, neighbors coords) of
|
||||
(True, 2) -> True
|
||||
(True, 3) -> True
|
||||
(False, 3) -> True
|
||||
_ -> False
|
||||
|
||||
countActive :: State -> Int
|
||||
countActive (State _ b _ _ _ _) = M.size b
|
||||
|
||||
runNcycles :: Bool -> Int -> State -> State
|
||||
runNcycles _ 0 s = s
|
||||
runNcycles p c s = runNcycles p (c - 1) s'
|
||||
where s' = newCycle p s
|
||||
|
||||
y20day17 :: [String] -> (String, String)
|
||||
y20day17 input = (part1, part2)
|
||||
where part1 = show $ countActive $ runNcycles False 6 initialState
|
||||
part2 = show $ countActive $ runNcycles True 6 initialState
|
||||
|
||||
initialState = State 0 initialMap xbounds ybounds zbounds wbounds
|
||||
where (xbounds, ybounds, zbounds, wbounds) = getBounds initialMap
|
||||
initialMap = M.fromList $ concatMap parseInput $ zip (iterate (+1) 0) input
|
||||
@@ -16,6 +16,7 @@ import Y2020.Day13
|
||||
import Y2020.Day14
|
||||
import Y2020.Day15
|
||||
import Y2020.Day16
|
||||
import Y2020.Day17
|
||||
|
||||
year2020 :: String -> [String] -> (String, String)
|
||||
year2020 "01" = y20day01
|
||||
@@ -34,3 +35,4 @@ year2020 "13" = y20day13
|
||||
year2020 "14" = y20day14
|
||||
year2020 "15" = y20day15
|
||||
year2020 "16" = y20day16
|
||||
year2020 "17" = y20day17
|
||||
|
||||
Reference in New Issue
Block a user