diff options
author | tomsmeding <tom.smeding@gmail.com> | 2019-12-25 10:12:23 +0100 |
---|---|---|
committer | tomsmeding <tom.smeding@gmail.com> | 2019-12-25 10:12:23 +0100 |
commit | 83ed445f43e23f35b46d76ea53c4ab74e1115e9e (patch) | |
tree | ce842accf30ce3172401514223ffe1ff4d50979c /2019 | |
parent | 3521485ffb5beecb6dab78705765e01658b3f0c1 (diff) |
Day 24
Diffstat (limited to '2019')
-rw-r--r-- | 2019/24.hs | 105 | ||||
-rw-r--r-- | 2019/24.in | 5 |
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 @@ +..##. +#.... +..... +#.#.# +#..#. |