48 lines
1.4 KiB
Haskell
48 lines
1.4 KiB
Haskell
|
import Data.List
|
||
|
|
||
|
main :: IO ()
|
||
|
main = do
|
||
|
input <- readFile "6/input.txt"
|
||
|
let x = parse input
|
||
|
-- Problem 1
|
||
|
print $ f x
|
||
|
-- Problem 2
|
||
|
print $ g x
|
||
|
where
|
||
|
f = solve 80
|
||
|
g = solve 256
|
||
|
|
||
|
parse :: String -> [Int]
|
||
|
parse = map read . words . map f
|
||
|
where f ',' = ' '
|
||
|
f x = x
|
||
|
|
||
|
-- Solve the problem by creating an association list mapping a
|
||
|
-- value for the internal timer to a number of fishies as the seed,
|
||
|
-- and then simulating `n` iterations of growth.
|
||
|
solve :: Int -- ^ n: The number of generations to simulate
|
||
|
-> [Int] -- ^ The initial population
|
||
|
-> Int -- ^ The total population at the end of n generations
|
||
|
solve n = sum . map snd . simulate n . map assoc . group . sort
|
||
|
where assoc x = (head x, length x)
|
||
|
|
||
|
-- Simulate `n` iterations of growth and return the state
|
||
|
-- after that many iterations.
|
||
|
simulate :: Int -> [(Int, Int)] -> [(Int, Int)]
|
||
|
simulate 0 st = st
|
||
|
simulate n st = simulate (n - 1) (update st)
|
||
|
|
||
|
-- Update the simulation state by one iteration.
|
||
|
update :: [(Int, Int)] -> [(Int, Int)]
|
||
|
update = merge . (>>= f)
|
||
|
where f (0, n) = [(6, n), (8, n)]
|
||
|
f (t, n) = [(t - 1, n)]
|
||
|
|
||
|
-- Merge the values of duplicate key entries and produce a new list
|
||
|
-- where each key is mapped to the sum of all values associated with
|
||
|
-- that key.
|
||
|
merge :: [(Int, Int)] -> [(Int, Int)]
|
||
|
merge [] = []
|
||
|
merge ((t,n) : ls) = (t, n + sum (map snd x)) : merge r
|
||
|
where (x,r) = partition ((== t) . fst) ls
|