def calc(log, values, mode, debug=False, draw=False): from program import Program if mode == 1: prog = Program(values, log if debug else None) while not prog.seen_pc(): prog.step() return prog.acc else: prog = Program(values) swap = {"jmp": "nop", "nop": "jmp"} to_test = [] for i in range(len(values)): if prog.instructions[i].op in swap: to_test.append(i) for i in to_test: prog = Program(values) prog.instructions[i].op = swap[prog.instructions[i].op] backup = prog.clone() hit_end = True while prog.step(): if prog.seen_pc(): hit_end = False break if hit_end: if draw: while True: print(f"Drawing frame {backup.steps} of {prog.steps}") backup.show() if not backup.step(): break return prog.acc return 0
def maps(): with zipfile.ZipFile(os.path.join("source", "challenge.zip"), 'r') as zip: machine = zip.read('challenge.bin') todo = [2317] todo = [2488] todo = [2498] starts = [ { 'name': 'start', 'room': 2317, 'lantern': False }, { 'name': 'start_lantern', 'room': 2317, 'lantern': True }, { 'name': 'hq', 'room': 2488, 'lantern': False }, { 'name': 'island', 'room': 2498, 'lantern': False }, ] for start in starts: rooms = {} todo = [start['room']] while len(todo) > 0: room = todo.pop(0) rooms[room] = {'id': room, 'connections': [], 'name': ''} program = Program() program.load_bytes(machine) program.deserialize(os.path.join("source", "start_state.zip")) program.memory[2732] = room if start['lantern']: program.memory[2682] = 0 program.run(abort_on_input=True, hide_output=True) program.room = [] program.input_buffer = "look\n" program.run(abort_on_input=True, hide_output=True) left = 0 for cur in program.room: m = re.search("== (.*) ==", cur) if m is not None: rooms[room]['name'] = m.group(1) m = re.search("There (are|is) ([0-9]+) exits{0,1}:", cur) if m is not None: left = int(m.group(2)) if left > 0 and cur.startswith("- "): left -= 1 rooms[room]['connections'].append([cur[2:], -1]) temp = program.clone() for i in range(len(rooms[room]['connections'])): program = temp.clone() program.input_buffer = rooms[room]['connections'][i][0] + "\n" program.run(abort_on_input=True, hide_output=True) rooms[room]['connections'][i][1] = program.memory[2732] if rooms[room]['connections'][i][1] not in rooms: rooms[rooms[room]['connections'][i][1]] = None todo.append(rooms[room]['connections'][i][1]) import csv edge = 0 with open("edges_" + start['name'] + ".csv", "w", newline='') as f_edges: cw_edges = csv.writer(f_edges) cw_edges.writerow( ['id', 'source', 'source_name', 'dest', 'dest_name', 'dir']) for room in rooms.values(): # cw_nodes.writerow(["node" + str(room['id']), room['name']]) for dir, other in room['connections']: edge += 1 cw_edges.writerow([ "edge" + str(edge), "node" + str(room['id']), room['name'], "node" + str(other), rooms[other]['name'], dir ]) print("Done with " + start['name'])
def auto(state=""): with zipfile.ZipFile(os.path.join("source", "challenge.zip"), 'r') as zip: machine = zip.read('challenge.bin') program = Program() program.load_bytes(machine) if len(state) == 0: state = os.path.join("source", "start_state.zip") program.deserialize(state) ignore = set([ 'The passage to the east looks very dark; you think you hear a Grue.', 'The east passage appears very dark; you feel likely to be eaten by a Grue.', 'emBLbWMgDhds', '\n\nThat door is locked.\n\nWhat do you do?', '\n\nYou have been eaten by a grue.', "\n\nThe vault door is sealed.\n\nWhat do you do?", ]) states = [(program.clone(), None, [], [])] seen = set() while len(states) > 0: program, step, path, inv = states.pop(0) if step is not None: program.input_buffer += step + "\n" path = path + [step] program.run(abort_on_input=True, hide_output=True) room = "\n".join(program.room) m = re.search( "Chiseled on the wall of one of the passageways, you see:\n\n (?P<code>[a-zA-Z0-9]+)\n\nYou take note of this and keep walking.(?P<other>.*)", room, flags=re.DOTALL) if m is not None: if m.group("code") not in ignore: print(path) print("New code: " + m.group("code")) exit(1) else: room = m.group("other") room = re.sub( "^\n\nAs you (approach the vault door|(enter|leave) the room).*?\n", "\n", room, flags=re.DOTALL) room = re.sub( "^\n\nAs you (approach the vault door|(enter|leave) the room).*?\n", "\n", room, flags=re.DOTALL) if room not in ignore: m = re.search( "^\n\n(?P<room>== .*? ==\n.*?)\n\n(?P<other>.*)\n\nWhat do you do\\?$", room, flags=re.DOTALL) if m is None: program.serialize("temp.zip") print("Room with odd description: " + json.dumps(room)) exit(1) else: room, other = m.group("room"), m.group("other") mem = "" for key, value in program.changed.items(): if key < 3000: mem += f"{key},{value}|" if mem not in seen: seen.add(mem) in_list = "" lists = { "door": [], "item": [], 'other': [], } for cur in other.split("\n"): if re.search("^There (are|is) [0-9]+ exits{0,1}:$", cur): in_list = "door" elif cur == "Things of interest here:": in_list = "item" elif cur == "": in_list = "" elif cur.startswith("- "): lists[in_list].append(cur[2:]) elif re.search( '[0-9_]+ \\+ [0-9_]+ \\* [0-9_]+\\^2 \\+ [0-9_]+\\^3 \\- [0-9_]+ = 399', cur): lists["other"].append(cur) else: known = False if cur in ignore: known = True if not known: if re.search( "The floor of this room is a large mosaic depicting a '(.*)' symbol.", cur): known = True if not known: if re.search( "The floor of this room is a large mosaic depicting the number '([0-9]+)'.", cur): known = True if not known: print("Unknown line of desc: " + json.dumps(cur)) print("Inventory: ", inv) exit(1) for other in lists["other"]: if len([x for x in inv if x.endswith("coin")]) == 5: # From solve_coins order = [ "blue", "red", "shiny", "concave", "corroded" ] for test in order: test += " coin" inv.remove(test) path = path + ['use ' + test] program.input_buffer += path[-1] + "\n" program.run(abort_on_input=True) lists['door'] = ["look"] + lists['door'] for item in lists["item"]: if item not in { "empty lantern", "can", "teleporter", 'business card', 'strange book', 'journal', 'orb' } and not item.endswith("coin"): print(item) print(inv) print("-- Path --:") for temp in path: print(temp) exit(1) inv.append(item) path = path + ['take ' + item] program.input_buffer += path[-1] + "\n" program.run(abort_on_input=True, hide_output=True) if len( inv ) == 2 and 'can' in inv and 'empty lantern' in inv: path = path + ['use can'] program.input_buffer += path[-1] + "\n" program.run(abort_on_input=True) path = path + ['use lantern'] program.input_buffer += path[-1] + "\n" program.run(abort_on_input=True) if item == 'teleporter': inv.remove('teleporter') path = path + ['use teleporter'] program.input_buffer += path[-1] + "\n" program.run(abort_on_input=True) states = [] lists['door'] = ['look'] if "== Vault" in room: program.save_state.serialize( "room_" + str(program.memory[2732]) + ".zip") for door in lists["door"]: states.append((program.clone(), door, path[:], inv[:])) print("--- All steps ---") for cur in path: print(cur) program.save_state.serialize(os.path.join('source', 'book.zip'))
def find_rooms(): with zipfile.ZipFile(os.path.join("source", "challenge.zip"), 'r') as zip: machine = zip.read('challenge.bin') program = Program() program.load_bytes(machine) program.deserialize(os.path.join("source", "beach.zip")) program.run(abort_on_input=True, hide_output=True) known_rooms = set([ 2317, 2327, 2332, 2337, 2342, 2347, 2352, 2357, 2362, 2367, 2372, 2377, 2397, 2402, 2417, 2427, 2432, 2437, 2442, 2447, 2452, 2457, 2463, 2468, 2473, 2478, 2483, 2488, 2498, 2513, 2523, 2528, 2533, 2538, 2543, 2548, 2553, 2558, 2573, 2578, 2588, 2593, 2603, 2608, 2613, 2618, 2623, 2643, 2322, 2382, 2387, 2392, 2407, 2412, 2422, 2493, 2503, 2508, 2518, 2563, 2568, 2583, 2598, 2628, 2633, 2638, 2648, 2653, 2658, ]) start = program.clone() for i in range(2000, 3000): if i not in known_rooms: program = start.clone() program.memory[2732] = i program.input_buffer = "look\n" try: val = program.run(abort_on_input=True, hide_output=True) if val not in { "Unknown output character", "Halt instruction hit!" }: print(i, val) program.input_buffer = "look\n" program.run(abort_on_input=True) except: pass