Commit 51389d5c authored by Neil Smith's avatar Neil Smith
Browse files

Done part 1

parent b6aca76d
# 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: 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
-- 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
.###.#.#
####.#.#
#.....#.
####....
#...##.#
########
..#####.
######.#
......@@ -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
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment