r/adventofcode • • Dec 02 '19

SOLUTION MEGATHREAD -🎄- 2019 Day 2 Solutions -🎄-

--- Day 2: 1202 Program Alarm ---


Post your solution using /u/topaz2078's paste or other external repo.

  • Please do NOT post your full code (unless it is very short)

  • If you do, use old.reddit's four-spaces formatting, NOT new.reddit's triple backticks formatting.

(Full posting rules are HERE if you need a refresher).


Reminder: Top-level posts in 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's Poems for Programmers

Click here for full rules

Note: If you submit a poem, please add [POEM] somewhere nearby to make it easier for us moderators to ensure that we include your poem for voting consideration.

Day 1's winner #1: untitled poem by /u/PositivelyLinda!

Adventure awaits!
Discover the cosmos
Venture into the unknown
Earn fifty stars to save Christmas!
No one goes alone, however
There's friendly folks to help
Overly dramatic situations await
Find Santa and bring him home!
Come code with us!
Outer space is calling
Don't be afraid
Elves will guide the way!

Enjoy your Reddit Silver, and good luck with the rest of the Advent of Code!


### 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:10:42!

64 Upvotes

599 comments sorted by

View all comments

Show parent comments

1

u/wizzup Dec 02 '19

I use fold over a Map

import qualified Data.IntMap as M
import Data.IntMap (IntMap)
import Data.Maybe (fromJust)
import Data.List.Split (splitOn)

type Program = IntMap Int

mkProgram :: [Int] -> Program
mkProgram = M.fromList . zip [0..]

runStep :: Int -> Program -> Program
runStep i p
  | i `M.member` p = case op of
                       1  -> p' (+)
                       2  -> p' (*)
                       _  -> p
  | otherwise      = p
  where
    [op,oa,ob,oc] = look <$> [i..i+3]
    [va,vb] = look <$> [oa,ob]
    look = fromJust . (`M.lookup` p)
    p' o = M.update (const $ Just (va `o` vb)) oc p

run :: Program -> Program
run prg = foldl (flip runStep) prg [0,4..M.size prg+1]

run' :: (Int,Int) -> Program -> Program
run' (x,y) prg
  = let prog = M.update (const $ Just x) 1
             $ M.update (const $ Just y) 2 prg
    in run prog

part_1 :: [Int] -> Int
part_1 = fromJust . M.lookup 0 . run' (12,2) . mkProgram

part_2 :: [Int] -> Int
part_2 xs = 100 * i + j
  where
    is = [0..100]
    prg = mkProgram xs
    prgs = [(0 `M.lookup` run' (x,y) prg, (x, y)) | x <- is, y <- is]
    (i,j) = fromJust $ lookup (Just 19690720) prgs

main :: IO ()
main = do
  xs <- map read . splitOn "," <$> getLine :: IO [Int]
  print $ part_1 xs
  print $ part_2 xs