From: Neil Smith Date: Sat, 26 Dec 2020 11:03:37 +0000 (+0000) Subject: Done part 1 X-Git-Url: https://git.njae.me.uk/?a=commitdiff_plain;h=51389d5cd4cba7f24464e200b363b16c81a78e9f;p=advent-of-code-20.git Done part 1 --- diff --git a/advent17/package.yaml b/advent17/package.yaml new file mode 100644 index 0000000..4d7792b --- /dev/null +++ b/advent17/package.yaml @@ -0,0 +1,62 @@ +# 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: . + +name: advent17 +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: + advent17: + main: advent17.hs + source-dirs: src + dependencies: + - base >= 2 && < 6 + - containers + - linear + - vector diff --git a/advent17/src/advent17.hs b/advent17/src/advent17.hs new file mode 100644 index 0000000..535f971 --- /dev/null +++ b/advent17/src/advent17.hs @@ -0,0 +1,51 @@ +-- import Debug.Trace + +import qualified Data.Set as S +import Linear (V3(..), V4(..), (^+^), (^-^)) +import qualified Data.Vector as V + +type Coord = V3 Int -- x, y, z +type Grid = S.Set Coord + +main :: IO () +main = + do grid0 <- readGrid "data/advent17.txt" + print grid0 + let finalGrid = head $ drop 6 $ iterate update grid0 + print $ S.size finalGrid + + +readGrid :: String -> IO Grid +readGrid filename = + do gs <- readFile filename + let grid = lines gs + let isActive x y = (grid!!y)!!x == '#' + let maxX = length (head grid) - 1 + let maxY = length grid - 1 + return $ S.fromList [ V3 x y 0 | x <- [0..maxX], y <- [0..maxY], isActive x y] + +neighbourSpaces :: Coord -> Grid +neighbourSpaces here = S.map (here ^+^) nbrs + where nbrs = S.fromList [ V3 dx dy dz + | dx <- [-1, 0, 1] + , dy <- [-1, 0, 1] + , dz <- [-1, 0, 1] + , (dx, dy, dz) /= (0, 0, 0)] + +countOccupiedNeighbours :: Coord -> Grid -> Int +countOccupiedNeighbours cell grid = S.size $ S.intersection grid $ neighbourSpaces cell + +cubeSurvives :: Grid -> Coord -> Bool +cubeSurvives grid cell = alive && (nNbrs == 2 || nNbrs == 3) + where alive = cell `S.member` grid + nNbrs = countOccupiedNeighbours cell grid + +cubeBorn :: Grid -> Coord -> Bool +cubeBorn grid cell = dead && (nNbrs == 3) + where dead = cell `S.notMember` grid + nNbrs = countOccupiedNeighbours cell grid + +update :: Grid -> Grid +update grid = S.union (S.filter (cubeSurvives grid) grid) (S.filter (cubeBorn grid) empties) + where empties = (S.foldr mergeEmpties S.empty grid) `S.difference` grid + mergeEmpties cell acc = S.union acc $ neighbourSpaces cell diff --git a/data/advent17.txt b/data/advent17.txt new file mode 100644 index 0000000..9ebe8fa --- /dev/null +++ b/data/advent17.txt @@ -0,0 +1,8 @@ +.###.#.# +####.#.# +#.....#. +####.... +#...##.# +######## +..#####. +######.# diff --git a/data/advent17a.txt b/data/advent17a.txt new file mode 100644 index 0000000..eedd3d2 --- /dev/null +++ b/data/advent17a.txt @@ -0,0 +1,3 @@ +.#. +..# +### diff --git a/stack.yaml b/stack.yaml index 9e7091d..d9fee51 100644 --- a/stack.yaml +++ b/stack.yaml @@ -51,6 +51,7 @@ packages: - advent14 - advent15 - advent16 +- advent17 # Dependency packages to be pulled from upstream that are not in the resolver. # These entries can reference officially published versions as well as