class EmHuPaR: def __init__(self): self.x = 0 self.y = 0 self.dir = 0 # up self.brain = None def load(self, program): self.brain = Intcode() self.brain.load(program) self.brain.exit_on_output = True def run(self, panels): dx = {0: 0, 1: 1, 2: 0, 3: -1} dy = {0: -1, 1: 0, 2: 1, 3: 0} while True: self.brain.set_input(panels[(self.x, self.y)]) self.brain.run() if self.brain.state == "halted": return color = self.brain.get_output() self.brain.run() turn = self.brain.get_output() panels[(self.x, self.y)] = color if turn == 1: self.dir = (self.dir + 1) % 4 else: self.dir = (self.dir + 3) % 4 self.x += dx[self.dir] self.y += dy[self.dir]
class Computer: def __init__(self, controller, input, num): self.controller = controller self.prog = Intcode(input, [num]) self.queue = asyncio.Queue() self.empty = 0 def send(self, x, y): self.queue.put_nowait(x) self.queue.put_nowait(y) async def run(self): while True: try: dest = self.prog.run(True) except NeedsInput: if self.queue.empty(): self.empty += 1 self.controller.update_empty() if self.empty >= 2: self.prog.input.append(await self.queue.get()) self.empty = 0 else: self.prog.input.append(-1) else: self.empty = 0 while not self.queue.empty(): self.prog.input.append(self.queue.get_nowait()) else: if dest is None: return x = self.prog.run(True) y = self.prog.run(True) self.controller.send(dest, x, y) await asyncio.sleep(0)
def problem2(program): tiles = [" ", "#", "o", "^", "*"] screen = [['.'] * 45 for i in range(26)] input, output = [], [] program[0] = 2 cpu = Intcode(program, input, output) bat_pos, ball_pos, score = 0, 0, 0 blocks_remaining = 1 while blocks_remaining > 0: cpu.run() while output: col, row = output.pop(0), output.pop(0) if col == -1 and row == 0: score = output.pop(0) else: tile_type = tiles[output.pop(0)] screen[row][col] = tile_type if tile_type == "*": ball_pos = col if tile_type == "^": bat_pos = col # could just track blocks based on whether # a block is being removed blocks_remaining = count_blocks(screen) if ball_pos > bat_pos: input.append(1) elif ball_pos < bat_pos: input.append(-1) else: input.append(0) for l in screen: print("".join(l)) print(score)
class Arcade: def __init__(self): self.cpu = Intcode() self.screen = {} def load_game(self, code): self.cpu.load(code) def insert_coins(self, n): self.cpu.code[0] = 2 def draw_screen(self): tiles = {0: "░░", 1: "██", 2: "▓▓", 3: "==", 4: "()"} if (-1, 0) in self.screen: score = self.screen[(-1, 0)] else: score = -1 print(f"██ {score:60d} points ██") for row in range(20): for col in range(38): if (col, row) in self.screen: tile = tiles[self.screen[(col, row)]] print(tile, end="") print() def auto_move(self): for x, y in self.screen.keys(): if self.screen[(x, y)] == 3: paddle = x if self.screen[(x, y)] == 4: ball = x if paddle < ball: return "d" elif paddle > ball: return "a" else: return "s" def run(self, automatic): inputs = {"": 0, "a": -1, "s": 0, "d": 1, "j": -1, "k": 0, "l": 1} while self.cpu.state != "halted": self.cpu.run() while len(self.cpu.outputs): if len(self.cpu.outputs) >= 3: x = self.cpu.outputs.popleft() y = self.cpu.outputs.popleft() tile = self.cpu.outputs.popleft() self.screen[(x, y)] = tile else: print( f"ERROR: Encountered a faulty cpu output: {list(self.cpu.outputs)}" ) break if self.cpu.state != "halted": self.draw_screen() if not automatic: inp = input("move: ") else: inp = self.auto_move() self.cpu.add_input(inputs[inp])
def ask_about_position(data, x, y): beam = Intcode() beam.load(data) beam.add_input(x) beam.add_input(y) beam.run() return beam.get_output()
class Game: def __init__(self, input, play=False): self.prog = Intcode(input) if play: self.prog[0] = 2 self.board = np.zeros((0, 0), dtype='u8') self.paddle = np.array([0, 0]) self.ball = np.array([0, 0]) self.score = 0 self.blocks = 0 def step(self): try: while True: x = self.prog.run(True) if x is None: return False y = self.prog.run(True) if x == -1 and y == 0: self.score = self.prog.run(True) else: tile = Tile(self.prog.run(True)) if tile == Tile.PADDLE: self.paddle = np.array([x, y]) elif tile == Tile.BALL: self.ball = np.array([x, y]) if y >= self.board.shape[0] or x >= self.board.shape[1]: self.board.resize( np.maximum(self.board.shape, np.array([y, x]) + 1)) self.board[y, x] = tile.value except NeedsInput: return True finally: self.blocks = np.sum(self.board == Tile.BLOCK.value) def draw_board(self): for line in self.board: print(''.join(str(Tile(tile)) for tile in line)) def move(self, dir): self.prog.input.append(np.sign(dir)) def play(self): prev_blocks = self.blocks prev_score = self.score while self.step(): ## self.draw_board() ## print('Score: {}'.format(self.score)) ## print('Blocks: {}'.format(self.blocks) ## print() if self.blocks != prev_blocks or self.score != prev_score: prev_blocks = self.blocks prev_score = self.score print('Blocks: {}, Score: {}'.format(self.blocks, self.score)) self.move(self.ball[0] - self.paddle[0]) ## self.draw_board() if self.blocks: print('There are still {} blocks left!'.format(self.blocks)) return self.score
def solve(a, x): intc = Intcode(a) intc.input([x]) intc.run() while intc.o == 0: intc.run() print(intc.o)
def part1(data): cpu = Intcode() cpu.load_program(data) cpu.ram[1] = 12 cpu.ram[2] = 2 cpu.run() return cpu.ram[0]
class Cryostasis: def __init__(self, data): self.intcode = Intcode(data) def run(self, inputs='', verbose=True): for input in inputs.split(';'): self.intcode.inputs = [ ord(ch) for ch in list(input.strip()) + ['\n'] ] self.intcode.run() output = ''.join([chr(ch) for ch in self.intcode.outputs]) self.intcode.outputs = [] if verbose: print(output) return output def run_interactive(self): self.intcode.run() while True: inp = input('$ ') print(f"{inp}\n") if inp in ['bye', 'quit']: break output = self.run(inp) if output.find('Analysis complete!') > -1: print(f"password is {re.search('[0-9]+', output).group(0)}") break def collect_all_items(self): cryostatis.run() cryostatis.run('south;take fixed point;north') # fixed point cryostatis.run( 'west;west;west;take hologram;east;east;east') # hologram cryostatis.run('north;take candy cane') # candy cane cryostatis.run('north;north;take polygon;south') # polygon cryostatis.run('south;west;take antenna') cryostatis.run( 'west;take shell;east;south;take whirled peas;north;east') cryostatis.run('north;west;take fuel cell;west') cryostatis.run( 'drop hologram;drop shell;drop whirled peas;drop fuel cell;drop fixed point;drop polygon;drop antenna;drop candy cane' ) def run_checkpoint(self): self.collect_all_items() items = [ 'whirled peas', 'fuel cell', 'fixed point', 'polygon', 'antenna', 'candy cane', 'hologram', 'shell' ] for n in range(1, len(items)): items_comb = list(itertools.combinations(items, n)) for item_set in items_comb: for count in range(n): self.run(f"take {item_set[count]}") output = self.run("west") if output.find('Analysis complete!') > -1: print(f"solution was: {sorted(list(item_set))}") return re.search('[0-9]+', output).group(0) for count in range(n): self.run(f"drop {item_set[count]}")
class VacuumRobot: def __init__(self): self.brain = Intcode() def load(self, code): self.brain.load(code) def grab_camera(self): self.brain.run() return "".join(map(chr, map(int, self.brain.get_all_outputs().split()))) def run_path(self, order, subpaths): self.brain.code[0] = 2 # switch to the path following mode line = list(map(ord, ",".join(map(str, order)) + "\n")) for c in line: self.brain.add_input(c) for path in subpaths: line = list(map(ord, ",".join(map(str, path)) + "\n")) for c in line: self.brain.add_input(c) line = list(map(ord, "n\n")) for c in line: self.brain.add_input(c) self.brain.run() outputs = self.brain.get_all_outputs().split() return outputs[-1]
class Computer(threading.Thread): def __init__(self, controller, input, num): super().__init__() self.daemon = True self.controller = controller self.prog = Intcode(input, [num]) self.lock = threading.RLock() self.empty = 0 def send(self, x, y): with self.lock: self.empty = 0 self.prog.input.extend([x, y]) def run(self): while True: try: dest = self.prog.run(True) except NeedsInput: with self.lock: if not self.prog.input: self.prog.input.append(-1) self.empty += 1 self.controller.update_empty() else: if dest is None: return x = self.prog.run(True) y = self.prog.run(True) self.controller.send(dest, x, y)
def compute_intcode_result(program, noun, verb): program_copy = program.copy() program_copy[1] = noun program_copy[2] = verb computer = Intcode(program_copy) computer.run() return computer.program[0]
class RescueDrone: def __init__(self, code): self.brain = Intcode() self.brain.load(code) self.commands = { "n": "north", "s": "south", "e": "east", "w": "west", "t": "take", "d": "drop", "i": "inv" } def act(self, command=""): if command != "": if command[0] in self.commands: command = self.commands[command[0]] + command[1:] for c in command: self.brain.add_input(ord(c)) self.brain.add_input(ord("\n")) self.brain.run() outputs = map(chr, map(int, self.brain.get_all_outputs().split())) self.print_output(outputs) def print_output(self, outputs): for c in outputs: print(c, end="")
def run_two(self, inputs): intcode_a = Intcode(self.code[:], [inputs[0], 0], name='A') intcode_b = Intcode(self.code[:], [inputs[1]], name='B') intcode_c = Intcode(self.code[:], [inputs[2]], name='C') intcode_d = Intcode(self.code[:], [inputs[3]], name='D') intcode_e = Intcode(self.code[:], [inputs[4]], name='E') while intcode_a.is_running() and intcode_b.is_running( ) and intcode_c.is_running() and intcode_a.is_running( ) and intcode_d.is_running() and intcode_e.is_running(): intcode_a.run() if intcode_b.is_running() and len(intcode_a.outputs) > 0: intcode_b.inputs += intcode_a.outputs intcode_a.outputs = [] intcode_b.run() if intcode_c.is_running() and len(intcode_b.outputs) > 0: intcode_c.inputs += intcode_b.outputs intcode_b.outputs = [] intcode_c.run() if intcode_d.is_running() and len(intcode_c.outputs) > 0: intcode_d.inputs += intcode_c.outputs intcode_c.outputs = [] intcode_d.run() if intcode_e.is_running() and len(intcode_d.outputs) > 0: intcode_e.inputs += intcode_d.outputs intcode_d.outputs = [] intcode_e.run() if intcode_a.is_running() and len(intcode_e.outputs) > 0: intcode_a.inputs += intcode_e.outputs intcode_e.outputs = [] return intcode_e.outputs[0]
def test_day9_solutions(): data = [int(s) for s in open('./day9.input').read().strip().split(',')] intcode = Intcode(data[:], inputs=[1], verbose=False) intcode.run() assert intcode.outputs == [3345854957] intcode = Intcode(data[:], inputs=[2], verbose=False) intcode.run() assert intcode.outputs == [68938]
def part2(input): for noun in range(100): for verb in range(100): prog = Intcode(input) prog[1] = noun prog[2] = verb prog.run() if prog[0] == 19690720: return 100 * noun + verb
def problem1(program): input, output = [], [] cpu = Intcode(program, input, output) cpu.run() block_tiles = 0 for i in range(0, len(output), 3): if output[i + 2] == 2: block_tiles += 1 print(block_tiles)
def main(): with open('data/input02.txt') as f: content = f.read() program_input = [int(x) for x in content.split(',')] intcode = Intcode(program_input) intcode.memory[1] = 12 intcode.memory[2] = 2 intcode.run() return intcode.memory[0]
def part1(data): cpu = Intcode() cpu.set_ascii_mode(True) cpu.load_program(data) while True: try: cpu.run() except KeyboardInterrupt: pass print(''.join([chr(c) for c in cpu.read_output()]))
def part1(input): max_thrust = 0 for phases in itertools.permutations((0, 1, 2, 3, 4)): signal = 0 for phase in phases: amp = Intcode(input, [phase, signal]) amp.run() signal = amp.output[-1] max_thrust = max(max_thrust, signal) return max_thrust
def part2(data, target): cpu = Intcode() cpu.load_program(data) for i, j in product(range(100), range(100)): cpu.reset() cpu.ram[1] = i cpu.ram[2] = j cpu.run() if cpu.ram[0] == target: return 100 * i + j
def part1(data): signals = [] for perm in permutations((0, 1, 2, 3, 4)): out = 0 for p in perm: cpu = Intcode(inputs=[p, out]) cpu.load_program(data) cpu.run() out = cpu.outputs[-1] signals.append(out) return max(signals)
def calculate_dust(program): main = "A,B,A,B,C,C,B,A,B,C\n" A = "L,10,R,10,L,10,L,10\n" B = "R,10,R,12,L,12\n" C = "R,12,L,12,R,6\n" video = "n\n" input_lines = [main, A, B, C, video] program[0] = 2 cpu = Intcode(program, [], []) cpu.input.extend(map(ord, "".join(input_lines))) cpu.run() return cpu.output[-1]
def run(): data = load_data("Day09.txt") comp = Intcode() comp.load(data) comp.add_input(1) comp.run() print(f"The BOOST keycode is {comp.get_output()}") comp.load(data) comp.add_input(2) comp.run() print(f"The coordinate is {comp.get_output()}")
def part2(input): code = [ 'A,B,B,C,A,B,C,A,B,C', 'L,6,R,12,L,4,L,6', 'R,6,L,6,R,12', 'L,6,L,10,L,10,R,6', 'n' ] code = '\n'.join(code) + '\n' prog = Intcode(input) prog[0] = 2 prog.input = list(map(ord, code)) prog.run() assert not prog.input return prog.output[-1]
def run_one(self, inputs): intcode_a = Intcode(self.code[:], [inputs[0], 0]) intcode_a.run() intcode_b = Intcode(self.code[:], [inputs[1], intcode_a.outputs[0]]) intcode_b.run() intcode_c = Intcode(self.code[:], [inputs[2], intcode_b.outputs[0]]) intcode_c.run() intcode_d = Intcode(self.code[:], [inputs[3], intcode_c.outputs[0]]) intcode_d.run() intcode_e = Intcode(self.code[:], [inputs[4], intcode_d.outputs[0]]) intcode_e.run() return intcode_e.outputs[0]
def springscript(input, script): prog = Intcode(input) if not isinstance(script, str): script = '\n'.join(line.strip() for line in script if line.strip()) script = script.strip() + '\n' prog.input.extend(map(ord, script)) prog.run() if prog.output[-1] >= 256: ret = prog.output.pop() else: ret = None print(''.join(map(chr, prog.output))) return ret
class Scaffolding: def __init__(self, data): self.coords = [] self.robot = None self.robot_state = None self.intcode = Intcode(data) def parse_output(self): output = "" x = 0 y = 0 for value in self.intcode.outputs: output += chr(value) if value == 35: # # self.coords += [(x, y)] elif value == 94: # ^ up self.robot = (x, y) self.robot_state = 'up' elif value == 118: # v down self.robot = (x, y) self.robot_state = 'down' elif value == 60: # < left self.robot = (x, y) self.robot_state = 'left' elif value == 62: # > right self.robot = (x, y) self.robot_state = 'right' elif value == 88: # X tumbling self.robot = (x, y) self.robot_state = 'tumbling' if value == 10: y += 1 x = 0 else: x += 1 return output def calibrate(self): result = 0 for coord in self.coords: (x, y) = coord if (x - 1, y) in self.coords and (x + 1, y) in self.coords and ( x, y - 1) in self.coords and (x, y + 1) in self.coords: print(f"found intersection {coord}") result += x * y return result def run(self): self.intcode.run() print(self.parse_output())
def tests(): i = Intcode([1, 9, 10, 3, 2, 3, 11, 0, 99, 30, 40, 50]) i.execute_next() assert i.memory == [1, 9, 10, 70, 2, 3, 11, 0, 99, 30, 40, 50] i.execute_next() assert i.memory == [3500, 9, 10, 70, 2, 3, 11, 0, 99, 30, 40, 50] i = Intcode([1, 0, 0, 0, 99]) i.run() assert i.memory == [2, 0, 0, 0, 99] i = Intcode([2, 3, 0, 3, 99]) i.run() assert i.memory == [2, 3, 0, 6, 99] i = Intcode([2, 4, 4, 5, 99, 0]) i.run() assert i.memory == [2, 4, 4, 5, 99, 9801] i = Intcode([1, 1, 1, 4, 99, 5, 6, 0, 99]) i.run() assert i.memory == [30, 1, 1, 4, 2, 5, 6, 0, 99] assert i.pointer == 8 i.reset() assert i.memory == [1, 1, 1, 4, 99, 5, 6, 0, 99]
def part1(input): prog = Intcode(input) prog.run() s = ''.join(map(chr, prog.output)).strip() print(s) grid = np.array([list(line) for line in s.split('\n')]) alignment = 0 for y in range(1, grid.shape[0] - 1): for x in range(1, grid.shape[1] - 1): if (grid[y, x] != '.' and grid[y - 1, x] != '.' and grid[y + 1, x] != '.' and grid[y, x - 1] != '.' and grid[y, x + 1] != '.'): alignment += x * y return alignment