parent
6b507bc436
commit
5d482a4230
4 changed files with 143 additions and 2 deletions
@ -0,0 +1 @@ |
|||||||
|
3,225,1,225,6,6,1100,1,238,225,104,0,1101,61,45,225,102,94,66,224,101,-3854,224,224,4,224,102,8,223,223,1001,224,7,224,1,223,224,223,1101,31,30,225,1102,39,44,224,1001,224,-1716,224,4,224,102,8,223,223,1001,224,7,224,1,224,223,223,1101,92,41,225,101,90,40,224,1001,224,-120,224,4,224,102,8,223,223,1001,224,1,224,1,223,224,223,1101,51,78,224,101,-129,224,224,4,224,1002,223,8,223,1001,224,6,224,1,224,223,223,1,170,13,224,101,-140,224,224,4,224,102,8,223,223,1001,224,4,224,1,223,224,223,1101,14,58,225,1102,58,29,225,1102,68,70,225,1002,217,87,224,101,-783,224,224,4,224,102,8,223,223,101,2,224,224,1,224,223,223,1101,19,79,225,1001,135,42,224,1001,224,-56,224,4,224,102,8,223,223,1001,224,6,224,1,224,223,223,2,139,144,224,1001,224,-4060,224,4,224,102,8,223,223,101,1,224,224,1,223,224,223,1102,9,51,225,4,223,99,0,0,0,677,0,0,0,0,0,0,0,0,0,0,0,1105,0,99999,1105,227,247,1105,1,99999,1005,227,99999,1005,0,256,1105,1,99999,1106,227,99999,1106,0,265,1105,1,99999,1006,0,99999,1006,227,274,1105,1,99999,1105,1,280,1105,1,99999,1,225,225,225,1101,294,0,0,105,1,0,1105,1,99999,1106,0,300,1105,1,99999,1,225,225,225,1101,314,0,0,106,0,0,1105,1,99999,1008,677,226,224,102,2,223,223,1006,224,329,101,1,223,223,108,677,677,224,102,2,223,223,1005,224,344,101,1,223,223,107,677,677,224,1002,223,2,223,1005,224,359,101,1,223,223,1107,226,677,224,1002,223,2,223,1005,224,374,1001,223,1,223,1008,677,677,224,102,2,223,223,1006,224,389,1001,223,1,223,1007,677,677,224,1002,223,2,223,1006,224,404,1001,223,1,223,8,677,226,224,102,2,223,223,1005,224,419,1001,223,1,223,8,226,226,224,102,2,223,223,1006,224,434,101,1,223,223,1107,226,226,224,1002,223,2,223,1006,224,449,101,1,223,223,1107,677,226,224,102,2,223,223,1005,224,464,101,1,223,223,1108,226,226,224,102,2,223,223,1006,224,479,1001,223,1,223,7,677,677,224,1002,223,2,223,1006,224,494,101,1,223,223,7,677,226,224,102,2,223,223,1005,224,509,101,1,223,223,1108,226,677,224,1002,223,2,223,1006,224,524,101,1,223,223,8,226,677,224,1002,223,2,223,1005,224,539,101,1,223,223,1007,226,226,224,102,2,223,223,1006,224,554,1001,223,1,223,108,226,226,224,1002,223,2,223,1006,224,569,1001,223,1,223,1108,677,226,224,102,2,223,223,1005,224,584,101,1,223,223,108,226,677,224,102,2,223,223,1005,224,599,101,1,223,223,1007,226,677,224,102,2,223,223,1006,224,614,1001,223,1,223,1008,226,226,224,1002,223,2,223,1006,224,629,1001,223,1,223,107,226,226,224,1002,223,2,223,1006,224,644,101,1,223,223,7,226,677,224,102,2,223,223,1005,224,659,1001,223,1,223,107,677,226,224,102,2,223,223,1005,224,674,1001,223,1,223,4,223,99,226 |
@ -0,0 +1,132 @@ |
|||||||
|
module Day5 |
||||||
|
( |
||||||
|
module Day5 |
||||||
|
) where |
||||||
|
|
||||||
|
import Data.Char |
||||||
|
import Data.Maybe |
||||||
|
import Control.Applicative |
||||||
|
import qualified Data.Text as T |
||||||
|
import qualified Data.Attoparsec.Text as P |
||||||
|
import qualified Data.Vector as V |
||||||
|
|
||||||
|
type ADDRp = Int |
||||||
|
type ADDRi = Integer |
||||||
|
type ADDR = Either ADDRp ADDRi |
||||||
|
type INPUT = Integer |
||||||
|
type OUTPUT = Integer |
||||||
|
|
||||||
|
data Instruction = ADD ADDR ADDR ADDRp |
||||||
|
| MUL ADDR ADDR ADDRp |
||||||
|
| STORE ADDRp |
||||||
|
| LOAD ADDRp |
||||||
|
| JMPT ADDR ADDR |
||||||
|
| JMPF ADDR ADDR |
||||||
|
| LT' ADDR ADDR ADDRp |
||||||
|
| EQ' ADDR ADDR ADDRp |
||||||
|
| HALT |
||||||
|
deriving (Show) |
||||||
|
|
||||||
|
execute :: INPUT -> String -> [OUTPUT] |
||||||
|
execute i s = maybe [] (runProgram i) $ parseProgram (T.pack s) |
||||||
|
|
||||||
|
type Program = V.Vector Integer |
||||||
|
type PC = Int |
||||||
|
type RunningProg = (INPUT, Program, PC, [OUTPUT]) |
||||||
|
|
||||||
|
parseProgram :: T.Text -> Maybe Program |
||||||
|
parseProgram = fmap V.fromList . P.maybeResult . parseNumbers |
||||||
|
where parseNumbers = P.parse (P.sepBy1 (P.signed P.decimal) (P.char ',')) |
||||||
|
|
||||||
|
runProgram :: INPUT -> Program -> [OUTPUT] |
||||||
|
runProgram i p = go i p 0 [] |
||||||
|
where go i' p' pc outputs = |
||||||
|
let inst = parseInstruction p' pc in |
||||||
|
case inst of |
||||||
|
HALT -> outputs |
||||||
|
_ -> let (i'', p'',pc', outputs') = executeInstruction (i', p', pc, outputs) inst in |
||||||
|
outputs ++ go i'' p'' pc' outputs' |
||||||
|
|
||||||
|
parseInstruction :: Program -> PC -> Instruction |
||||||
|
parseInstruction p i = |
||||||
|
let inst = p V.! i |
||||||
|
a = (inst `div` 10000) /= 0 |
||||||
|
b = (inst `mod` 10000) `div` 1000 /= 0 |
||||||
|
c = (inst `mod` 1000) `div` 100 /= 0 |
||||||
|
de = (inst `mod` 100) |
||||||
|
addr b a = if b then Right a else Left (fromInteger a) |
||||||
|
in |
||||||
|
case de of |
||||||
|
1 -> ADD (addr c (p V.! (i+1))) |
||||||
|
(addr b (p V.! (i+2))) |
||||||
|
(fromInteger (p V.! (i+3))) |
||||||
|
2 -> MUL (addr c (p V.! (i+1))) |
||||||
|
(addr b (p V.! (i+2))) |
||||||
|
(fromInteger (p V.! (i+3))) |
||||||
|
3 -> STORE $ fromInteger (p V.! (i+1)) |
||||||
|
4 -> LOAD $ fromInteger (p V.! (i+1)) |
||||||
|
5 -> JMPT (addr c (p V.! (i+1))) (addr b (p V.! (i+2))) |
||||||
|
6 -> JMPF (addr c (p V.! (i+1))) (addr b (p V.! (i+2))) |
||||||
|
7 -> LT' (addr c (p V.! (i+1))) |
||||||
|
(addr b (p V.! (i+2))) |
||||||
|
(fromInteger (p V.! (i+3))) |
||||||
|
8 -> EQ' (addr c (p V.! (i+1))) |
||||||
|
(addr b (p V.! (i+2))) |
||||||
|
(fromInteger (p V.! (i+3))) |
||||||
|
99 -> HALT |
||||||
|
_ -> error $ "unknown instruction " ++ show ((a,b,c), de) |
||||||
|
|
||||||
|
executeInstruction :: RunningProg -> Instruction -> RunningProg |
||||||
|
executeInstruction (input, p, pc, outputs) i = |
||||||
|
case i of |
||||||
|
ADD (Left a) (Left b) c -> |
||||||
|
(input, p V.// [(c, (p V.! a) + (p V.! b))], pc + 4, outputs) |
||||||
|
ADD (Left a) (Right b) c -> |
||||||
|
(input, p V.// [(c, (p V.! a) + b)], pc + 4, outputs) |
||||||
|
ADD (Right a) (Left b) c -> |
||||||
|
(input, p V.// [(c, a + (p V.! b))], pc + 4, outputs) |
||||||
|
ADD (Right a) (Right b) c -> |
||||||
|
(input, p V.// [(c, a + b)], pc + 4, outputs) |
||||||
|
MUL (Left a) (Left b) c -> |
||||||
|
(input, p V.// [(c, (p V.! a) * (p V.! b))], pc + 4, outputs) |
||||||
|
MUL (Left a) (Right b) c -> |
||||||
|
(input, p V.// [(c, (p V.! a) * b)], pc + 4, outputs) |
||||||
|
MUL (Right a) (Left b) c -> |
||||||
|
(input, p V.// [(c, a * (p V.! b))], pc + 4, outputs) |
||||||
|
MUL (Right a) (Right b) c -> |
||||||
|
(input, p V.// [(c, a * b)], pc + 4, outputs) |
||||||
|
STORE a -> (input, p V.// [(a, input)], pc + 2, outputs) |
||||||
|
LOAD a -> (input, p, pc + 2, outputs ++ [p V.! a]) |
||||||
|
JMPT (Left a) (Left b) -> |
||||||
|
(input, p, if (p V.! a) /= 0 then fromInteger (p V.! b) else pc + 3, outputs) |
||||||
|
JMPT (Left a) (Right b) -> |
||||||
|
(input, p, if (p V.! a) /= 0 then fromInteger b else pc + 3, outputs) |
||||||
|
JMPT (Right a) (Left b) -> |
||||||
|
(input, p, if a /= 0 then fromInteger (p V.! b) else pc + 3, outputs) |
||||||
|
JMPT (Right a) (Right b) -> |
||||||
|
(input, p, if a /= 0 then fromInteger b else pc + 3, outputs) |
||||||
|
JMPF (Left a) (Left b) -> |
||||||
|
(input, p, if (p V.! a) == 0 then fromInteger (p V.! b) else pc + 3, outputs) |
||||||
|
JMPF (Left a) (Right b) -> |
||||||
|
(input, p, if (p V.! a) == 0 then fromInteger b else pc + 3, outputs) |
||||||
|
JMPF (Right a) (Left b) -> |
||||||
|
(input, p, if a == 0 then fromInteger (p V.! b) else pc + 3, outputs) |
||||||
|
JMPF (Right a) (Right b) -> |
||||||
|
(input, p, if a == 0 then fromInteger b else pc + 3, outputs) |
||||||
|
LT' (Left a) (Left b) c -> |
||||||
|
(input, p V.// [(c, if (p V.! a) < (p V.! b) then 1 else 0)], pc + 4, outputs) |
||||||
|
LT' (Left a) (Right b) c -> |
||||||
|
(input, p V.// [(c, if (p V.! a) < b then 1 else 0)], pc + 4, outputs) |
||||||
|
LT' (Right a) (Left b) c -> |
||||||
|
(input, p V.// [(c, if a < (p V.! b) then 1 else 0)], pc + 4, outputs) |
||||||
|
LT' (Right a) (Right b) c -> |
||||||
|
(input, p V.// [(c, if a < b then 1 else 0)], pc + 4, outputs) |
||||||
|
EQ' (Left a) (Left b) c -> |
||||||
|
(input, p V.// [(c, if (p V.! a) == (p V.! b) then 1 else 0)], pc + 4, outputs) |
||||||
|
EQ' (Left a) (Right b) c -> |
||||||
|
(input, p V.// [(c, if (p V.! a) == b then 1 else 0)], pc + 4, outputs) |
||||||
|
EQ' (Right a) (Left b) c -> |
||||||
|
(input, p V.// [(c, if a == (p V.! b) then 1 else 0)], pc + 4, outputs) |
||||||
|
EQ' (Right a) (Right b) c -> |
||||||
|
(input, p V.// [(c, if a == b then 1 else 0)], pc + 4, outputs) |
||||||
|
_ -> (input, p, pc + 1, outputs) |
Loading…
Reference in new issue