intcode 0.1.0.0 → 0.2.0.0
raw patch · 3 files changed
+58/−37 lines, 3 filesPVP ok
version bump matches the API change (PVP)
API changes (from Hackage documentation)
- Intcode: intCodeToList :: [Int] -> [Int] -> [Int]
+ Intcode: intcodeToList :: [Int] -> [Int] -> [Int]
Files
- CHANGELOG.md +3/−0
- intcode.cabal +7/−1
- src/Intcode.hs +48/−36
CHANGELOG.md view
@@ -1,4 +1,7 @@ # Revision history for intcode +## 0.2.0.0+* Rename 'intCodeToList' to 'intcodeToList'+ ## 0.1.0.0 * Initial release
intcode.cabal view
@@ -1,7 +1,7 @@ cabal-version: 2.4 name: intcode-version: 0.1.0.0+version: 0.2.0.0 synopsis: Advent of Code 2019 intcode interpreter category: Compilers/Interpreters license: ISC@@ -10,6 +10,8 @@ maintainer: emertens@gmail.com copyright: 2019 Eric Mertens build-type: Simple+homepage: https://github.com/glguy/intcode+bug-reports: https://github.com/glguy/intcode/issues tested-with: GHC ==8.6.5, GHC ==8.8.1 description:@@ -23,6 +25,10 @@ extra-source-files: CHANGELOG.md README.md++source-repository head+ type: git+ location: https://github.com/glguy/intcode library hs-source-dirs: src
src/Intcode.hs view
@@ -18,18 +18,18 @@ 1. Parse input text file into a list of numbers 2. Execute op codes to single-step input/output effects. 3. Execute single-stop effects into big-step effects.- 4. Optional: Evaluate the effect as a function from a list of inputs to list of outputs Common use modes: -* List functions: 'intCodeToList'-* Effect interpretation: 'new', 'run', 'Effect'+* List functions: 'intcodeToList'+* Individual machine step processing: 'Step', 'new', 'step'+* Input/output interpretation: 'Effect', 'new', 'run' -} module Intcode ( -- * Simple interface- intCodeToList,+ intcodeToList, runIO, -- * Machine state@@ -60,7 +60,8 @@ -- ASCII I/O ------------------------------------------------------------------------ --- | Run intcode program using stdio.+-- | Run intcode program using stdio. Non-ASCII outputs are printed as+-- integers. -- -- >>> runIO (run (new [104,72,104,101,104,108,104,108,104,111,104,33,104,10,99])) -- Hello!@@ -83,25 +84,25 @@ -- Throws: 'IntcodeFault' when machine faults or too few inputs are provided. -- ----- >>> intCodeToList [3,12,6,12,15,1,13,14,13,4,13,99,-1,0,1,9] <$> [[0],[10]]+-- >>> intcodeToList [3,12,6,12,15,1,13,14,13,4,13,99,-1,0,1,9] <$> [[0],[10]] -- [[0],[1]] ----- >>> intCodeToList [3,3,1105,-1,9,1101,0,0,12,4,12,99,1] <$> [[0],[10]]+-- >>> intcodeToList [3,3,1105,-1,9,1101,0,0,12,4,12,99,1] <$> [[0],[10]] -- [[0],[1]] -- -- >>> :{--- >>> intCodeToList+-- >>> intcodeToList -- >>> [3,21,1008,21,8,20,1005,20,22,107,8,21,20,1006,20,31, -- >>> 1106,0,36,98,0,0,1002,21,125,20,4,20,1105,1,46,104, -- >>> 999,1105,1,46,1101,1000,1,20,4,20,1105,1,46,98,99] -- >>> <$> [[7],[8],[9]] -- >>> :} -- [[999],[1000],[1001]]-intCodeToList ::+intcodeToList :: [Int] {- ^ initial memory -} -> [Int] {- ^ inputs -} -> [Int] {- ^ outputs -}-intCodeToList = effectList . run . new+intcodeToList = effectList . run . new -- | Evaluate a program's effect as a function from a list of -- inputs to a list of outputs.@@ -133,7 +134,10 @@ deriving (Eq, Ord, Show) -- | Value stored in initial memory image at given index.-indexImage :: Machine -> Int -> Int+indexImage ::+ Machine {- ^ machine -} ->+ Int {- ^ position -} ->+ Int {- ^ value -} indexImage m i | a `seq` True, 0 <= i, i < P.sizeofPrimArray a = P.indexPrimArray a i | otherwise = 0@@ -207,7 +211,9 @@ | Fault -- ^ Execution failure deriving Show --- | Big-step semantics of virtual machine.+-- | Big-step semantics of virtual machine. The implementation details+-- of 'Machine' are abstracted away and the program behavior can be+-- observed by interpreting the various 'Effect' constructors. -- -- >>> run (new [1102,34915192,34915192,7,4,7,99,0]) -- Output 1219070632396864 Halt@@ -252,7 +258,7 @@ followedBy (Output o x) y = Output o (followedBy x y) followedBy (Input f ) y = Input (\i -> followedBy (f i) y) --- | Provide an input to the first occurence of an input request+-- | Provide an input to the first occurrence of an input request -- in a program effect. It is considered a fault if a program -- terminates before using the input. --@@ -281,35 +287,38 @@ -- | Small-step semantics of virtual machine. step :: Machine -> Step step mach =- case populateParams <$> decode (at (pc mach)) of+ case populateParams <$> decode (mach ! pc mach) of Nothing -> StepFault- Just (pc', opcode) -> impl opcode $! jmp pc' mach+ Just (pc', opcode) -> opcodeImpl opcode $! jmp pc' mach where populateParams :: Opcode Mode -> (Int, Opcode Int) populateParams = mapWithIndex toPtr (pc mach + 1) - at :: Int -> Int- at i = mach ! i- toPtr :: Int -> Mode -> Int- toPtr i Imm = i- toPtr i Abs = at i- toPtr i Rel = at i + relBase mach+ toPtr i Imm = i+ toPtr i Abs = mach ! i+ toPtr i Rel = mach ! i + relBase mach - impl :: Opcode Int -> Machine -> Step- impl opcode =- case opcode of- Add a b c -> Step . set c (at a + at b)- Mul a b c -> Step . set c (at a * at b)- Inp a -> StepIn . flip (set a)- Out a -> StepOut (at a)- Jnz a b -> Step . if at a /= 0 then jmp (at b) else id- Jz a b -> Step . if at a == 0 then jmp (at b) else id- Lt a b c -> Step . set c (if at a < at b then 1 else 0)- Eq a b c -> Step . set c (if at a == at b then 1 else 0)- Arb a -> Step . adjustRelBase (at a)- Hlt -> const StepHalt+-- | Apply a decoded opcode to the machine state.+opcodeImpl ::+ Opcode Int {- ^ opcode with pointers -} ->+ Machine {- ^ machine with PC updated -} ->+ Step+opcodeImpl o m =+ case o of+ Add a b c -> Step (set c (at a + at b) m)+ Mul a b c -> Step (set c (at a * at b) m)+ Inp a -> StepIn (\i -> set a i m)+ Out a -> StepOut (at a) m+ Jnz a b -> Step (if at a /= 0 then jmp (at b) m else m)+ Jz a b -> Step (if at a == 0 then jmp (at b) m else m)+ Lt a b c -> Step (set c (if at a < at b then 1 else 0) m)+ Eq a b c -> Step (set c (if at a == at b then 1 else 0) m)+ Arb a -> Step (adjustRelBase (at a) m)+ Hlt -> StepHalt+ where+ at i = m ! i mapWithIndex :: (Int -> a -> b) -> Int -> Opcode a -> (Int, Opcode b) mapWithIndex f = mapAccumL (\i a -> (i+1, f i a))@@ -362,7 +371,10 @@ fill = traverse (parameter n) -- | Compute the parameter mode for an argument at a given position.-parameter :: Int {- ^ opcode -} -> Int {- ^ position -} -> Maybe Mode+parameter ::+ Int {- ^ opcode -} ->+ Int {- ^ position -} ->+ Maybe Mode parameter n i = case digit (i+1) n of 0 -> Just Abs@@ -401,7 +413,7 @@ -- Exceptions ------------------------------------------------------------------------ --- | Error when a machine fails to step.+-- | Error when a machine fails to decode an instruction. data IntcodeFault = IntcodeFault deriving (Eq, Ord, Show, Read)