1
0
Fork 0
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:
Lukas Winkler 2019-12-05 20:33:54 +01:00
parent 29e5c6d740
commit 76daaaa199
Signed by: lukas
GPG key ID: 54DE4D798D244853
3 changed files with 176 additions and 1 deletions

94
python/5/day5.py Normal file
View 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
View 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

View file

@ -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]