def sol2(code, show_progress=False): colour = {} current_pos = [0, 0] current_dir = Dir(0) computer = Intcode(code, []) next_input = 1 while not computer.done(): computer.add_input(next_input) while not computer.done() and len(computer.outputs) < 2: computer.execute_command() if computer.done(): break paint, d = computer.outputs current_dir = current_dir.pred() if d == 0 else current_dir.succ() computer.outputs = [] colour[tuple(current_pos)] = paint current_pos[0] += current_dir.xy()[0] current_pos[1] += current_dir.xy()[1] next_input = colour.get(tuple(current_pos), 0) if show_progress: print(identifier(colour)) print() sleep(0.05) return identifier(colour)
def sol1(code, dbg=False): colour = {} current_pos = [0, 0] current_dir = Dir(0) computer = Intcode(code, []) next_input = 0 while not computer.done(): computer.add_input(next_input) while not computer.done() and len(computer.outputs) < 2: computer.execute_command() if computer.done(): break paint, d = computer.outputs current_dir = current_dir.pred() if d == 0 else current_dir.succ() computer.outputs = [] colour[tuple(current_pos)] = paint current_pos[0] += current_dir.xy()[0] current_pos[1] += current_dir.xy()[1] next_input = colour.get(tuple(current_pos), 0) return len(colour)
def sol2(data, feed=False): """ Manually computed input: ABABCBACBC A = L 12 L 8 R 10 R 10 B = L 6 L 4 L 12 C = R 10 L 8 L 4 R 10 """ # with open('board.txt', 'w') as f: # for row in board: # f.write(row.__str__() + '\n') data[0] = 2 main_routine = 'A,B,A,B,C,B,A,C,B,C' routine_a = 'L,12,L,8,R,10,R,10' routine_b = 'L,6,L,4,L,12' routine_c = 'R,10,L,8,L,4,R,10' feed_char = 'y' if feed else 'n' input_str = '\n'.join( [main_routine, routine_a, routine_b, routine_c, feed_char]) + '\n' inputs = [ord(c) for c in input_str] computer = Intcode(data, inputs=inputs) while not computer.done(): computer.execute_command() if computer.outputs[-2:] == [10, 10] and feed: print('\n' * 100) print(''.join([chr(i) for i in computer.outputs]), end='') computer.outputs = [] return computer.outputs[-1]
def sol2(code, user_input=False, display=False): code[0] = 2 computer = Intcode(code, user_input=user_input) blocks = [] score = 0 while not computer.done(): if computer.is_input(): score, move = simulate_board(blocks, *get_dimensions(blocks), display) if not user_input: computer.add_input(move) computer.execute_command() if len(computer.outputs) == 3: x, y, tile = computer.outputs blocks.append((x, y, tile)) computer.outputs = [] score, _ = simulate_board(blocks, *get_dimensions(blocks), display) return score
def sol1(code): computer = Intcode(code) blocks = 0 while not computer.done(): computer.execute_command() if len(computer.outputs) == 3: x, y, tile = computer.outputs computer.outputs = [] if tile == 2: blocks += 1 return blocks
def sol1(data, show=False): computer = Intcode(data) board = [None] * BOARD_SIZE dist = [None] * BOARD_SIZE for i in range(BOARD_SIZE): board[i] = [' '] * BOARD_SIZE dist[i] = [-1] * BOARD_SIZE d_x, d_y = BOARD_SIZE // 2, BOARD_SIZE // 2 board[d_y][d_x] = 'D' dist[d_y][d_x] = 0 last_inp = None oxygen = None cur_dir = Direction.UP cur_dist = 0 moves = 0 while (d_x, d_y) != (BOARD_SIZE // 2, BOARD_SIZE // 2) or moves == 0: out = computer.execute_command() if out is not None: if out >= 0: if out == 0: w_x, w_y = move_droid((d_x, d_y), last_inp) board[w_y][w_x] = '#' # Hit wall, adjust to the right twice cur_dir = cur_dir.right() cur_dir = cur_dir.right() elif out == 1: if moves == 0: moves = 1 board[d_y][d_x] = '.' # Mark as safe d_x, d_y = move_droid((d_x, d_y), last_inp) if dist[d_y][d_x] >= 0: cur_dist = dist[d_y][d_x] else: cur_dist += 1 dist[d_y][d_x] = cur_dist elif out == 2: d_x, d_y = move_droid((d_x, d_y), last_inp) oxygen = (d_x, d_y) cur_dist += 1 # definitely wasn't there before, just increase return cur_dist if show: print_board(board, (d_x, d_y), oxygen) print('Current distance:', cur_dist) sleep(0.005) elif out == -2: # waiting for input cur_dir = cur_dir.left() last_inp = go_forward(cur_dir) computer.add_input(last_inp) return cur_dist
def retrieve_board(data, show=False): """ Retrieve the whole board by sticking to the left wall until reaching the beginning """ if show: print('Retrieving board...') computer = Intcode(data) # Otherwise the default list argument is overwritten board = [None] * BOARD_SIZE for i in range(BOARD_SIZE): board[i] = [' '] * BOARD_SIZE d_x, d_y = BOARD_SIZE // 2, BOARD_SIZE // 2 board[d_y][d_x] = 'D' last_inp = None cur_dir = Direction.UP oxygen = None moves = 0 while (d_x, d_y) != (BOARD_SIZE // 2, BOARD_SIZE // 2) or moves == 0: out = computer.execute_command() if out is not None: if out >= 0: if out == 0: w_x, w_y = move_droid((d_x, d_y), last_inp) board[w_y][w_x] = '#' # Hit wall, adjust to the right twice cur_dir = cur_dir.right() cur_dir = cur_dir.right() elif out == 1: if moves == 0: moves = 1 board[d_y][d_x] = '.' # Mark as safe d_x, d_y = move_droid((d_x, d_y), last_inp) elif out == 2: d_x, d_y = move_droid((d_x, d_y), last_inp) oxygen = (d_x, d_y) if show: print_board(board, (d_x, d_y), oxygen) sleep(0.01) elif out == -2: # waiting for input cur_dir = cur_dir.left() last_inp = go_forward(cur_dir) computer.add_input(last_inp) if show: print('Board retrieved') return board, oxygen
def sol1(data): computer = Intcode(data) board = [[]] while not computer.done(): computer.execute_command() if computer.outputs: out = computer.outputs.pop() if out == 10: board.append([]) else: board[-1].append(chr(out)) while not board[-1]: board.pop() result = 0 for y, row in enumerate(board): if y == 0 or y == len(board) - 1: continue for x, c in enumerate(row): if c != '#' or x == 0 or x == len(row) - 1: continue neighbours = 0 for nx, ny in [(x - 1, y), (x + 1, y), (x, y + 1), (x, y - 1)]: if board[ny][nx] == '#': neighbours += 1 if neighbours == 4: result += x * y return result