day11: Complete puzzles
This commit is contained in:
parent
d6739d00f6
commit
6723ef2021
10
11/input.txt
Normal file
10
11/input.txt
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
5421451741
|
||||||
|
3877321568
|
||||||
|
7583273864
|
||||||
|
3451717778
|
||||||
|
2651615156
|
||||||
|
6377167526
|
||||||
|
5182852831
|
||||||
|
4766856676
|
||||||
|
3437187583
|
||||||
|
3633371586
|
93
11/octoflash.hs
Normal file
93
11/octoflash.hs
Normal file
|
@ -0,0 +1,93 @@
|
||||||
|
import Data.Char (digitToInt)
|
||||||
|
|
||||||
|
main :: IO ()
|
||||||
|
main = do
|
||||||
|
input <- getContents
|
||||||
|
let
|
||||||
|
octopodes = (map (map digitToInt) . lines) input
|
||||||
|
(putStrLn . show . solution1) octopodes
|
||||||
|
(putStrLn . show . solution2) octopodes
|
||||||
|
|
||||||
|
solution1 :: [[Int]] -> Int
|
||||||
|
solution1 m = snd (iterate flashSimulate (m, 0) !! 100)
|
||||||
|
|
||||||
|
solution2 :: [[Int]] -> Int
|
||||||
|
solution2 m = countUntil (all (all (==0)) . fst) flashSimulate (m, 0)
|
||||||
|
|
||||||
|
flashSimulate :: ([[Int]], Int) -> ([[Int]], Int)
|
||||||
|
flashSimulate (octopodes, flashes) =
|
||||||
|
(refreshOctopodes exhaustedOctopodes, flashes + countExhaustedOctopodes exhaustedOctopodes)
|
||||||
|
where
|
||||||
|
exhaustedOctopodes = flashStep octopodes
|
||||||
|
countExhaustedOctopodes = foldr (\l a -> length l + a) 0 . map (filter (> 9))
|
||||||
|
refreshOctopodes = map (map (\o -> if o > 9 then 0 else o))
|
||||||
|
|
||||||
|
flashStep :: [[Int]] -> [[Int]]
|
||||||
|
flashStep = propagateFlashes . map (map (+1))
|
||||||
|
where
|
||||||
|
propagateFlashes :: [[Int]] -> [[Int]]
|
||||||
|
propagateFlashes = until allExhausted flashOctopi
|
||||||
|
where
|
||||||
|
allExhausted :: [[Int]] -> Bool
|
||||||
|
allExhausted = all (all (/= 10))
|
||||||
|
flashOctopi :: [[Int]] -> [[Int]]
|
||||||
|
flashOctopi m = map (map (incrementFlashing m))
|
||||||
|
[[(x, y) | y <- [0..length (m !! x) - 1]] | x <- [0..length m - 1]]
|
||||||
|
where
|
||||||
|
incrementFlashing ::[[Int]] -> (Int, Int) -> Int
|
||||||
|
incrementFlashing m' o
|
||||||
|
| charge < 10 && newCharge > 10 = 10 -- Ensure we don't miss an increment
|
||||||
|
| otherwise = charge + numFlashingNeighbors o
|
||||||
|
where
|
||||||
|
newCharge = charge + numFlashingNeighbors o
|
||||||
|
charge = m' !!! o
|
||||||
|
numFlashingNeighbors :: (Int, Int) -> Int
|
||||||
|
numFlashingNeighbors = length . filter (\o -> (m !!! o) == 10) . (flip adjacent m)
|
||||||
|
|
||||||
|
(!!!) :: [[Int]] -> (Int, Int) -> Int
|
||||||
|
(!!!) m index = m !! (fst index) !! (snd index)
|
||||||
|
|
||||||
|
countUntil :: (a -> Bool) -> (a -> a) -> a -> Int
|
||||||
|
countUntil p f = call
|
||||||
|
where
|
||||||
|
call x
|
||||||
|
| p x = 0
|
||||||
|
| otherwise = call (f x) + 1
|
||||||
|
|
||||||
|
adjacent :: (Int, Int) -> [[Int]] -> [(Int, Int)]
|
||||||
|
adjacent (x, y) m = [(x+i, y+j) |
|
||||||
|
i <- [-1..1],
|
||||||
|
j <- [-1..1],
|
||||||
|
-- (i, j) /= (0, 0),
|
||||||
|
x+i >= 0,
|
||||||
|
y+j >= 0,
|
||||||
|
x+i < length m,
|
||||||
|
y+j < length (m !! 0)]
|
||||||
|
|
||||||
|
-- Tests
|
||||||
|
|
||||||
|
testInput1 = [
|
||||||
|
"5483143223",
|
||||||
|
"2745854711",
|
||||||
|
"5264556173",
|
||||||
|
"6141336146",
|
||||||
|
"6357385478",
|
||||||
|
"4167524645",
|
||||||
|
"2176841721",
|
||||||
|
"6882881134",
|
||||||
|
"4846848554",
|
||||||
|
"5283751526"
|
||||||
|
]
|
||||||
|
parsedTestInput1 = map (map digitToInt) testInput1
|
||||||
|
|
||||||
|
testInput2 = [
|
||||||
|
"11111",
|
||||||
|
"19991",
|
||||||
|
"19191",
|
||||||
|
"19991",
|
||||||
|
"11111"
|
||||||
|
]
|
||||||
|
parsedTestInput2 = map (map digitToInt) testInput2
|
||||||
|
|
||||||
|
test1 = solution1 parsedTestInput1
|
||||||
|
test2 = solution2 parsedTestInput1
|
Loading…
Reference in a new issue