Skip to content

Instantly share code, notes, and snippets.

@bChiquet
Created January 17, 2020 09:30
Show Gist options
  • Save bChiquet/200c663eed82afdd3281c5312d8bbd4f to your computer and use it in GitHub Desktop.
Save bChiquet/200c663eed82afdd3281c5312d8bbd4f to your computer and use it in GitHub Desktop.
aoc_2
module Lib
( Program
, Cursor
, eval
, (|+|)
, at, writeIn
, Value(..)
) where
import Control.Monad (liftM2)
import Data.Function ((&))
import Debug.Trace
type Cursor = Int
type Program = [Int]
type Error = String
data Value =
Address Int
at :: [Int] -> Value -> Either Error Int
at (value:_) (Address 0) = Right value
at (_:rest) (Address n) = rest `at` Address (n-1)
at [] (Address n) = Left ("Tried to read out of bounds: " ++ show n)
(|+|) :: Monad m => m Int -> m Int -> m Int
(|+|) = liftM2 (+)
(|*|) :: Monad m => m Int -> m Int -> m Int
(|*|) = liftM2 (*)
writeIn :: Value -> Program -> Int -> Either Error Program
writeIn (Address 0) (addr0:rest) input = Right (input:rest)
writeIn (Address a) p@(addr0:rest) input =
writeIn (Address (a-1)) rest input
& fmap (addr0 :)
writeIn (Address a) _ _ = Left ("Tried to write out of bounds: " ++ show a)
eval :: Cursor -> Program -> Either Error Program
eval c program = case drop c program of
1:ina:inb:out:_ ->
((program `at` Address ina) |+| (program `at` Address inb))
>>= writeIn (Address out) program
>>= eval (c+4)
2:ina:inb:out:_ ->
((program `at` Address ina) |*| (program `at` Address inb))
>>= writeIn (Address out) program
>>= eval (c+4)
99:_ ->
Right program
op ->
Left ("Tried to eval unknown operation: " ++ show op)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment