async def bot(prog, white, *, x=0, y=0): io = asyncio.Queue(), asyncio.Queue() cpu = Intcode(*io) task = asyncio.Task(cpu.task(prog)) painted = set() turns = [0, 1, 0, -1, 0] direction = 0 while not task.done(): await io[0].put((x, y) in white) if await io[1].get(): white.add((x, y)) else: white.discard((x, y)) painted.add((x, y)) if await io[1].get(): direction += 1 else: direction -= 1 direction = (direction + 4) % 4 dx, dy = turns[direction:direction+2] x += dx y += dy await task return len(painted)
def test_mul_opcode_immediate(): computer = Intcode([1102, 5, 6, 0, 99, 10, 15], None) computer.run_program() if computer.program[0] == 30: assert True else: assert False
def find_tank(d, pos, data, trace): global order, loc # Is the requested direction already explored? old_pos = pos pos = tuple(map(operator.add, pos, p[d])) if pos in explored: return # Load a copy of the bot comp = Intcode() bot = comp.load(data) # Send it in the requested direction r = bot.send(d) if r == 0: explored[pos] = "." pos = old_pos elif r == 1: explored[pos] = " " trace.append(pos) elif r == 2: explored[pos] = "X" order = trace loc = old_pos trace.append(pos) for x in p.keys(): find_tank(x, pos, comp.save(), trace.copy())
def test_less_than_fail(): computer = Intcode([7, 5, 6, 0, 99, 31, 29], None) computer.less_than_opcode(0, 0) if computer.program[0] == 0: assert True else: assert False
def test_equal_fail(): computer = Intcode([8, 5, 6, 0, 99, 31, 29], None) computer.equals_opcode(0, 0) if computer.program[0] == 0: assert True else: assert False
def test_jump_false_fail_immediate(): computer = Intcode([6, 2, 33, 99], None) computer.jump_false_opcode(1, 1) if computer.pointer == 3: assert True else: assert False
def test_jump_false_fail_mixed_2(): computer = Intcode([6, 2, 32, 99], None) computer.jump_false_opcode(0, 1) if computer.pointer == 3: assert True else: assert False
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]
def __init__(self, programStr, worldSize=50): self.programStr = programStr self.computer = Intcode(self.programStr) self.program = self.computer.run() self.program.send(None) self.world = Map(worldSize, worldSize) self.position = np.array((0, 0))
def __init__(self, path): self.int = Intcode(path) self.dir = 0 self.directions = [(0, 1), (1, 0), (0, -1), (-1, 0)] self.x = 0 self.y = 0 self.painted = {(0, 0): "1"}
def tests(): i = Intcode( [3, 15, 3, 16, 1002, 16, 10, 16, 1, 16, 15, 15, 4, 15, 99, 0, 0]) assert thrusters.thrusters(i, [4, 3, 2, 1, 0]) == 43210 i = Intcode([ 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 ]) assert thrusters.thrusters(i, [0, 1, 2, 3, 4]) == 54321 i = Intcode([ 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 ]) assert thrusters.thrusters(i, [1, 0, 4, 3, 2]) == 65210 prog = [ 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 ] i = [Intcode(prog, name=i) for i in 'ABCDE'] assert thrusters.feedback_thrusters(i, [9, 8, 7, 6, 5]) == 139629729 prog = [ 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 ] i = [Intcode(prog, name=i) for i in 'ABCDE'] assert thrusters.feedback_thrusters(i, [9, 7, 8, 5, 6]) == 18216
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_part_1(code): # Direction dx = 0 dy = 1 # Position of robot px = 0 py = 0 # Squares painted squares = {} program = Intcode(code) for i in count(): logging.debug(f'{i}') logging.debug(len(squares)) moves = program.run(pvector([squares.get((px, py), 0)])) logging.debug(moves) if len(moves) == 0: break for move in grouper(moves, 2): colour, turn = tuple(move) squares[(px, py)] = colour if turn == 0: # turn left dx, dy = -dy, dx else: # turn right dx, dy = dy, -dx px += dx py += dy return (len(squares))
def amp_to_thruster(phase_set, i_set): # Handles amp chaining, returns [signal, [phase_order]] resultant_set = [0, []] possible_phases = permute(phase_set) for phases in possible_phases: amps = [] temp_result = 0 halted = False for phase in phases: temp_amp = Computer(i_set.copy(), amp_inputs=[phase, temp_result], pause_on_output=True) temp_amp.run_program() temp_result = int(temp_amp.output) amps.append(temp_amp) i = 0 while not halted: amps[i].run_program(amp_inputs=[temp_result]) halted = amps[i].halted if not halted: # print(f'amp output: {amps[i].output} - halted? {amps[i].halted}') temp_result = int(amps[i].output) i += 1 if i == len(amps): i = 0 # Reset and loop # print(f'halted? {halted}') if temp_result > resultant_set[0]: # print(f'New record: {temp_result} using set {phases}') resultant_set = [temp_result, phases] return resultant_set
def test_jump_false_opcode_mixed_2(): computer = Intcode([6, 4, 1, 99, 0], None) computer.jump_false_opcode(0, 1) if computer.pointer == 1: assert True else: assert False
def part2(lines): program = [int(e) for e in lines[0].split(',')] code = Intcode(program) robot = GridWalker() robot.set_value(1) while True: try: colour, turn = code.run(robot.get_value()) except ExitException: break robot.set_value(colour) if turn == 0: robot.turn_left() else: robot.turn_right() robot.step() minX = min([x for x, y in robot.values]) maxX = max([x for x, y in robot.values]) minY = min([y for x, y in robot.values]) maxY = max([y for x, y in robot.values]) for y in range(maxY + 1, minY - 2, -1): for x in range(minX, maxX): if robot.values[x, y] == 0: sys.stdout.write(" ") else: sys.stdout.write("#") print() print(robot.values)
def test_jump_false_fail(): computer = Intcode([6, 2, 1, 99], None) computer.jump_false_opcode(0, 0) if computer.pointer == 3: assert True else: assert False
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]}")
def test_add_opcode_mixed_1(): computer = Intcode([1001, 5, 6, 0, 99, 10, 15], None) computer.run_program() if computer.program[0] == 16: assert True else: assert False
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]
def test_less_than_succeed(): computer = Intcode([7, 1, 2, 0, 99], None) computer.less_than_opcode(0, 0) if computer.program[0] == 1: assert True else: assert False
def test_1(self): filename = 'testInput.txt' intcode = Intcode(filename) userInput = [] with open(filename) as f: expectedReturnValue = [int(n) for n in (f.read().split(','))] self.assertEqual(intcode.run(userInput), expectedReturnValue)
def test_equal_succeed(): computer = Intcode([8, 2, 2, 0, 99], None) computer.equals_opcode(0, 0) if computer.program[0] == 1: assert True else: assert False
def test_jump_false_opcode(): computer = Intcode([6, 4, 4, 99, 0], None) computer.jump_false_opcode(0, 0) if computer.pointer == 0: assert True else: assert False
def test_mul_opcode_position(): computer = Intcode([2, 5, 6, 0, 99, 10, 15], None) computer.run_program() if computer.program[0] == 150: assert True else: assert False
def test_jump_false_opcode_immediate(): computer = Intcode([6, 0, 4, 99, 44], None) computer.jump_false_opcode(1, 1) if computer.pointer == 4: assert True else: assert False
def test_jump_true_opcode(): computer = Intcode([5, 1, 4, 99, 44], None) computer.jump_true_opcode(0, 0) if computer.pointer == 44: assert True else: assert False
def test_jump_false_opcode_mixed_1(): computer = Intcode([6, 0, 4, 99, 44], None) computer.jump_false_opcode(1, 0) if computer.pointer == 44: assert True else: assert False
def move(codes, is_origin_white=False): visited = set() white_pos = set() pos = (0, 0) # (y, x) direction = (-1, 0) # (y, x): face up if is_origin_white: white_pos.add(pos) intcode = Intcode(0, codes) while not intcode.halted(): inst = [1] if pos in white_pos else [0] color, turn = intcode.run(2, inst).get_output()[-2:] visited.add(pos) if color == 1: white_pos.add(pos) elif pos in white_pos: white_pos.remove(pos) direction = right(direction[0], direction[1]) if turn == 1 else left( direction[0], direction[1]) pos = sum(i[0] for i in [pos, direction]), sum(i[1] for i in [pos, direction]) return visited, white_pos
def test_jump_imm(self): program = Intcode([3, 3, 1105, -1, 9, 1101, 0, 0, 12, 4, 12, 99, 1], user_input=[ 100, ]) output = program.execute() self.assertEqual(output, [1])