def __init__(self) -> None: with open_fixture("day15") as fp: data = decode(fp.readline()) self.vm = IntcodeVM(data) self.grid = Grid() self.pos = Position(0, 0) self.oxygen_system_pos = Position(0, 0)
def __init__( self, wake_up: bool = False, ): with open_fixture("day17") as fp: data = decode(fp.readline()) self.vm = IntcodeVM(data) if wake_up: self.vm.data[0] = 2
class Droid: def __init__(self) -> None: with open_fixture("day15") as fp: data = decode(fp.readline()) self.vm = IntcodeVM(data) self.grid = Grid() self.pos = Position(0, 0) self.oxygen_system_pos = Position(0, 0) @property def cell(self) -> Cell: return self.grid[self.pos] def move(self, direction: Direction) -> bool: self.vm.io_push(direction.value) while not self.vm.stdout: self.vm.step() status = Status(self.vm.io_pop()) pos = self.pos.move(direction) self.grid.set_status(pos, status) if status.passable: self.pos = pos if status == Status.OXYGENATED: self.oxygen_system_pos = pos return True return False def explore(self) -> bool: # first explore unexplored cells for direction in Direction.all(): npos = self.pos.move(direction) if npos not in self.grid: if self.move(direction): return True # invariant: all neighbors are known # quit if home again if not self.pos: return False # move back towards home options = {} for direction in Direction.all(): npos = self.pos.move(direction) cell = self.grid[npos] if cell.status == Status.OKAY: options[cell.distance] = direction continue assert options best = sorted(options.keys())[0] assert best < self.cell.distance direction = options[best] assert self.move(direction) return True
def __init__(self, data: Data) -> None: self.vm = IntcodeVM(data, trap_input=self._trap_input) self.score = 0 self.frame = 0 self.init_block_count = 0 self.last_good_frame = 0 self.last_good_state = data.copy() self.last_miss_x = 0 self.last_paddle_x = 0 self.failed = False self.moves: Optional[List[int]] = None self.stdscr: Any = None
def collect_all_items(program, item_paths): command_list = [] for path, item in item_paths: if item[0] == "Checkpoint": continue command_list.extend(path) command_list.append(f"take {item}") command_list.extend(OPPOSITES[step] for step in reversed(path)) command_list.extend(next(path for path, item in item_paths if item[0] == "Checkpoint")) for _, item in item_paths: command_list.append(f"drop {item}") vm = IntcodeVM(program, CommandInput(command_list), lambda c: None) vm.run() return vm
def start_nic(program, address, channels): def non_blocking_input(): if not non_blocking_input.address_sent: non_blocking_input.address_sent = True return address if non_blocking_input.this_packet: return non_blocking_input.this_packet.popleft() try: non_blocking_input.this_packet = channels[address].get(timeout=0.1) except Empty: return -1 else: return non_blocking_input.this_packet.popleft() non_blocking_input.address_sent = False non_blocking_input.this_packet = None def route_output(val): route_output.this_packet.append(val) if len(route_output.this_packet) == 3: dest, x, y = route_output.this_packet route_output.this_packet = [] channels[dest].put(deque([x, y])) route_output.this_packet = [] IntcodeVM(program, non_blocking_input, route_output).run()
def run_springscript(script, mode): input = deque(ord(c) for c in script + f"\n{mode}\n") output = deque() IntcodeVM(SPRINGSCRIPT_VM_CODE, input.popleft, output.append).run() if output[-1] > 255: return output.pop() for c in output: sys.stdout.write(chr(c))
def run(initialBlock): vm = IntcodeVM(data) grid = defaultdict(lambda: BLACK) grid[(0, 0)] = initialBlock direction = 'N' x = 0 y = 0 halted = False while not halted: vm.addInput([grid[(x, y)]]) halted = vm.runToBlock() grid[(x, y)] = vm.output[-2] direction = TURNS[direction][vm.output[-1]] dx, dy = DIRECTIONS[direction] x += dx y += dy return grid
class Robot: def __init__(self, program: Data) -> None: self.vm = IntcodeVM(program) self.grid = Grid() self.orientation = Orientation.UP self.position = (0, 0) def step(self) -> bool: # get current color self.vm.io_push(self.grid[self.position].value) # run the program until output is availble while len(self.vm.stdout) < 2: if not self.vm.step(): return False # paint color = Color(self.vm.io_pop()) self.grid[self.position] = color # turn direction = self.vm.io_pop() if direction: self.orientation = self.orientation.turn_right() else: self.orientation = self.orientation.turn_left() # move if self.orientation == Orientation.UP: self.position = (self.position[0], self.position[1] - 1) if self.orientation == Orientation.RIGHT: self.position = (self.position[0] + 1, self.position[1]) if self.orientation == Orientation.DOWN: self.position = (self.position[0], self.position[1] + 1) if self.orientation == Orientation.LEFT: self.position = (self.position[0] - 1, self.position[1]) return not self.vm.halted def run(self) -> None: while self.step(): pass
def run_interactive(program): def input_reader(): if input_reader.last_input: return input_reader.last_input.popleft() for c in input(): input_reader.last_input.append(ord(c)) input_reader.last_input.append(ord("\n")) return input_reader.last_input.popleft() input_reader.last_input = deque() def output(output): sys.stdout.write(chr(output)) IntcodeVM(program, input_reader, output).run()
def thrust(data: Data, phase_sequence: Sequence[int]) -> int: vms = [IntcodeVM(data, [phase]) for phase in phase_sequence] E = vms[len(vms) - 1] v = 0 i = 0 while not E.halted: vm = vms[i] vm.io_push(v) while not vm.halted: vm.step() if vm.stdout: v = vm.io_pop() break i = (i + 1) % len(phase_sequence) return v
def firstVisiblePoint(): for i in range(1, 50): for j in range(1, 50): UserInput.append((i, j)) for spot in UserInput: robot = IntcodeVM(memry.copy()) robot.updateInput([spot[0], spot[1]]) robot.run() if robot.prgOutput == 1: return (spot[0], spot[1])
def runScript(scr): vm = IntcodeVM(prog) inp = [] for line in scr.splitlines(): inp += list(map(ord, line)) inp.append(10) vm.addInput(inp) vm.runToBlock() s = '' ans = 0 for i in vm.output: try: s += chr(i) except ValueError: ans = i return ans, s
def run(data: Data, stdin: Optional[Data] = None) -> Data: vm = IntcodeVM(data, stdin=stdin) vm.run() return vm.stdout
def readGrid(x, y): vm = IntcodeVM(prog) vm.addInput([x, y]) vm.runToBlock() return vm.output[-1]
## Read tries.txt to see me trying all the inputs. Solved today mostly by hand! from intcode import IntcodeVM file = open('input.txt', 'r') memry = [] for line in file: memry = line.split(',') comp = IntcodeVM(memry) while True: comp.run() print(chr(comp.prgOutput), end="")
from intcode import IntcodeVM from collections import defaultdict file = open('input.txt', 'r') for line in file: memry = line.split(',') robot = IntcodeVM(memry) nrOfBlockTiles = 0 while robot.finished == False: robot.run(137) robot.run(137) robot.run(137) tileID = robot.prgOutput if tileID == 2: nrOfBlockTiles += 1 print(nrOfBlockTiles)
from common import * from intcode import IntcodeVM prog = filemap(int, "day9.txt", ',') vm = IntcodeVM(prog) vm.addInput([1]) vm.runToBlock() print(vm.output) vm = IntcodeVM(prog) vm.addInput([2]) vm.runToBlock() print(vm.output)
from common import * from intcode import IntcodeVM data = filemap(int, "day15.txt", ',') grid = defaultdict(lambda: None) x, y = 0, 0 WALL = 0 OPEN = 1 TARGET = 2 vm = IntcodeVM(data) BACKWARDS = {1: 2, 2: 1, 3: 4, 4: 3} def explore(x, y): for direction in range(1, 5): dx, dy = DIRECTIONS[direction] nx = x + dx ny = y + dy if grid[(nx, ny)] is not None: continue vm.addInput([direction]) vm.runToBlock() grid[(nx, ny)] = vm.output[-1] if vm.output[-1] in (OPEN, TARGET):
from intcode import IntcodeVM from collections import defaultdict file = open('input.txt', 'r') for line in file: memry = line.split(',') currentLocation = (0, 0) facing = 0 panels = defaultdict(int) robot = IntcodeVM(memry) panels[currentLocation] = 1 while robot.finished == False: robot.run(panels[currentLocation]) colourToPaint = robot.prgOutput robot.run(panels[currentLocation]) turn = robot.prgOutput panels[currentLocation] = colourToPaint if turn == 0: facing -= 1 if turn == 1: facing += 1 facing = facing % 4 if facing == 0: currentLocation = (currentLocation[0], currentLocation[1] + 1) if facing == 1: currentLocation = (currentLocation[0] + 1, currentLocation[1]) if facing == 2:
from intcode import IntcodeVM from collections import defaultdict file = open('input.txt', 'r') memry = [] computers = [] inputFrom = defaultdict(lambda: []) NATInput = [] for line in file: memry = line.split(',') for i in range(50): comp = IntcodeVM(memry.copy()) comp.updateInput(i) computers.append(comp) while len(NATInput) == 0: for i in range(50): computers[i].run() if computers[i].output: inputFrom[i].append(computers[i].prgOutput) if len(inputFrom[i]) >= 3: who = inputFrom[i].pop(0) xtoSend = inputFrom[i].pop(0) ytoSend = inputFrom[i].pop(0) if who != 255: computers[who].updateInput(xtoSend) computers[who].updateInput(ytoSend) else:
if tile == 4: print("â– ", end="") print("") print("Score:", score) file = open('input.txt', 'r') for line in file: memry = line.split(',') tiles = defaultdict(int) memry[0] = 2 robot = IntcodeVM(memry) score = 0 ballPos = (0, 0) playerPos = (0, 0) playerInput = 0 frameCounter = 0 while robot.finished == False: robot.run(playerInput) xpos = robot.prgOutput robot.run(playerInput) ypos = robot.prgOutput robot.run(playerInput) tileID = robot.prgOutput pos = (xpos, ypos)
from common import * from intcode import IntcodeVM prog = filemap(int, "day17.txt", ',') vm = IntcodeVM(prog) vm.runToBlock() s = '' for i in vm.output: s += chr(i) print(s) dg = s.strip().split('\n') grid = defaultdict(lambda: False) SCAFFOLD = set('#^><v') HEIGHT = len(dg) WIDTH = len(dg[0]) robotPos = None robotDirection = None DIRS = {'^': 'N', 'v': 'S', '>': 'W', '<': 'E'} for y in range(HEIGHT): for x in range(WIDTH): if dg[y][x] in SCAFFOLD: grid[(x, y)] = True if dg[y][x] in '^v<>': robotPos = (x, y) robotDirection = DIRS[dg[y][x]]
def __init__(self, program: Data) -> None: self.vm = IntcodeVM(program) self.grid = Grid() self.orientation = Orientation.UP self.position = (0, 0)
from intcode import IntcodeVM from collections import defaultdict file = open('input.txt', 'r') memry = [] for line in file: memry = line.split(',') robot = IntcodeVM(memry) map = defaultdict(lambda: 46) rows = 0 realColumns = 0 columns = 0 while not robot.finished: robot.run() char = robot.prgOutput if char == 10: rows += 1 columns = 0 else: columns += 1 if columns > realColumns: realColumns = columns map[(rows, columns)] = char columns = realColumns rows -= 2
for j in range(smallesty - 5, biggesty + 5): if (i, j) in special: print("@", end="") elif grid[(i, j)] == -1: print(" ", end="") elif grid[(i, j)] == 0: print(" ", end="") elif grid[(i, j)] == 2: print("@", end="") else: print("▓", end="") print("") grid = defaultdict(lambda: -1) robot = IntcodeVM(memry) startPos = (0, 0) grid[startPos] = 1 rob = startPos OXYGEN = (1234, 1234) facing = 1 while True: robot.run(getLeft()) if robot.prgOutput == 2: #finished rob = positionQueried(getLeft()) facing = getLeft() OXYGEN = rob grid[OXYGEN] = 1 break elif robot.prgOutput == 0:
class ArcadeCabinet: def __init__(self, data: Data) -> None: self.vm = IntcodeVM(data, trap_input=self._trap_input) self.score = 0 self.frame = 0 self.init_block_count = 0 self.last_good_frame = 0 self.last_good_state = data.copy() self.last_miss_x = 0 self.last_paddle_x = 0 self.failed = False self.moves: Optional[List[int]] = None self.stdscr: Any = None def step(self) -> bool: if not self.vm.step(): return False if len(self.vm.stdout) == 3: self._trap_draw_tile() return True def _trap_draw_tile(self) -> None: x = self.vm.io_pop() y = self.vm.io_pop() if x == -1 and y == 0: # update score self.score = self.vm.io_pop() return # paint a tile tile = Tile(self.vm.io_pop()) if tile == Tile.BLOCK: # track count for part 1 self.init_block_count += 1 if tile == Tile.PADDLE: self.last_paddle_x = x if tile == Tile.BALL: # did the ball hit the paddle if y == 20 and x in [ self.last_paddle_x - 1, self.last_paddle_x, self.last_paddle_x + 1, ]: self.last_good_frame = self.frame self.last_good_state = self.vm.data.copy() # did the ball go past the paddle if y == 21: self.failed = True self.last_miss_x = x # update curses window if self.stdscr is None: return self.stdscr.addstr(y, x, str(tile)) def _trap_input(self) -> int: """ Called whenever the vm is starved for input, between each iteration of the program state. """ self.frame += 1 v = 0 # neutral paddle movement if self.moves: v = self.moves[0] self.moves = self.moves[1:] stdscr = self.stdscr if stdscr is None: return v # paint curses window stdscr.addstr(24, 0, f"Score: {self.score} Frame: {self.frame}") stdscr.refresh() sleep(0.01) return v def run(self, stdscr=None, moves: Optional[List[int]] = None) -> bool: # if stdscr: self.stdscr = stdscr self.moves = moves while not self.vm.halted: self.step() return not self.failed
from common import * from intcode import IntcodeVM from itertools import permutations prog = filemap(int, "day7.txt", ',') m = 0 for perm in permutations(range(5)): out = 0 for i in perm: vm = IntcodeVM(prog) vm.addInput([i, out]) vm.runToBlock() out = vm.output[0] m = max(out, m) print(m) m = 0 for perm in permutations(range(5, 10)): vms = [] for i in perm: vm = IntcodeVM(prog) vm.addInput([i]) vms.append(vm) amp = 0 out = 0 while True: vm = vms[amp] vm.addInput([out])
### (!A && D) || (!B && D) || (!C && D && H) from intcode import IntcodeVM file = open('input.txt', 'r') memry = [] for line in file: memry = line.split(',') robot = IntcodeVM(memry) UserInput = [] answer = "NOT A T\nNOT B J\nAND D J\nOR T J\nNOT C T\nAND D T\nAND H T\nOR T J\nRUN\n" for a in answer: UserInput.append(ord(a)) robot.updateInput(UserInput) while robot.finished == False: robot.run() if robot.prgOutput < 255: print(chr(robot.prgOutput), end="") else: print(robot.prgOutput)
from intcode import IntcodeVM file = open('input.txt', 'r') memry = [] for line in file: memry = line.split(',') howBigIsTheScan = 50 UserInput = [] for i in range(howBigIsTheScan): for j in range(howBigIsTheScan): UserInput.append((i, j)) howManyTracks = 0 for spot in UserInput: robot = IntcodeVM(memry.copy()) robot.updateInput([spot[0], spot[1]]) robot.run() howManyTracks += robot.prgOutput print(howManyTracks)