summaryrefslogtreecommitdiff
path: root/2019
diff options
context:
space:
mode:
authortomsmeding <tom.smeding@gmail.com>2019-12-25 10:12:23 +0100
committertomsmeding <tom.smeding@gmail.com>2019-12-25 10:12:23 +0100
commit83ed445f43e23f35b46d76ea53c4ab74e1115e9e (patch)
treece842accf30ce3172401514223ffe1ff4d50979c /2019
parent3521485ffb5beecb6dab78705765e01658b3f0c1 (diff)
Day 24
Diffstat (limited to '2019')
-rw-r--r--2019/24.hs105
-rw-r--r--2019/24.in5
2 files changed, 110 insertions, 0 deletions
diff --git a/2019/24.hs b/2019/24.hs
new file mode 100644
index 0000000..52fbc05
--- /dev/null
+++ b/2019/24.hs
@@ -0,0 +1,105 @@
+{-# LANGUAGE TupleSections #-}
+module Main where
+
+import Control.Monad
+import Data.List
+import qualified Data.Set as Set
+
+import Input
+
+
+data World = World [[Bool]]
+ deriving (Show, Eq, Ord)
+
+showWorld :: World -> String
+showWorld (World bds) = unlines (map showRow [0..4])
+ where
+ showRow y = intercalate " " (map (showBdRow y) bds)
+ showBdRow y bd = [".#" !! fromEnum (bd !! (5 * y + x)) | x <- [0..4]]
+
+evolve1 :: World -> World
+evolve1 (World [bd]) =
+ World [[let s = sum [fromEnum (bd !! n) | n <- neighbours idx]
+ in s == 1 || (not cell && s == 2)
+ | (idx, cell) <- zip [0..] bd]]
+ where
+ neighbours idx =
+ let (y, x) = idx `divMod` 5
+ in concat [guard (x > 0) >> [idx-1]
+ ,guard (y > 0) >> [idx-5]
+ ,guard (x < 4) >> [idx+1]
+ ,guard (y < 4) >> [idx+5]]
+evolve1 _ = undefined
+
+findWorldReappear1 :: World -> World
+findWorldReappear1 initWorld = go initWorld Set.empty
+ where
+ go w seen | w `Set.member` seen = w
+ | otherwise = go (evolve1 w) (Set.insert w seen)
+
+biodiversity1 :: World -> Int
+biodiversity1 (World [bd]) = sum [fromEnum c * 2 ^ i | (c, i) <- zip bd [0::Int ..]]
+biodiversity1 _ = undefined
+
+numBugs2 :: World -> Int
+numBugs2 (World bds) = sum (map fromEnum (concat bds))
+
+evolve2 :: World -> World
+evolve2 (World bds) = World newbds
+ where
+ srcbds = (if all not (head bds) then [] else [emptybd]) ++
+ bds ++
+ (if all not (last bds) then [] else [emptybd])
+ lowestLvlSrc = if all not (head bds) then 0 else -1
+ newbds = [[let s = sum [fromEnum (deref n) | n <- neighbours (lvl, idx)]
+ in s == 1 || (not cell && s == 2)
+ | (idx, cell) <- zip [0..] bd]
+ | (lvl, bd) <- zip [lowestLvlSrc..] srcbds]
+
+ emptybd = replicate 25 False
+
+ numlevels = length bds
+
+ deref (lvl, idx) | lvl < 0 = False
+ | lvl >= numlevels = False
+ | otherwise = bds !! lvl !! idx
+
+ neighbours (lvl, idx) = table !! idx
+ where
+ table = [[(lvl-1, 11), (lvl-1, 7), (lvl, 1), (lvl, 5)]
+ ,[(lvl, 0), (lvl-1, 7), (lvl, 2), (lvl, 6)]
+ ,[(lvl, 1), (lvl-1, 7), (lvl, 3), (lvl, 7)]
+ ,[(lvl, 2), (lvl-1, 7), (lvl, 4), (lvl, 8)]
+ ,[(lvl, 3), (lvl-1, 7), (lvl-1, 13), (lvl, 9)]
+
+ ,[(lvl-1, 11), (lvl, 0), (lvl, 6), (lvl, 10)]
+ ,[(lvl, 5), (lvl, 1), (lvl, 7), (lvl, 11)]
+ ,[(lvl, 6), (lvl, 2), (lvl, 8)] ++ map (lvl+1,) [0..4]
+ ,map (lvl,) [3,7,9,13]
+ ,(lvl-1, 13) : map (lvl,) [8,4,14]
+
+ ,(lvl-1,11) : map (lvl,) [5,11,15]
+ ,map (lvl,) [10,6,16] ++ map (lvl+1,) [0,5..20]
+ ,[]
+ ,map (lvl,) [8,14,18] ++ map (lvl+1,) [4,9..24]
+ ,(lvl-1, 13) : map (lvl,) [9,13,19]
+
+ ,(lvl-1, 11) : map (lvl,) [10,16,20]
+ ,map (lvl,) [15,11,17,21]
+ ,map (lvl,) [16,18,22] ++ map (lvl+1,) [20..24]
+ ,map (lvl,) [17,13,19,23]
+ ,(lvl-1, 13) : map (lvl,) [18,14,24]
+
+ ,[(lvl, 15), (lvl, 21), (lvl-1, 11), (lvl-1, 17)]
+ ,(lvl-1, 17) : map (lvl,) [20, 16, 22]
+ ,(lvl-1, 17) : map (lvl,) [21, 17, 23]
+ ,(lvl-1, 17) : map (lvl,) [22, 18, 24]
+ ,[(lvl, 23), (lvl, 19), (lvl-1, 17), (lvl-1, 13)]]
+
+main :: IO ()
+main = do
+ stringbd <- getInput 24
+ let initWorld = World [[stringbd !! (idx `div` 5) !! (idx `mod` 5) == '#' | idx <- [0..24]]]
+ print (biodiversity1 (findWorldReappear1 initWorld))
+
+ print (numBugs2 (iterate evolve2 initWorld !! 200))
diff --git a/2019/24.in b/2019/24.in
new file mode 100644
index 0000000..ea81228
--- /dev/null
+++ b/2019/24.in
@@ -0,0 +1,5 @@
+..##.
+#....
+.....
+#.#.#
+#..#.