Day 22: Monkey Market
Megathread guidelines
- Keep top level comments as only solutions, if you want to say something other than a solution put it in a new post. (replies to comments can be whatever)
- You can send code in code blocks by using three backticks, the code, and then three backticks or use something such as https://topaz.github.io/paste/ if you prefer sending it through a URL
FAQ
- What is this?: Here is a post with a large amount of details: https://programming.dev/post/6637268
- Where do I participate?: https://adventofcode.com/
- Is there a leaderboard for the community?: We have a programming.dev leaderboard with the info on how to join in this post: https://programming.dev/post/6631465
Haskell
I have no Idea how to optimize this and am looking forward to the other solutions that probably run in sub-single-second times. I like my solution because it was simple to write which I hadn’t managed in the previous days, runs in 17 seconds with no less than 100MB of RAM.
import Control.Arrow
import Data.Bits (xor)
import Data.Ord (comparing)
import qualified Data.List as List
import qualified Data.Map as Map
parse :: String -> [Int]
parse = map read . filter (/= "") . lines
mix = xor
prune = flip mod 16777216
priceof = flip mod 10
nextSecret step0 = do
let step1 = prune . mix step0 $ step0 * 64
let step2 = prune . mix step1 $ step1 `div` 32
let step3 = prune . mix step2 $ step2 * 2048
step3
part1 = sum . map (head . drop 2000 . iterate nextSecret)
part2 = map (iterate nextSecret
>>> take 2001
>>> map priceof
>>> (id &&& tail)
>>> uncurry (zipWith (curry (uncurry (flip (-)) &&& snd)))
>>> map (take 4) . List.tails
>>> filter ((==4) . length)
>>> map (List.map fst &&& snd . List.last)
>>> List.foldl (\ m (s, p) -> Map.insertWith (flip const) s p m) Map.empty
)
>>> Map.unionsWith (+)
>>> Map.assocs
>>> List.maximumBy (comparing snd)
main = getContents
>>= print
. (part1 &&& part2)
. parse
Haha, same! Mine runs in a bit under 4s compiled, but uses a similar 100M-ish peak. Looks like we used the same method.
Maybe iterate all the secrets in parallel, and keep a running note of the best sequences so far? I’m not sure how you’d decide when to throw away old candidates, though. Sequences might match one buyer early and another really late.