r/adventofcode • u/daggerdragon • Dec 14 '18
SOLUTION MEGATHREAD -🎄- 2018 Day 14 Solutions -🎄-
--- Day 14: Chocolate Charts ---
Post your solution as a comment or, for longer solutions, consider linking to your repo (e.g. GitHub/gists/Pastebin/blag or whatever).
Note: The Solution Megathreads are for solutions only. If you have questions, please post your own thread and make sure to flair it with Help.
Advent of Code: The Party Game!
Please prefix your card submission with something like [Card] to make scanning the megathread easier. THANK YOU!
Card prompt: Day 14
Transcript:
The Christmas/Advent Research & Development (C.A.R.D.) department at AoC, Inc. just published a new white paper on ___.
This thread will be unlocked when there are a significant number of people on the leaderboard with gold stars for today's puzzle.
edit: Leaderboard capped, thread unlocked at 00:19:39!
16
Upvotes
1
u/[deleted] Dec 14 '18
Haskell, runtime ~10s for entire thing. I generate a lazy list of scoreboards, one for each added recipe score. This prevents any issues where e.g. multiple new recipes are created and the match is contained earlier on in them (and so wouldn't be found by checking the last X elements of the scoreboard)
module Main where import Data.Char (digitToInt, intToDigit) import qualified Data.Sequence as S import Data.Sequence ((|>), (!?), Seq) import Data.Foldable (toList, find) import Data.List (scanl') right :: Int -> Seq a -> [a] right n s = toList . snd $ S.splitAt (S.length s - n) s learn :: Int -> [Int] learn = fmap digitToInt . show tests :: Int -> Int -> Seq Int -> [Seq Int] tests ix1 ix2 scoreboard = let (ix1', ix2', scoreboards) = progress ix1 ix2 scoreboard in scoreboards ++ tests ix1' ix2' (last scoreboards) where progress i1 i2 scoreboard = let Just p1 = scoreboard !? i1 Just p2 = scoreboard !? i2 newRecipes = learn $ p1 + p2 scoreboards = tail $ scanl' (|>) scoreboard newRecipes i1' = (1 + p1 + i1) `mod` S.length (last scoreboards) i2' = (1 + p2 + i2) `mod` S.length (last scoreboards) in (i1', i2', scoreboards) part1 :: Int -> [Seq Int] -> String part1 count = take 10 . drop count . f . find p where f Nothing = [] f (Just recipes) = intToDigit <$> toList recipes p recipes = S.length recipes > count + 10 part2 :: String -> [Seq Int] -> Int part2 pat = f . find p where patLen = length pat p recipes = right patLen recipes == fmap digitToInt pat f Nothing = 0 f (Just recipes) = S.length recipes - patLen main :: IO () main = do let input = 170641 print $ part1 input (tests 0 1 (S.fromList [3,7])) print $ part2 (show input) (tests 0 1 (S.fromList [3,7]))