def run_intcode(inputfile, noun=None, verb=None): """Runs the Intcode provided in inputfile Parameters ---------- inputfile : str Name/path of file that contains the puzzle input noun : int Fixed value to put into memory[1] verb : int Fixed value to put into memory[2] """ memory = IntcodeVM.read_intcode(inputfile) if noun is not None: memory[1] = noun if verb is not None: memory[2] = verb machine = IntcodeVM(memory) machine.run() return machine
def paint_hull(inputfile, hull={}): """Launches the emergency hull painting robot with the specified Intcode source file Parameters ---------- inputfile: str Path/Filename of Intcode source code hull : dict<(int,int): int> Initial state of the hull """ robot_pos = (0, 0) robot_dir = (0, -1) machine = IntcodeVM(inputfile, silent=True) machine.run() while machine.waiting: color, turn = machine.resume([hull.get(robot_pos, BLACK)]) hull[robot_pos] = color robot_dir = TURNS[robot_dir][turn] robot_pos = (robot_pos[0] + robot_dir[0], robot_pos[1] + robot_dir[1]) return hull
def move_robot(inputfile, moves, screen): source = IntcodeVM.read_intcode(inputfile) drawer = GridDrawer(screen) source[0] = 2 machine = IntcodeVM(source, silent=True, output_func=drawer.add_output) outputs = machine.run(moves) sleep(2) return outputs.pop()
def play_game(inputfile, screen): source = IntcodeVM.read_intcode(inputfile) # Insert coin... source[0] = 2 # Boot up arcade machine machine = IntcodeVM(source, silent=True) grid = {} score = 0 total_bricks = 0 max_y = 0 move = None # Game loop while machine.waiting: if move is None: outputs = machine.run() else: outputs = machine.resume([move]) for o in range(0, len(outputs), 3): x, y, tile = outputs[o:o + 3] if x == -1 and y == 0: score = tile else: screen.print_at(SYMBOLS[tile], x * 3, y, COLORS[tile]) grid[(x, y)] = tile if total_bricks == 0: total_bricks = sum(1 for pos in grid if grid[pos] == BLOCK) if max_y == 0: max_y = max(grid.keys())[1] screen.print_at( "Blocks left: %s / %s " % (sum(1 for pos in grid if grid[pos] == 2), total_bricks), 5, max_y + 1) screen.print_at("Score: %s" % score, 5, max_y + 2) screen.move(0, 0) screen.refresh() sleep(0.01) # Breakout AI!! paddle = [key for key in grid if grid[key] == PADDLE][0] ball = [key for key in grid if grid[key] == BALL][0] if paddle[0] < ball[0]: move = 1 elif paddle[0] > ball[0]: move = -1 else: move = 0 screen.print_at("All done, press ENTER to exit!", 5, max_y // 2) screen.refresh() input()
def maze(screen): # Initialise droid droid = IntcodeVM( IntcodeVM.read_intcode(os.path.join(currentdir, "input.txt")), False, True) # One run to determine the dimensions of the grid droid.run() area_map, _ = explore(droid) minx = min(pos[0] for pos in area_map) maxx = max(pos[0] for pos in area_map) miny = min(pos[1] for pos in area_map) maxy = max(pos[1] for pos in area_map) dimensions = (minx, miny, maxx, maxy) # Actual run with visualization droid.run() area_map, distance_map = explore(droid, screen=screen, dimensions=dimensions) os_pos = [pos for pos in area_map if area_map[pos] == OS][0] # breadth-first algorithm for spreading the oxygen frontiers = [os_pos] minutes = 0 while len(frontiers) > 0: new_frontiers = [] for frontier in frontiers: for (dx, dy) in DIRECTIONS.values(): new_frontier = (frontier[0] + dx, frontier[1] + dy) if area_map.get(new_frontier, WALL) == FREE: area_map[new_frontier] = OS draw_map(area_map, None, screen, dimensions) new_frontiers.append(new_frontier) frontiers = new_frontiers if len(frontiers) > 0: minutes = minutes + 1 input() print("Part 1: %s" % distance_map[os_pos]) print("Part 2: %s" % minutes)
def one_run(inputfile): max_thruster = 0 code = IntcodeVM.read_intcode(inputfile) machine = IntcodeVM(code) for phases in permutations([0, 1, 2, 3, 4]): last_output = 0 for phase in phases: inputs = [phase, last_output] outputs = machine.run(inputs) last_output = outputs.pop() if last_output > max_thruster: max_thruster = last_output return max_thruster
def feedback_loop(inputfile): max_thruster = 0 code = IntcodeVM.read_intcode(inputfile) for phases in permutations([5, 6, 7, 8, 9]): done = False #Initialise machines machines = [] for phase in phases: machine = IntcodeVM(code) machine.run([phase]) machines.append(machine) last_output = 0 while not done: for machine in machines: last_output = machine.resume([last_output])[-1] if not machine.waiting: done = True if last_output > max_thruster: max_thruster = last_output return max_thruster
def create_grid(inputfile): source = IntcodeVM.read_intcode(inputfile) machine = IntcodeVM(source, silent=True) outputs = machine.run() grid = [] line = [] for output in outputs: if output == 10: if len(line) > 0: grid.append(line) line = [] else: line.append(chr(output)) return grid
def __init__(self, source, computers=50): self.computers = [] self.packets = [] self.outputs = [] self.idle = [] self.nat_package = None self.last_nat_package = None for c in range(computers): computer = IntcodeVM(source, silent=True) self.idle.append(0) self.packets.append([]) output = computer.run([c]) self.outputs.append(output) computer.stepwise = True self.computers.append(computer)
def run_program(self, code, inputs=[]): """Helper method to initialise an IntcodeVM, run it and return the machine itself and the output of the run""" machine = IntcodeVM(code) outputs = machine.run(inputs) return machine, outputs
advent.submit_answer(1, ans) def vm_write2(v): if v > 0x7f: # print('----', v, '----') advent.submit_answer(2, v) vm.reset() vm.code[0] = 2 vm.write = vm_write2 main = 'R,6,L,6,L,10,L,8,L,6,L,10,L,6,R,6,L,6,L,10,L,8,L,6,L,10,L,6,R,6,L,8,L,10,R,6,R,6,L,6,L,10,L,8,L,6,L,10,L,6,R,6,L,8,L,10,R,6,R,6,L,6,L,10,R,6,L,8,L,10,R,6' # Compress above program by hand... main = 'A,B,A,B,C,A,B,C,A,C' funcs = [ 'R,6,L,6,L,10', 'L,8,L,6,L,10,L,6', 'R,6,L,8,L,10,R,6', ] subs = '\n'.join(funcs) debug = 'n' robot_prog = list(map(ord, '{}\n{}\n{}\n'.format(main, subs, debug))) vm.run(robot_prog)
def vm_read_for(self): def vm_read(): if not Q: line = input() if line == 'n': line = N elif line == 's': line = S elif line == 'e': line = E elif line == 'w': line = W Q.extend(map(ord, line + '\n')) return Q.popleft() return vm_read def vm_write(v): if v <= 127: sys.stdout.write(chr(v)) else: print('----------', v) vm.read = vm_read_for(vm) vm.write = vm_write # Solve manually! :P vm.run()
# !AD+!BD+!CDH # == (!A+!B)D+!CDH # == !(AB)D + !CDH asm2 = """\ NOT A T NOT B J OR T J AND D J NOT C T AND D T AND H T OR T J RUN """ asm1 = list(map(ord, asm1)) ans1 = vm.run(asm1)[-1] advent.submit_answer(1, ans1) asm2 = list(map(ord, asm2.replace('\n\n', '\n'))) out = vm.run(asm2) # for v in out: # if v <= 127: # sys.stdout.write(chr(v)) ans2 = out[-1] # print(ans2) advent.submit_answer(2, ans2)
def game(stdscr, program): stdscr.clear() curses.curs_set(False) program[0] = 2 vm = IntcodeVM(program) screen = {} n_tiles = 0 while True: x, y, tile = vm.run([0], resume=True, n_out=3) if (x, y) != (-1, 0): screen[x, y] = tile if len(screen) == n_tiles: break n_tiles = len(screen) grid = build_grid(screen) pad = curses.newpad(100, 100) del screen make_move = True redraw = False paddle_x = 0 inp = [0] score = 0 while True: out = vm.run(inp, resume=True, n_out=3) if not out: break x, y, tile = out if (x, y) == (-1, 0): score = tile else: if tile in (BALL, PADDLE) and REV_TILE_MAP[grid[y][x]] == EMPTY: redraw = True grid[y][x] = TILE_MAP[tile] if tile == BALL and make_move: if x > paddle_x: inp = [1] elif x < paddle_x: inp = [-1] make_move = False elif tile == PADDLE and not make_move: paddle_x = x make_move = True if redraw: redraw = False ok = display(pad, grid, score) if not ok: return 1 sleep(1) return 0
fin = advent.get_input() # eprint(*fin, sep='') timer_start() ################################################## from lib.intcode import IntcodeVM prog = get_ints(fin, True) vm = IntcodeVM(prog) n = 0 for i in range(50): for j in range(50): out = vm.run([i, j], n_out=1) if not out: break if out[0] == 1: n += 1 # print(n) advent.submit_answer(1, n) # PART 2: # Visualize, copy in text editor and solve by hand # using a regex: (1{100}.+\n){100} starty, startx = 350, 1050 + (150 - 127) width, height = 150, 200 # grid = [[-1] * width for _ in range(height)]
import os import sys currentdir = os.path.dirname(os.path.abspath(__file__)) parentdir = os.path.dirname(currentdir) sys.path.insert(0, parentdir) from lib.intcode import IntcodeVM code = IntcodeVM.read_intcode(os.path.join(currentdir, "input.txt")) machine = IntcodeVM(code) outputs = machine.run([1]) print("Part 1: %s" % outputs.pop()) outputs = machine.run([5]) print("Part 2: %s" % outputs.pop())
if ok: A = ','.join(func_a) B = ','.join(func_b) C = ','.join(func_c) if len(A) <= 20 and len(B) <= 20 and len(C) <= 20: return A, B, C advent.setup(2019, 17) fin = advent.get_input() program = list(map(int, fin.read().split(','))) vm = IntcodeVM(program) out = vm.run() grid = ''.join(map(chr, out)).strip().splitlines() rows, columns = len(grid), len(grid[0]) answer = 0 for r in range(1, rows - 1): for c in range(1, columns - 1): if grid[r][c] == SCAFFOLD: n = sum((grid[rr][cc] == SCAFFOLD for rr, cc in ((r + 1, c), (r - 1, c), (r, c + 1), (r, c - 1)))) if n == 4: answer += r * c elif grid[r][c] in '^v<>': startpos = (r, c)
"east", "east", "take semiconductor", "north", "take planetoid", "west", "take food ration", "west", "west", "take monolith", "east", "east", "north", "take space law space brochure", "east", "take jam", "west", "north", "north", "take weather machine", "south", "south", "south", "east", "north", "take antenna", "south", "south", "east", "south", "south", "east", "drop food ration", "drop weather machine", "drop antenna", "drop space law space brochure", "drop jam", "drop semiconductor", "drop planetoid", "drop monolith" ] items = [ "food ration", "weather machine", "antenna", "space law space brochure", "jam", "semiconductor", "planetoid", "monolith" ] machine.run("\n".join(walkthrough) + "\n") # Brute forcing all item combinations until the right weight is reached. for l in range(len(items)): for selected in combinations(items, l): steps = [] for item in selected: steps.append("take %s" % item) steps.append("east") outputs = machine.resume("\n".join(steps) + "\n") outputs = "".join([chr(c) for c in outputs]) if outputs.find("lighter") >= 0: print("Too heavy:", selected) elif outputs.find("heavier") >= 0: print("Too light:", selected)
#!/usr/bin/env python3 from utils import advent from lib.intcode import IntcodeVM advent.setup(2019, 5) fin = advent.get_input() program = list(map(int, fin.read().split(','))) vm = IntcodeVM(program) out = vm.run([1])[-1] advent.print_answer(1, out) out = vm.run([5])[-1] advent.print_answer(2, out)
grid = defaultdict(lambda: BLACK) pos = (0,0) ############## Uncomment for part 2 ############ # grid[pos] = WHITE ################################################ curdir = NORTH first = True deb = False while True: # print(curdir, pos, grid[pos] if pos in grid else '?') if first: out = robot.run([grid[pos]], n_out=2, debug=deb) first = False else: out = robot.run([grid[pos]], n_out=2, resume=True, debug=deb) if not out: break color, dirr = out grid[pos] = color if dirr == LEFT: if curdir == NORTH: curdir = WEST pos = (pos[0], pos[1] - 1) elif curdir == SOUTH:
def load_input(filename): with open(filename, "r") as file: inputs = [int(line) for line in file] # Add an extra zero at the end so the Intcode program knows when to stop reading inputs.append(0) return inputs code1 = IntcodeVM.read_intcode(os.path.join(currentdir, "01_part1.ic")) machine = IntcodeVM(code1) print("Testcases") outputs = machine.run([12, 0]) assert outputs.pop() == 2 outputs = machine.run([14, 0]) assert outputs.pop() == 2 outputs = machine.run([1969, 0]) assert outputs.pop() == 654 outputs = machine.run([100756, 0]) assert outputs.pop() == 33583 inputs = load_input(os.path.join(currentdir, "testinput.txt")) outputs = machine.run(inputs) assert outputs.pop() == 34241 print("Part 1") inputs = load_input(os.path.join(currentdir, "input.txt"))
from utils.all import * from lib.intcode import IntcodeVM fin = advent.get_input() # eprint(*fin, sep='') timer_start() ################################################## program = get_ints(fin, True) vm = IntcodeVM(program) screen = set() out = vm.run() for i in range(0, len(out), 3): x, y, t = out[i:i + 3] if t == 2: screen.add((x, y)) # if t == 3: # paddle = x, y # print(paddle) # print(paddle) advent.submit_answer(1, len(screen)) # def display(screen): # minx = min(x for x, _ in screen)
#!/usr/bin/env python3 from utils import advent from lib.intcode import IntcodeVM advent.setup(2019, 9) fin = advent.get_input() program = list(map(int, fin.read().split(','))) vm = IntcodeVM(program) out = vm.run([1])[-1] advent.print_answer(1, out) out = vm.run([2])[-1] advent.print_answer(2, out)