Tidying
[advent-of-code-18.git] / src / advent14 / advent14.hs
1 import qualified Data.Sequence as Q
2 import Data.Sequence ((|>))
3 import Data.Foldable (toList)
4
5 type Recipes = Q.Seq Int
6 data State = State Int Int Recipes deriving (Eq, Show)
7
8 targetLength = 327901
9 -- targetLength = 59414
10
11 main :: IO ()
12 main = do
13 let state = State 0 1 (Q.fromList [3, 7])
14 putStrLn $ part1 state
15 print $ part2 state
16
17 part1 :: State -> String
18 part1 state0 = concatMap show $ toList $ Q.take 10 $ Q.drop targetLength recipes
19 where (State _ _ recipes) = last $ takeWhile unfinished1 $ states state0
20
21 unfinished1 :: State -> Bool
22 unfinished1 (State _ _ recipes) = (Q.length recipes) <= (targetLength + 10)
23
24 part2 :: State -> Int
25 part2 state0 = if (takeR (Q.length targetSeq) recipes) == targetSeq
26 then (Q.length recipes) - (Q.length targetSeq)
27 else (Q.length recipes) - (Q.length targetSeq) - 1
28 where (State _ _ recipes) = head $ dropWhile (unfinished2 targetSeq) $ states state0
29
30 unfinished2 :: Recipes -> State -> Bool
31 unfinished2 target (State _ _ recipes) =
32 ((takeR (Q.length target) recipes) /= target)
33 &&
34 ((Q.take (Q.length target) (takeR (1 + Q.length target) recipes)) /= target)
35
36 states :: State -> [State]
37 states = iterate extend
38
39 extend :: State -> State
40 extend (State e1 e2 recipes) = State e1' e2' recipes'
41 where v1 = Q.index recipes e1
42 v2 = Q.index recipes e2
43 total = v1 + v2
44 recipes' = if total >= 10
45 then recipes |> (total `div` 10) |> (total `mod` 10)
46 else recipes |> total
47 e1' = (e1 + v1 + 1) `mod` (Q.length recipes')
48 e2' = (e2 + v2 + 1) `mod` (Q.length recipes')
49
50 targetSeq :: Recipes
51 targetSeq = Q.fromList $ map read $ map (take 1 . drop 1) $ map show $ show targetLength
52
53 takeR n s = Q.drop (Q.length s - n) s