Moved Intcode interpreter into a separate module, ensured all previous days still...
[advent-of-code-19.git] / advent02 / src / advent02.hs
index 6eddc0a7375f5d71b7886517f9beed0b4ea6e988..1c127f7533bbfc2ec152e23915bfb36ce7226a97 100644 (file)
@@ -1,36 +1,15 @@
--- Some code taken from [AoC 2017 day 5](https://adventofcode.com/2017/day/5), 
---    and some from [AoC 2018 day 21](https://adventofcode.com/2018/day/21)
 
-import Data.Text (Text)
 import qualified Data.Text.IO as TIO
 
-import Data.Void (Void)
-
-import Text.Megaparsec hiding (State)
-import Text.Megaparsec.Char
-import qualified Text.Megaparsec.Char.Lexer as L
-import qualified Control.Applicative as CA
-
-import Control.Monad (unless)
-import Control.Monad.State.Strict
-
-import qualified Data.IntMap.Strict as M
-import Data.IntMap.Strict ((!))
-
-type Memory = M.IntMap Int
-
-data Machine = Machine { _memory :: Memory
-                       , _ip :: Int
-                       } 
-               deriving (Show, Eq)
-
-type ProgrammedMachine = State Machine ()
+import Intcode
 
+import qualified Data.Map as M
+import Data.Map ((!))
 
 main :: IO ()
 main = do 
         text <- TIO.readFile "data/advent02.txt"
-        let mem = successfulParse text
+        let mem = parseMachineMemory text
         let machine = makeMachine mem
         print $ part1 machine
         print $ part2 machine
@@ -49,74 +28,14 @@ part2 machine = noun * 100 + verb
                                           nounVerbResult n v machine == part2Target ]
 
 
-makeMachine :: [Int] -> Machine
-makeMachine memory = Machine {_ip = 0, _memory = M.fromList $ zip [0..] memory}
+nounVerbResult :: Integer -> Integer -> Machine -> Integer
+nounVerbResult noun verb machine = machineOutput machine'
+    where   (_, machine', _) = runMachine [] nvMachine
+            nvMachine = machineNounVerb machine noun verb
 
-nounVerbResult :: Int -> Int -> Machine -> Int
-nounVerbResult noun verb machine = machineOutput nvMachine
-    where nvMachine0 = machineNounVerb machine noun verb
-          nvMachine = execState runAll nvMachine0
-
-machineNounVerb :: Machine -> Int -> Int -> Machine
+machineNounVerb :: Machine -> Integer -> Integer -> Machine
 machineNounVerb machine noun verb = machine { _memory = M.insert 1 noun $ M.insert 2 verb $ _memory machine }
 
-machineOutput :: Machine -> Int
+machineOutput :: Machine -> Integer
 machineOutput machine = (_memory machine)!0
 
-
-runAll :: ProgrammedMachine
-runAll = do m0 <- get
-            unless (lkup (_ip m0) (_memory m0) == 99)
-                do runStep
-                   runAll
-
-runStep :: ProgrammedMachine
-runStep = 
-    do m0 <- get
-       let mem = _memory m0
-       let ip = _ip m0
-       let (mem', ip') = perform (mem!ip) ip mem
-       put m0 {_ip = ip', _memory = mem'}
-
-perform :: Int -> Int -> Memory -> (Memory, Int)
-perform 1 ip mem = (iInsert (ip + 3) (a + b) mem, ip + 4)
-    where a = mem!>(ip + 1)
-          b = mem!>(ip + 2)
-perform 2 ip mem = (iInsert (ip + 3) (a * b) mem, ip + 4)
-    where a = mem!>(ip + 1)
-          b = mem!>(ip + 2)
-
-
--- Some IntMap utility functions, for syntactic sugar
-
--- prefix version of (!)
-lkup k m = m!k
-
--- indirect lookup
-(!>) m k = m!(m!k)
-
--- indirect insert
-iInsert k v m = M.insert (m!k) v m
-
-
-
--- Parse the input file
-type Parser = Parsec Void Text
-
-sc :: Parser ()
-sc = L.space (skipSome spaceChar) CA.empty CA.empty
--- sc = L.space (skipSome (char ' ')) CA.empty CA.empty
-
-lexeme  = L.lexeme sc
-integer = lexeme L.decimal
--- signedInteger = L.signed sc integer
-symb = L.symbol sc
-comma = symb ","
-
-memoryP = integer `sepBy` comma
-
-successfulParse :: Text -> [Int]
-successfulParse input = 
-        case parse memoryP "input" input of
-                Left  _err -> [] -- TIO.putStr $ T.pack $ parseErrorPretty err
-                Right memory -> memory
\ No newline at end of file