mirror of
https://github.com/thib8956/advent-of-code.git
synced 2025-08-23 16:01:59 +00:00
2019 day7 part 2
This commit is contained in:
@@ -5,18 +5,23 @@ from pathlib import Path
|
|||||||
# installed module https://stackoverflow.com/a/50194143
|
# installed module https://stackoverflow.com/a/50194143
|
||||||
sys.path.append(str(Path(__file__).absolute().parent.parent / "intcode"))
|
sys.path.append(str(Path(__file__).absolute().parent.parent / "intcode"))
|
||||||
|
|
||||||
import itertools
|
from itertools import cycle, permutations
|
||||||
from intcode import interpret_intcode
|
from intcode import interpret_intcode, Interpreter
|
||||||
|
|
||||||
|
|
||||||
def main(inp):
|
def main(inp):
|
||||||
mem = list(map(int, inp.readline().rstrip().split(",")))
|
mem = list(map(int, inp.readline().rstrip().split(",")))
|
||||||
max_ret = 0
|
max_ret = 0
|
||||||
for seq in itertools.permutations([0, 1, 2, 3, 4], 5):
|
for seq in permutations([0, 1, 2, 3, 4], 5):
|
||||||
ret = amplifiers(mem, list(seq))
|
ret = amplifiers(mem, list(seq))
|
||||||
#print(ret)
|
|
||||||
max_ret = max(ret[0], max_ret)
|
max_ret = max(ret[0], max_ret)
|
||||||
print(max_ret)
|
print("Part 1: ", max_ret)
|
||||||
|
|
||||||
|
max_ret = 0
|
||||||
|
for seq in permutations((5, 6, 7, 8, 9)):
|
||||||
|
ret = part2(mem, list(seq))
|
||||||
|
max_ret = max(max_ret, ret)
|
||||||
|
print("Part 2: ", max_ret)
|
||||||
|
|
||||||
|
|
||||||
def amplifiers(program, sequence):
|
def amplifiers(program, sequence):
|
||||||
@@ -27,27 +32,65 @@ def amplifiers(program, sequence):
|
|||||||
ret = interpret_intcode(program[::], [sequence.pop(0), ret.pop()])
|
ret = interpret_intcode(program[::], [sequence.pop(0), ret.pop()])
|
||||||
return ret
|
return ret
|
||||||
|
|
||||||
|
|
||||||
|
def part2(program, sequence):
|
||||||
|
amplifiers = [Interpreter(program[::], [sequence.pop(0)]) for _ in range(5)]
|
||||||
|
it = cycle(enumerate(amplifiers))
|
||||||
|
|
||||||
|
id_, amp = next(it)
|
||||||
|
inp = 0
|
||||||
|
max_signal = 0
|
||||||
|
while True:
|
||||||
|
max_signal = max(max_signal, inp)
|
||||||
|
amp.stdin.append(inp)
|
||||||
|
amp.interpret()
|
||||||
|
out = amp.stdout
|
||||||
|
if amp.halted:
|
||||||
|
break
|
||||||
|
next_id, next_amp = next(it)
|
||||||
|
inp = out.pop(0)
|
||||||
|
amp = next_amp
|
||||||
|
id_= next_id
|
||||||
|
return max_signal
|
||||||
|
|
||||||
|
|
||||||
def tests():
|
def tests():
|
||||||
program = [3, 15, 3, 16, 1002, 16, 10, 16, 1, 16, 15, 15, 4, 15, 99, 0, 0]
|
program = [3, 15, 3, 16, 1002, 16, 10, 16, 1, 16, 15, 15, 4, 15, 99, 0, 0]
|
||||||
sequence = [4, 3, 2, 1, 0]
|
sequence = [4, 3, 2, 1, 0]
|
||||||
res = amplifiers(program, sequence)
|
res = amplifiers(program, sequence)
|
||||||
assert res == [43210]
|
assert res == [43210]
|
||||||
|
|
||||||
program = [3,23,3,24,1002,24,10,24,1002,23,-1,23, 101,5,23,23,1,24,23,23,4,23,99,0,0]
|
program = [3,23,3,24,1002,24,10,24,1002,23,-1,23,
|
||||||
|
101,5,23,23,1,24,23,23,4,23,99,0,0]
|
||||||
sequence = [0,1,2,3,4]
|
sequence = [0,1,2,3,4]
|
||||||
res = amplifiers(program, sequence)
|
res = amplifiers(program, sequence)
|
||||||
assert res == [54321]
|
assert res == [54321]
|
||||||
|
|
||||||
|
|
||||||
program = [3,31,3,32,1002,32,10,32,1001,31,-2,31,1007,31,0,33, 1002,33,7,33,1,33,31,31,1,32,31,31,4,31,99,0,0,0]
|
program = [3,31,3,32,1002,32,10,32,1001,31,-2,31,1007,31,0,33,
|
||||||
|
1002,33,7,33,1,33,31,31,1,32,31,31,4,31,99,0,0,0]
|
||||||
sequence = [1,0,4,3,2]
|
sequence = [1,0,4,3,2]
|
||||||
res = amplifiers(program, sequence)
|
res = amplifiers(program, sequence)
|
||||||
assert res == [65210]
|
assert res == [65210]
|
||||||
|
|
||||||
print("All tests passed")
|
|
||||||
|
def tests2():
|
||||||
|
program = [3,26,1001,26,-4,26,3,27,1002,27,2,27,1,27,26,
|
||||||
|
27,4,27,1001,28,-1,28,1005,28,6,99,0,0,5]
|
||||||
|
sequence = [9,8,7,6,5]
|
||||||
|
assert part2(program, sequence) == 139629729
|
||||||
|
|
||||||
|
|
||||||
|
program = [3,52,1001,52,-5,52,3,53,1,52,56,54,1007,54,5,55,1005,55,26,1001,54,
|
||||||
|
-5,54,1105,1,12,1,53,54,53,1008,54,0,55,1001,55,1,55,2,53,55,53,4,
|
||||||
|
53,1001,56,-1,56,1005,56,6,99,0,0,0,0,10]
|
||||||
|
sequence = [9,7,8,5,6]
|
||||||
|
assert part2(program, sequence) == 18216
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
import fileinput
|
import fileinput
|
||||||
main(fileinput.input())
|
|
||||||
tests()
|
tests()
|
||||||
|
tests2()
|
||||||
|
main(fileinput.input())
|
||||||
|
|
||||||
|
@@ -3,7 +3,7 @@ from collections import namedtuple
|
|||||||
from enum import Enum
|
from enum import Enum
|
||||||
import logging
|
import logging
|
||||||
|
|
||||||
logging.basicConfig(format="%(levelname)s:%(message)s", level=logging.DEBUG)
|
logging.basicConfig(format="%(levelname)s:%(message)s", level=logging.WARN)
|
||||||
|
|
||||||
|
|
||||||
def get_nth_digit(n, number):
|
def get_nth_digit(n, number):
|
||||||
@@ -40,6 +40,7 @@ class Instruction:
|
|||||||
self.handler = getattr(self, self.handler_name, self.handle_termination)
|
self.handler = getattr(self, self.handler_name, self.handle_termination)
|
||||||
self.input = None
|
self.input = None
|
||||||
self.output = None
|
self.output = None
|
||||||
|
self.halted = False
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return f"[{self.opcode}] Instruction({self.operation}, {self.modes})"
|
return f"[{self.opcode}] Instruction({self.operation}, {self.modes})"
|
||||||
@@ -102,6 +103,7 @@ class Instruction:
|
|||||||
|
|
||||||
def handle_termination(self, program, ip):
|
def handle_termination(self, program, ip):
|
||||||
logging.debug("HALT")
|
logging.debug("HALT")
|
||||||
|
self.halted = True
|
||||||
return ip
|
return ip
|
||||||
|
|
||||||
def _get_param(self, program, ip, i=0):
|
def _get_param(self, program, ip, i=0):
|
||||||
@@ -117,16 +119,38 @@ class Instruction:
|
|||||||
return first, second
|
return first, second
|
||||||
|
|
||||||
|
|
||||||
def interpret_intcode(program, stdin=[]):
|
class Interpreter:
|
||||||
ip = 0
|
def __init__(self, program, stdin=[]):
|
||||||
out = []
|
self.ip = 0
|
||||||
while program[ip] != 99:
|
self.stdin = stdin
|
||||||
opcode = program[ip]
|
self.stdout = []
|
||||||
instruction = Instruction(opcode)
|
self.program = program
|
||||||
if instruction.operation == Operation.INPUT:
|
self.halted = False
|
||||||
instruction.input=stdin.pop(0)
|
|
||||||
ip = instruction.handle(program, ip)
|
def __repr__(self):
|
||||||
if instruction.output is not None:
|
return f"Interpreter(ip={self.ip}, {self.stdin}, {self.stdout}, {self.halted})"
|
||||||
out.append(instruction.output)
|
|
||||||
return out
|
def next_instruction(self):
|
||||||
|
instruction = Instruction(self.program[self.ip])
|
||||||
|
if instruction.operation == Operation.INPUT:
|
||||||
|
instruction.input = self.stdin.pop(0)
|
||||||
|
self.ip = instruction.handle(self.program, self.ip)
|
||||||
|
if instruction.output is not None:
|
||||||
|
self.stdout.append(instruction.output)
|
||||||
|
elif instruction.halted:
|
||||||
|
self.halted = True
|
||||||
|
return instruction
|
||||||
|
|
||||||
|
def interpret(self, break_on_output=True):
|
||||||
|
while instruction := self.next_instruction():
|
||||||
|
if self.halted:
|
||||||
|
break
|
||||||
|
if break_on_output and instruction.output is not None:
|
||||||
|
break
|
||||||
|
|
||||||
|
|
||||||
|
def interpret_intcode(program, stdin=[]):
|
||||||
|
interpreter = Interpreter(program, stdin)
|
||||||
|
interpreter.interpret(break_on_output=False)
|
||||||
|
return interpreter.stdout
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user