diff --git a/2019/aoc2019/day25.py b/2019/aoc2019/day25.py index 9cebf1f..3aff0e2 100644 --- a/2019/aoc2019/day25.py +++ b/2019/aoc2019/day25.py @@ -1,9 +1,15 @@ -from typing import TextIO +import itertools +from typing import TextIO, Iterable, Tuple, Set from aoc2019.intcode import read_program, Computer -def print_output(computer: Computer): +def powerset(iterable: Iterable) -> Iterable[Tuple]: + s = list(iterable) + return itertools.chain.from_iterable(itertools.combinations(s, r) for r in range(len(s) + 1)) + + +def print_output(computer: Computer) -> str: output = "" while len(computer.output): @@ -11,6 +17,8 @@ def print_output(computer: Computer): print(output, end='') + return output + def load_save(save, computer: Computer): computer.pointer, computer.relative_base, computer.program = save @@ -20,10 +28,40 @@ def create_save(computer: Computer): return computer.pointer, computer.relative_base, computer.program.copy() +def send_command(computer: Computer, command: str): + for c in command: + computer.send_input(ord(c)) + + computer.send_input(10) # manually send newline + + +def force(computer: Computer, direction: str, items: Set[str]): + for combination in powerset(items): + # Drop everything, disregard what's on the ground + for item in items: + send_command(computer, f"drop {item}") + + # Now pick up whatever we want to try + for item in combination: + send_command(computer, f"take {item}") + + send_command(computer, direction) + + try: + computer.run() + print_output(computer) + return True + except IndexError: + print_output(computer) + + return False + + def part1(data: TextIO): print("This day must use a file as input as it requires the stdin for other things.") computer = Computer(read_program(data)) + items = set() saves = {} @@ -42,14 +80,35 @@ def part1(data: TextIO): saves['auto'] = create_save(computer) - command = input().strip() + try: + command = input().strip() + except EOFError: + return "exiting" if command == "exit": - return - # TODO: add manual save states. + return "exiting" + elif command == "items": + print(items) + continue + elif command.startswith("save "): + save_name = command.removeprefix("save ") + saves[save_name] = create_save(computer) + print(f"Saved game state as {save_name}") + continue + elif command.startswith("load "): + save_name = command.removeprefix("load ") + load_save(saves[save_name], computer) + print(f"Loaded game state from {save_name}") + continue + elif command.startswith("take "): + items.add(command.removeprefix("take ")) + elif command.startswith("drop "): + items.remove(command.removeprefix("drop ")) + elif command.startswith("force "): + direction = command.removeprefix("force ") + if force(computer, direction, items): + return + continue - for c in command: - computer.send_input(ord(c)) - - computer.send_input(10) # manually send newline + send_command(computer, command)