X-Git-Url: https://git.njae.me.uk/?p=advent-of-code-19.git;a=blobdiff_plain;f=advent02%2Fsrc%2Fadvent02.hs;h=1c127f7533bbfc2ec152e23915bfb36ce7226a97;hp=6eddc0a7375f5d71b7886517f9beed0b4ea6e988;hb=9c092291e0a897ae7c8b3d59b04a0cd1938bbcaf;hpb=6bee1a6e12e08b5e130add0d3e1f8b80b66b722a diff --git a/advent02/src/advent02.hs b/advent02/src/advent02.hs index 6eddc0a..1c127f7 100644 --- a/advent02/src/advent02.hs +++ b/advent02/src/advent02.hs @@ -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