1 import qualified Data.Sequence as Q
2 import Data.Sequence ((<|), (|>))
4 import Data.Foldable (toList)
6 type Recipes = Q.Seq Int
7 data State = State Int Int Recipes deriving (Eq, Show)
10 -- targetLength = 59414
14 let state = State 0 1 (Q.fromList [3, 7])
15 putStrLn $ part1 state
18 part1 :: State -> String
19 part1 state0 = concatMap show $ toList $ Q.take 10 $ Q.drop targetLength recipes
20 where (State _ _ recipes) = last $ takeWhile unfinished1 $ states state0
22 unfinished1 :: State -> Bool
23 unfinished1 (State _ _ recipes) = (Q.length recipes) <= (targetLength + 10)
26 part2 state0 = if (takeR (Q.length targetSeq) recipes) == targetSeq
27 then (Q.length recipes) - (Q.length targetSeq)
28 else (Q.length recipes) - (Q.length targetSeq) - 1
29 -- recipes -- (Q.length recipes) - (Q.length targetSeq)
31 where (State _ _ recipes) = head $ dropWhile (unfinished2 targetSeq) $ states state0
33 unfinished2 :: Recipes -> State -> Bool
34 unfinished2 target (State _ _ recipes) =
35 ((takeR (Q.length target) recipes) /= target)
37 ((Q.take (Q.length target) (takeR (1 + Q.length target) recipes)) /= target)
39 states :: State -> [State]
40 states = iterate extend
42 extend :: State -> State
43 extend (State e1 e2 recipes) = State e1' e2' recipes'
44 where v1 = Q.index recipes e1
45 v2 = Q.index recipes e2
47 recipes' = if total >= 10
48 then recipes |> (total `div` 10) |> (total `mod` 10)
50 e1' = (e1 + v1 + 1) `mod` (Q.length recipes')
51 e2' = (e2 + v2 + 1) `mod` (Q.length recipes')
54 targetSeq = Q.fromList $ map read $ map (take 1 . drop 1) $ map show $ show targetLength
56 takeR n s = Q.drop (Q.length s - n) s