mirror of
https://github.com/Findus23/AdventOfCode2019.git
synced 2024-08-27 19:52:12 +02:00
complete day 5
This commit is contained in:
parent
29e5c6d740
commit
76daaaa199
3 changed files with 176 additions and 1 deletions
94
python/5/day5.py
Normal file
94
python/5/day5.py
Normal file
|
@ -0,0 +1,94 @@
|
|||
from typing import List, Tuple
|
||||
|
||||
intcode = List[int]
|
||||
INPUT = 1
|
||||
|
||||
|
||||
def parse_intcode(text: str) -> intcode:
|
||||
return list(map(int, text.split(",")))
|
||||
|
||||
|
||||
def decode_code(code: int):
|
||||
paramcode, opcode = divmod(code, 100) # splits 12345 into (123,45)
|
||||
return paramcode, opcode
|
||||
|
||||
|
||||
class ParamReader():
|
||||
def __init__(self, pointer, cl, paramcode):
|
||||
self.pointer = pointer
|
||||
self.cl = cl
|
||||
self.paramcode = paramcode
|
||||
|
||||
def index(self, id):
|
||||
return self.cl[self.pointer + id]
|
||||
|
||||
def param(self, id):
|
||||
param_mode = (self.paramcode // 10 ** (id - 1)) % 10
|
||||
if param_mode == 1:
|
||||
return self.index(id)
|
||||
elif param_mode == 0:
|
||||
return self.cl[self.index(id)% len(self.cl)]
|
||||
else:
|
||||
raise ValueError(f"invalid parameter code {param_mode} for parameter {id}")
|
||||
|
||||
|
||||
def run_intcode(codelist: intcode, input) -> Tuple[intcode, List[int]]:
|
||||
# codelist.extend([99, 99, 99]) # hack so we don't look over the edge
|
||||
output = []
|
||||
p = 0 # pointer
|
||||
while True:
|
||||
paramcode, code = decode_code(codelist[p])
|
||||
pr = ParamReader(p, codelist, paramcode)
|
||||
|
||||
if code == 99:
|
||||
break
|
||||
if code == 1:
|
||||
codelist[pr.index(3)] = pr.param(1) + pr.param(2)
|
||||
elif code == 2:
|
||||
codelist[pr.index(3)] = pr.param(1) * pr.param(2)
|
||||
elif code == 3:
|
||||
codelist[pr.index(1)] = input
|
||||
elif code == 4:
|
||||
output.append(pr.param(1))
|
||||
elif code == 5: # jump if true
|
||||
if pr.param(1):
|
||||
p = pr.param(2)
|
||||
else:
|
||||
p += 3
|
||||
elif code == 6: # jump if false
|
||||
if not pr.param(1):
|
||||
p = pr.param(2)
|
||||
else:
|
||||
p += 3
|
||||
elif code == 7: # less than
|
||||
codelist[pr.index(3)] = 1 if (pr.param(1) < pr.param(2)) else 0
|
||||
elif code == 8: # equals
|
||||
codelist[pr.index(3)] = 1 if (pr.param(1) == pr.param(2)) else 0
|
||||
else:
|
||||
raise ValueError(f"invalid intcode: {code}")
|
||||
if code in [1, 2,7, 8]:
|
||||
p += 4
|
||||
elif code in [3, 4]:
|
||||
p += 2
|
||||
return codelist, output
|
||||
|
||||
|
||||
def part1() -> List[int]:
|
||||
with open("5/input.txt") as f:
|
||||
cl = parse_intcode(f.read())
|
||||
cl, output = run_intcode(cl, input=1)
|
||||
|
||||
return output
|
||||
|
||||
|
||||
def part2() -> List[int]:
|
||||
with open("5/input.txt") as f:
|
||||
cl = parse_intcode(f.read())
|
||||
cl, output = run_intcode(cl, input=5)
|
||||
|
||||
return output
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
# print(part1())
|
||||
print(part2())
|
1
python/5/input.txt
Normal file
1
python/5/input.txt
Normal file
|
@ -0,0 +1 @@
|
|||
3,225,1,225,6,6,1100,1,238,225,104,0,1101,11,91,225,1002,121,77,224,101,-6314,224,224,4,224,1002,223,8,223,1001,224,3,224,1,223,224,223,1102,74,62,225,1102,82,7,224,1001,224,-574,224,4,224,102,8,223,223,1001,224,3,224,1,224,223,223,1101,28,67,225,1102,42,15,225,2,196,96,224,101,-4446,224,224,4,224,102,8,223,223,101,6,224,224,1,223,224,223,1101,86,57,225,1,148,69,224,1001,224,-77,224,4,224,102,8,223,223,1001,224,2,224,1,223,224,223,1101,82,83,225,101,87,14,224,1001,224,-178,224,4,224,1002,223,8,223,101,7,224,224,1,223,224,223,1101,38,35,225,102,31,65,224,1001,224,-868,224,4,224,1002,223,8,223,1001,224,5,224,1,223,224,223,1101,57,27,224,1001,224,-84,224,4,224,102,8,223,223,1001,224,7,224,1,223,224,223,1101,61,78,225,1001,40,27,224,101,-89,224,224,4,224,1002,223,8,223,1001,224,1,224,1,224,223,223,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,1002,223,2,223,1006,224,329,101,1,223,223,8,226,677,224,102,2,223,223,1005,224,344,101,1,223,223,1107,226,677,224,102,2,223,223,1006,224,359,101,1,223,223,1007,226,226,224,102,2,223,223,1006,224,374,101,1,223,223,7,677,677,224,102,2,223,223,1005,224,389,1001,223,1,223,108,677,677,224,1002,223,2,223,1005,224,404,101,1,223,223,1008,226,226,224,102,2,223,223,1005,224,419,1001,223,1,223,1107,677,226,224,102,2,223,223,1005,224,434,1001,223,1,223,1108,677,677,224,102,2,223,223,1006,224,449,1001,223,1,223,7,226,677,224,102,2,223,223,1005,224,464,101,1,223,223,1008,677,677,224,102,2,223,223,1005,224,479,101,1,223,223,1007,226,677,224,1002,223,2,223,1006,224,494,101,1,223,223,8,677,226,224,1002,223,2,223,1005,224,509,101,1,223,223,1007,677,677,224,1002,223,2,223,1006,224,524,101,1,223,223,107,226,226,224,102,2,223,223,1006,224,539,101,1,223,223,107,226,677,224,102,2,223,223,1005,224,554,1001,223,1,223,7,677,226,224,102,2,223,223,1006,224,569,1001,223,1,223,107,677,677,224,1002,223,2,223,1005,224,584,101,1,223,223,1107,677,677,224,102,2,223,223,1005,224,599,101,1,223,223,1108,226,677,224,102,2,223,223,1006,224,614,101,1,223,223,8,226,226,224,102,2,223,223,1006,224,629,101,1,223,223,108,226,677,224,102,2,223,223,1005,224,644,1001,223,1,223,108,226,226,224,102,2,223,223,1005,224,659,101,1,223,223,1108,677,226,224,102,2,223,223,1006,224,674,1001,223,1,223,4,223,99,226
|
|
@ -1,4 +1,8 @@
|
|||
from day5 import run_intcode, decode_code, part1
|
||||
from day5 import run_intcode, decode_code, part1, part2
|
||||
|
||||
complex = [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]
|
||||
|
||||
|
||||
def test_new_opcodes():
|
||||
|
@ -19,3 +23,79 @@ def test_decode_code():
|
|||
|
||||
def test_part1():
|
||||
assert part1() == [0, 0, 0, 0, 0, 0, 0, 0, 0, 7286649]
|
||||
|
||||
|
||||
def test_advanced1_false():
|
||||
assert run_intcode(
|
||||
[3, 9, 8, 9, 10, 9, 4, 9, 99, -1, 8], input=42) == ([3, 9, 8, 9, 10, 9, 4, 9, 99, 0, 8], [0])
|
||||
|
||||
|
||||
def test_advanced1_true():
|
||||
assert run_intcode(
|
||||
[3, 9, 8, 9, 10, 9, 4, 9, 99, -1, 8], input=8) == ([3, 9, 8, 9, 10, 9, 4, 9, 99, 1, 8], [1])
|
||||
|
||||
|
||||
def test_advanced2_false():
|
||||
assert run_intcode(
|
||||
[3, 9, 7, 9, 10, 9, 4, 9, 99, -1, 8], input=10) == ([3, 9, 7, 9, 10, 9, 4, 9, 99, 0, 8], [0])
|
||||
|
||||
|
||||
def test_advanced2_true():
|
||||
assert run_intcode(
|
||||
[3, 9, 7, 9, 10, 9, 4, 9, 99, -1, 8], input=5) == ([3, 9, 7, 9, 10, 9, 4, 9, 99, 1, 8], [1])
|
||||
|
||||
|
||||
def test_advanced3_false():
|
||||
assert run_intcode(
|
||||
[3, 3, 1108, -1, 8, 3, 4, 3, 99], input=10) == ([3, 3, 1108, 0, 8, 3, 4, 3, 99], [0])
|
||||
|
||||
|
||||
def test_advanced3_true():
|
||||
assert run_intcode(
|
||||
[3, 3, 1108, -1, 8, 3, 4, 3, 99], input=8) == ([3, 3, 1108, 1, 8, 3, 4, 3, 99], [1])
|
||||
|
||||
|
||||
def test_advanced4_false():
|
||||
assert run_intcode(
|
||||
[3, 3, 1107, -1, 8, 3, 4, 3, 99], input=10) == ([3, 3, 1107, 0, 8, 3, 4, 3, 99], [0])
|
||||
|
||||
|
||||
def test_advanced4_true():
|
||||
assert run_intcode(
|
||||
[3, 3, 1107, -1, 8, 3, 4, 3, 99], input=5) == ([3, 3, 1107, 1, 8, 3, 4, 3, 99], [1])
|
||||
|
||||
|
||||
def test_jump1_nonzero():
|
||||
assert run_intcode(
|
||||
[3, 12, 6, 12, 15, 1, 13, 14, 13, 4, 13, 99, -1, 0, 1, 9], input=5)[1][0] == 1
|
||||
|
||||
|
||||
def test_jump1_zero():
|
||||
assert run_intcode(
|
||||
[3, 12, 6, 12, 15, 1, 13, 14, 13, 4, 13, 99, -1, 0, 1, 9], input=0)[1][0] == 0
|
||||
|
||||
|
||||
def test_jump2_nonzero():
|
||||
assert run_intcode(
|
||||
[3, 3, 1105, -1, 9, 1101, 0, 0, 12, 4, 12, 99, 1], input=5)[1][0] == 1
|
||||
|
||||
|
||||
def test_jump2_zero():
|
||||
assert run_intcode(
|
||||
[3, 3, 1105, -1, 9, 1101, 0, 0, 12, 4, 12, 99, 1], input=0)[1][0] == 0
|
||||
|
||||
|
||||
def test_complex_below_8():
|
||||
assert run_intcode(complex, input=5)[1][0] == 999
|
||||
|
||||
|
||||
def test_complex_8():
|
||||
assert run_intcode(complex, input=8)[1][0] == 1000
|
||||
|
||||
|
||||
def test_complex_above_8():
|
||||
assert run_intcode(complex, input=15)[1][0] == 1001
|
||||
|
||||
|
||||
def test_part2():
|
||||
assert part2() == [15724522]
|
||||
|
|
Loading…
Reference in a new issue