Solve 2019:05 "Sunny with a Chance of Asteroids"
Refactored the intcode computer to live in a separate file, since it will come back more times. As a nice touch, output of aoc.py will print the version used of the intcode. As another nice touch, the int code has a CHANGELOG.
This commit is contained in:
parent
298b97b66d
commit
9eccd731b4
3 changed files with 181 additions and 30 deletions
|
|
@ -1,6 +1,8 @@
|
|||
from output import answer, puzzleinput
|
||||
from collections import defaultdict
|
||||
|
||||
from output.intcode_computer import execute
|
||||
|
||||
n = 2
|
||||
title = "1202 Program Alarm"
|
||||
|
||||
|
|
@ -10,41 +12,15 @@ def parse_input(data):
|
|||
return list(map(int, data.split(",")))
|
||||
|
||||
|
||||
@answer(1, "Value of pos 0 is {} at halt signal")
|
||||
@answer(1, "[intcode-0.1.0] Value of pos 0 is {} at halt signal")
|
||||
def part_1(program):
|
||||
state = dict(zip(range(len(program)), program))
|
||||
state[1] = 12
|
||||
state[2] = 2
|
||||
|
||||
for i in range(0, len(state), 4):
|
||||
opcode, *args = list(state.values())[i : i + 4]
|
||||
if opcode == 1:
|
||||
a, b, p = args
|
||||
state[p] = state[a] + state[b]
|
||||
if opcode == 2:
|
||||
a, b, p = args
|
||||
state[p] = state[a] * state[b]
|
||||
if opcode == 99:
|
||||
break
|
||||
state, _ = execute(program, noun=12, verb=2)
|
||||
return state[0]
|
||||
|
||||
|
||||
@answer(2, "100 * noun + verb = {} for output 19690720")
|
||||
@answer(2, "[intcode-0.1.1] 100 * noun + verb = {} for output 19690720")
|
||||
def part_2(program, noun=76, verb=21):
|
||||
state = dict(zip(range(len(program)), program))
|
||||
state[1] = noun
|
||||
state[2] = verb
|
||||
|
||||
for i in range(0, len(state), 4):
|
||||
opcode, *args = list(state.values())[i : i + 4]
|
||||
if opcode == 1:
|
||||
a, b, p = args
|
||||
state[p] = state[a] + state[b]
|
||||
if opcode == 2:
|
||||
a, b, p = args
|
||||
state[p] = state[a] * state[b]
|
||||
if opcode == 99:
|
||||
break
|
||||
state, _ = execute(program, noun, verb)
|
||||
if state[0] == 19690720:
|
||||
return 100 * noun + verb
|
||||
return state[0]
|
||||
|
|
|
|||
29
2019-python/output/day_05.py
Normal file
29
2019-python/output/day_05.py
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
from output import answer, puzzleinput
|
||||
|
||||
from output.intcode_computer import execute
|
||||
|
||||
n = 5
|
||||
title = "Sunny with a Chance of Asteroids"
|
||||
|
||||
|
||||
@puzzleinput(n)
|
||||
def parse_input(data):
|
||||
return list(map(int, data.split(",")))
|
||||
|
||||
|
||||
@answer(1, "[intcode-0.2.0] Program diagnostic code, ID 1: {}")
|
||||
def part_1(program):
|
||||
_, stdout = execute(program, stdin=1)
|
||||
return max(stdout)
|
||||
|
||||
|
||||
@answer(2, "[intcode-0.2.1] Program diagnostic code, ID 5: {}")
|
||||
def part_2(program):
|
||||
_, stdout = execute(program, stdin=5)
|
||||
return stdout[0]
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
parsed = parse_input()
|
||||
part_1(parsed)
|
||||
part_2(parsed)
|
||||
146
2019-python/output/intcode_computer.py
Normal file
146
2019-python/output/intcode_computer.py
Normal file
|
|
@ -0,0 +1,146 @@
|
|||
from collections import defaultdict
|
||||
|
||||
|
||||
def execute(program, noun=None, verb=None, stdin=0, debug=False):
|
||||
"""
|
||||
intcode computer, AoC 2019
|
||||
|
||||
Changelog
|
||||
=========
|
||||
|
||||
0.2.1
|
||||
-----
|
||||
|
||||
Patch release (day 5 part 2).
|
||||
|
||||
- Add operation 5: set instruction pointer to value at parameter 2 position, based on value at parameter 1 position
|
||||
- Add operation 6: set instruction pointer to value at parameter 2 position, based on value at parameter 1 position
|
||||
- Add operation 7: compares values in parameter 1 position and parameter 2 position, stores at parameter 3 position
|
||||
- Add operation 8: compares values in parameter 1 position and parameter 2 position, stores at parameter 3 position
|
||||
|
||||
0.2.0
|
||||
-----
|
||||
|
||||
Minor release (day 5 part 1).
|
||||
|
||||
- Support immediate parameter mode
|
||||
- Add stdin argument
|
||||
- Make arguments optional: noun, verb
|
||||
- Capture and return stdout
|
||||
- Add operation 3: store stdin to parameter 1 position
|
||||
- Add operation 4: output value at parameter 1 position to stdout
|
||||
|
||||
0.1.1
|
||||
-----
|
||||
|
||||
Patch release (day 2 part 2).
|
||||
|
||||
- Remove initial modification 1=12, 2=2
|
||||
- Add noun argument, stored at pos 1 (default value: 12)
|
||||
- Add verb argument, stored at pos 2 (default value: 2)
|
||||
|
||||
0.1.0
|
||||
-----
|
||||
|
||||
Initial version (day 2 part 1).
|
||||
|
||||
- Support positional parameter mode
|
||||
- Add operation 1: adds parameter 1 to parameter 2, store to parameter 3 position
|
||||
- Add operation 2: multiply parameter 1 with parameter 2, store to parameter 3 position
|
||||
"""
|
||||
state = dict(zip(range(len(program)), program))
|
||||
if noun:
|
||||
state[1] = noun
|
||||
if verb:
|
||||
state[2] = verb
|
||||
n = 0
|
||||
c = 0
|
||||
stdout = []
|
||||
|
||||
while True:
|
||||
instruction = state[n]
|
||||
opcode = instruction % 100
|
||||
modes = str(instruction // 100 % 100).zfill(2)
|
||||
if opcode == 1:
|
||||
a = state[n + 1]
|
||||
b = state[n + 2]
|
||||
p = state[n + 3]
|
||||
x = a if modes[1] == "1" else state[a]
|
||||
y = b if modes[0] == "1" else state[b]
|
||||
state[p] = x + y
|
||||
n += 4
|
||||
if debug:
|
||||
print(f"{n}:{opcode} | {x} + {y} to {p}")
|
||||
if opcode == 2:
|
||||
a = state[n + 1]
|
||||
b = state[n + 2]
|
||||
p = state[n + 3]
|
||||
x = a if modes[1] == "1" else state[a]
|
||||
y = b if modes[0] == "1" else state[b]
|
||||
state[p] = x * y
|
||||
n += 4
|
||||
if debug:
|
||||
print(f"{n}:{opcode} | {x} * {y} to {p}")
|
||||
if opcode == 3:
|
||||
p = state[n + 1]
|
||||
state[p] = stdin
|
||||
n += 2
|
||||
if debug:
|
||||
print(f"{n}:{opcode} | {i} to {p}")
|
||||
if opcode == 4:
|
||||
a = state[n + 1]
|
||||
x = a if modes[1] == "1" else state[a]
|
||||
n += 2
|
||||
stdout.append(x)
|
||||
if debug:
|
||||
print(f"{n}:{opcode} | {stdout}")
|
||||
if opcode == 5:
|
||||
a = state[n + 1]
|
||||
b = state[n + 2]
|
||||
x = a if modes[1] == "1" else state[a]
|
||||
y = b if modes[0] == "1" else state[b]
|
||||
if x != 0:
|
||||
n = y
|
||||
else:
|
||||
n += 3
|
||||
if debug:
|
||||
print(f"{n}:{opcode} | {n}")
|
||||
if opcode == 6:
|
||||
a = state[n + 1]
|
||||
b = state[n + 2]
|
||||
x = a if modes[1] == "1" else state[a]
|
||||
y = b if modes[0] == "1" else state[b]
|
||||
if x == 0:
|
||||
n = y
|
||||
else:
|
||||
n += 3
|
||||
if debug:
|
||||
print(f"{n}:{opcode} | {n}")
|
||||
if opcode == 7:
|
||||
a = state[n + 1]
|
||||
b = state[n + 2]
|
||||
p = state[n + 3]
|
||||
x = a if modes[1] == "1" else state[a]
|
||||
y = b if modes[0] == "1" else state[b]
|
||||
state[p] = int(x < y)
|
||||
n += 4
|
||||
if debug:
|
||||
print(f"{n}:{opcode} | {x}")
|
||||
if opcode == 8:
|
||||
a = state[n + 1]
|
||||
b = state[n + 2]
|
||||
p = state[n + 3]
|
||||
x = a if modes[1] == "1" else state[a]
|
||||
y = b if modes[0] == "1" else state[b]
|
||||
state[p] = int(x == y)
|
||||
n += 4
|
||||
if debug:
|
||||
print(f"{n}:{opcode} | {x}")
|
||||
if opcode == 99:
|
||||
break
|
||||
c += 1
|
||||
if debug and c % 1000 == 0:
|
||||
print(f"{c} instructions done, current pos: {n}")
|
||||
# if c == 3:
|
||||
# break
|
||||
return state, stdout
|
||||
Loading…
Add table
Reference in a new issue