2019, take 2 #2
4 changed files with 158 additions and 45 deletions
|
|
@ -1,7 +1,7 @@
|
||||||
from output import answer, puzzleinput
|
from output import answer, puzzleinput
|
||||||
from collections import defaultdict
|
from collections import defaultdict
|
||||||
|
|
||||||
from output.intcode_computer import execute
|
from output.intcode_computer import execute, parse
|
||||||
|
|
||||||
n = 2
|
n = 2
|
||||||
title = "1202 Program Alarm"
|
title = "1202 Program Alarm"
|
||||||
|
|
@ -9,18 +9,18 @@ title = "1202 Program Alarm"
|
||||||
|
|
||||||
@puzzleinput(n)
|
@puzzleinput(n)
|
||||||
def parse_input(data):
|
def parse_input(data):
|
||||||
return list(map(int, data.split(",")))
|
return parse(data)
|
||||||
|
|
||||||
|
|
||||||
@answer(1, "[intcode-0.1.0] 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):
|
def part_1(program):
|
||||||
state, _ = execute(program, noun=12, verb=2)
|
_code, state, *_unused = execute(program, noun=12, verb=2)
|
||||||
return state[0]
|
return state[0]
|
||||||
|
|
||||||
|
|
||||||
@answer(2, "[intcode-0.1.1] 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):
|
def part_2(program, noun=76, verb=21):
|
||||||
state, _ = execute(program, noun, verb)
|
_code, state, *_unused = execute(program, noun, verb)
|
||||||
if state[0] == 19690720:
|
if state[0] == 19690720:
|
||||||
return 100 * noun + verb
|
return 100 * noun + verb
|
||||||
return state[0]
|
return state[0]
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
from output import answer, puzzleinput
|
from output import answer, puzzleinput
|
||||||
|
|
||||||
from output.intcode_computer import execute
|
from output.intcode_computer import execute, parse
|
||||||
|
|
||||||
n = 5
|
n = 5
|
||||||
title = "Sunny with a Chance of Asteroids"
|
title = "Sunny with a Chance of Asteroids"
|
||||||
|
|
@ -8,18 +8,18 @@ title = "Sunny with a Chance of Asteroids"
|
||||||
|
|
||||||
@puzzleinput(n)
|
@puzzleinput(n)
|
||||||
def parse_input(data):
|
def parse_input(data):
|
||||||
return list(map(int, data.split(",")))
|
return parse(data)
|
||||||
|
|
||||||
|
|
||||||
@answer(1, "[intcode-0.2.0] Program diagnostic code, ID 1: {}")
|
@answer(1, "[intcode-0.2.0] Program diagnostic code, ID 1: {}")
|
||||||
def part_1(program):
|
def part_1(program):
|
||||||
_, stdout = execute(program, stdin=1)
|
_code, _state, _cursorpos, stdout = execute(program, stdin=1)
|
||||||
return max(stdout)
|
return max(stdout)
|
||||||
|
|
||||||
|
|
||||||
@answer(2, "[intcode-0.2.1] Program diagnostic code, ID 5: {}")
|
@answer(2, "[intcode-0.2.1] Program diagnostic code, ID 5: {}")
|
||||||
def part_2(program):
|
def part_2(program):
|
||||||
_, stdout = execute(program, stdin=5)
|
_code, _state, _cursorpos, stdout = execute(program, stdin=5)
|
||||||
return stdout[0]
|
return stdout[0]
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
65
2019-python/output/day_07.py
Normal file
65
2019-python/output/day_07.py
Normal file
|
|
@ -0,0 +1,65 @@
|
||||||
|
from collections import defaultdict
|
||||||
|
from itertools import permutations
|
||||||
|
|
||||||
|
from output import answer, puzzleinput
|
||||||
|
from output.intcode_computer import execute, parse
|
||||||
|
|
||||||
|
n = 7
|
||||||
|
title = "Amplification Circuit"
|
||||||
|
|
||||||
|
|
||||||
|
@puzzleinput(n)
|
||||||
|
def parse_input(data):
|
||||||
|
return parse(data)
|
||||||
|
|
||||||
|
|
||||||
|
@answer(
|
||||||
|
1,
|
||||||
|
"[intcode 0.3.0] Given the phase settings [0, 3, 1, 2, 4], the highest achievable signal to the thruster is {}",
|
||||||
|
)
|
||||||
|
def part_1(program):
|
||||||
|
thruster_signals = []
|
||||||
|
for settings in map(list, permutations(range(5))):
|
||||||
|
o = 0
|
||||||
|
for ps in settings:
|
||||||
|
_code, _state, _n, so = execute(program, stdin=[ps, o])
|
||||||
|
o = so.pop(0)
|
||||||
|
thruster_signals.append(o)
|
||||||
|
return max(thruster_signals)
|
||||||
|
|
||||||
|
|
||||||
|
@answer(
|
||||||
|
2,
|
||||||
|
"[intcode 0.3.0] Given the phase settings [7, 8, 5, 9, 6] and creating feedback loop, the highest achievable signal to the thruster is {}",
|
||||||
|
)
|
||||||
|
def part_2(program):
|
||||||
|
thruster_signals = []
|
||||||
|
for settings in map(list, permutations(range(5, 10))):
|
||||||
|
o = [0]
|
||||||
|
finished = set()
|
||||||
|
paused = defaultdict(tuple)
|
||||||
|
while len(finished) < 5:
|
||||||
|
for amp, ps in enumerate(settings):
|
||||||
|
if paused[amp]:
|
||||||
|
program, resume_at = paused[amp]
|
||||||
|
del paused[amp]
|
||||||
|
code, state, n, so = execute(program, stdin=o, n=resume_at)
|
||||||
|
else:
|
||||||
|
code, state, n, so = execute(program, stdin=[ps, *o])
|
||||||
|
if code == 3:
|
||||||
|
paused[amp] = (
|
||||||
|
list(state.values()),
|
||||||
|
n,
|
||||||
|
)
|
||||||
|
o = so
|
||||||
|
if code == 99:
|
||||||
|
finished.add(amp)
|
||||||
|
o = so
|
||||||
|
thruster_signals.append(o[-1])
|
||||||
|
return max(thruster_signals)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
parsed = parse_input()
|
||||||
|
part_1(parsed)
|
||||||
|
part_2(parsed)
|
||||||
|
|
@ -1,61 +1,99 @@
|
||||||
from collections import defaultdict
|
from collections import defaultdict
|
||||||
|
|
||||||
|
|
||||||
def execute(program, noun=None, verb=None, stdin=0, debug=False):
|
"""
|
||||||
"""
|
intcode computer, AoC 2019
|
||||||
intcode computer, AoC 2019
|
|
||||||
|
|
||||||
Changelog
|
Changelog
|
||||||
=========
|
=========
|
||||||
|
|
||||||
0.2.1
|
0.3.0
|
||||||
-----
|
-----
|
||||||
|
|
||||||
Patch release (day 5 part 2).
|
Minor release (day 7 part 1-2).
|
||||||
|
|
||||||
- Add operation 5: set instruction pointer to value at parameter 2 position, based on value at parameter 1 position
|
BREAKING CHANGE: execute() now returns 4 values.
|
||||||
- Add operation 6: set instruction pointer to value at parameter 2 position, based on value at parameter 1 position
|
- now: exit code, state at halt, instruction position at halt, and captured stdout.
|
||||||
- Add operation 7: compares values in parameter 1 position and parameter 2 position, stores at parameter 3 position
|
- before: final state, and captured stdout
|
||||||
- Add operation 8: compares values in parameter 1 position and parameter 2 position, stores at parameter 3 position
|
|
||||||
|
|
||||||
0.2.0
|
Changes:
|
||||||
-----
|
|
||||||
|
|
||||||
Minor release (day 5 part 1).
|
- Add support for a sequence of stdins
|
||||||
|
- Add interactive param to ask for manual (interactive) input on input opcode
|
||||||
|
- Add verbose param to show more output in interactive input mode
|
||||||
|
- Will now halt with code 3 (input) when input is required, stdin is empty and interactive input mode is not enabled
|
||||||
|
|
||||||
- Support immediate parameter mode
|
0.2.1
|
||||||
- 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 5 part 2).
|
||||||
-----
|
|
||||||
|
|
||||||
Patch release (day 2 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
|
||||||
|
|
||||||
- Remove initial modification 1=12, 2=2
|
0.2.0
|
||||||
- Add noun argument, stored at pos 1 (default value: 12)
|
-----
|
||||||
- Add verb argument, stored at pos 2 (default value: 2)
|
|
||||||
|
|
||||||
0.1.0
|
Minor release (day 5 part 1).
|
||||||
-----
|
|
||||||
|
|
||||||
Initial version (day 2 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
|
||||||
|
|
||||||
- Support positional parameter mode
|
0.1.1
|
||||||
- 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
|
|
||||||
"""
|
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
|
||||||
|
"""
|
||||||
|
v = "0.2.3"
|
||||||
|
|
||||||
|
|
||||||
|
def parse(data):
|
||||||
|
return list(map(int, data.split(",")))
|
||||||
|
|
||||||
|
|
||||||
|
def execute(
|
||||||
|
program,
|
||||||
|
noun=None,
|
||||||
|
verb=None,
|
||||||
|
stdin=[],
|
||||||
|
debug=False,
|
||||||
|
interactive=False,
|
||||||
|
verbose=False,
|
||||||
|
n=0,
|
||||||
|
):
|
||||||
|
if verbose:
|
||||||
|
title = f"intcode computer, version {v}"
|
||||||
|
print("".join("=" for _ in title))
|
||||||
|
print(title)
|
||||||
|
print("".join("=" for _ in title))
|
||||||
state = dict(zip(range(len(program)), program))
|
state = dict(zip(range(len(program)), program))
|
||||||
if noun:
|
if noun:
|
||||||
state[1] = noun
|
state[1] = noun
|
||||||
if verb:
|
if verb:
|
||||||
state[2] = verb
|
state[2] = verb
|
||||||
n = 0
|
|
||||||
c = 0
|
c = 0
|
||||||
stdout = []
|
stdout = []
|
||||||
|
if not isinstance(stdin, list):
|
||||||
|
stdin = [stdin]
|
||||||
|
|
||||||
while True:
|
while True:
|
||||||
instruction = state[n]
|
instruction = state[n]
|
||||||
|
|
@ -83,7 +121,13 @@ def execute(program, noun=None, verb=None, stdin=0, debug=False):
|
||||||
print(f"{n}:{opcode} | {x} * {y} to {p}")
|
print(f"{n}:{opcode} | {x} * {y} to {p}")
|
||||||
if opcode == 3:
|
if opcode == 3:
|
||||||
p = state[n + 1]
|
p = state[n + 1]
|
||||||
state[p] = stdin
|
if stdin:
|
||||||
|
state[p] = stdin.pop(0)
|
||||||
|
else:
|
||||||
|
if interactive:
|
||||||
|
state[p] = int(input("> "))
|
||||||
|
else:
|
||||||
|
return 3, state, n, stdout
|
||||||
n += 2
|
n += 2
|
||||||
if debug:
|
if debug:
|
||||||
print(f"{n}:{opcode} | {i} to {p}")
|
print(f"{n}:{opcode} | {i} to {p}")
|
||||||
|
|
@ -92,6 +136,8 @@ def execute(program, noun=None, verb=None, stdin=0, debug=False):
|
||||||
x = a if modes[1] == "1" else state[a]
|
x = a if modes[1] == "1" else state[a]
|
||||||
n += 2
|
n += 2
|
||||||
stdout.append(x)
|
stdout.append(x)
|
||||||
|
if verbose:
|
||||||
|
print(x)
|
||||||
if debug:
|
if debug:
|
||||||
print(f"{n}:{opcode} | {stdout}")
|
print(f"{n}:{opcode} | {stdout}")
|
||||||
if opcode == 5:
|
if opcode == 5:
|
||||||
|
|
@ -143,4 +189,6 @@ def execute(program, noun=None, verb=None, stdin=0, debug=False):
|
||||||
print(f"{c} instructions done, current pos: {n}")
|
print(f"{c} instructions done, current pos: {n}")
|
||||||
# if c == 3:
|
# if c == 3:
|
||||||
# break
|
# break
|
||||||
return state, stdout
|
if verbose:
|
||||||
|
title = f"intcode computer received SIGTERM"
|
||||||
|
return 99, state, n, stdout
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue