Compare commits

...

3 Commits

Author SHA1 Message Date
Tibor Bizjak 95fce120ce Refactored with Interpreter.pipe_from 2023-03-14 12:45:17 +01:00
Tibor Bizjak bdb48f0320 Added memoize to lib 2023-03-14 12:44:57 +01:00
Tibor Bizjak 8b0cb8d9d7 Added pipes to intcode 2023-03-14 12:44:43 +01:00
3 changed files with 50 additions and 19 deletions

View File

@ -1,49 +1,52 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
from intcode import Interpreter, makeIO, Singleton, Halted from intcode import Interpreter, SingletonIO
from itertools import permutations from itertools import permutations
from lib import memoize
stack_size = 5 stack_size = 5
fst_amp_input = 0 fst_amp_input = 0
IO = makeIO(list, Singleton)
def preproc(puzzle_input): def preproc(puzzle_input):
program = list(map(int, puzzle_input.split(','))) program = list(map(int, puzzle_input.split(',')))
amp = lambda : Interpreter(program, IO) def make_amp(phase):
return amp amp = Interpreter(program, SingletonIO)
amp.eval(phase)
return amp
return make_amp
def partI(amp): def partI(make_amp):
@memoize
def run_amp(phase, amp_in):
amp = make_amp(phase)
return amp.run(amp_in)
phase_range = range(stack_size) phase_range = range(stack_size)
best = 0 best = 0
for perm in permutations(phase_range): for perm in permutations(phase_range):
amp_in = fst_amp_input amp_in = fst_amp_input
for phase in perm: for phase in perm:
amp_in = amp().run([phase, amp_in]) amp_in = run_amp(phase, amp_in)
best = max(amp_in, best) best = max(amp_in, best)
return best return best
def partII(amp): def partII(make_amp):
phase_range = range(5, 10) phase_range = range(5, 10)
best = 0 best = 0
for perm in permutations(phase_range): for perm in permutations(phase_range):
amps = [amp() for _ in range(stack_size)] amps = list(map(make_amp, perm))
for p, a in zip(perm, amps): for prev, amp in zip(amps, amps[1:]):
a.eval([p]) amp.pipe_from(prev)
amp_in = fst_amp_input amp.write(fst_amp_input)
while True: for amp_in in amp:
try: amp.write(amp_in)
for a in amps:
amp_in = a.eval([amp_in])
except Halted:
break
best = max(amp_in, best) best = max(amp_in, best)
return best return best
from main import Tests from main import Tests

View File

@ -9,6 +9,9 @@ class WaitForInput(Exception):
class Halted(Exception): class Halted(Exception):
pass pass
class PipeError(Exception):
pass
class defaultlist(list): class defaultlist(list):
"""Default list class. Allows writing and reading out of bounds.""" """Default list class. Allows writing and reading out of bounds."""
def __init__(self, lst, val_factory): def __init__(self, lst, val_factory):
@ -207,6 +210,21 @@ class Interpreter(object):
pass pass
return self.IO.flush() return self.IO.flush()
def pipe_from(self, other):
class Output(Exception):
pass
def raise_output(o):
raise Output(o)
other.comp.out_f = raise_output
def get_input():
try:
other.run()
raise PipeError
except Output as o:
return int(str(o))
self.comp.in_f = get_input
self.IO.write = other.IO.write
def copy(self): def copy(self):
memory = self.memory.copy() memory = self.memory.copy()

10
lib.py
View File

@ -1,5 +1,15 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
def memoize(f):
cache = dict()
def memf(*args):
key = tuple(args)
if key not in cache:
cache[key] = f(*args)
return cache[key]
return memf
class Graph(dict): class Graph(dict):
nodes = dict.keys nodes = dict.keys