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

  • VegOwOtenks@lemmy.world
    link
    fedilink
    English
    arrow-up
    3
    ·
    2 days ago

    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
    
    • lwhjp@lemmy.sdf.org
      link
      fedilink
      arrow-up
      3
      ·
      2 days ago

      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.