from part1 import * verbose = False sssst = True thoughts = \ """ So, we can place an obstacle on each of the 130*130 - #obstacles = 16900 - obstacles positions, but the initial path only covers 1512 positions (thus 1512 - 1 = 1511 steps). By instead placing an obstacle on each of those steps, we can find a loop. The other thing we need to do, is detect loops. For that, It would be nice to store both positions and directions to establish uniqueness, or just check whether it is the fifth time in a position (as we have then travelled to that position at least twice from at least one position; see Pigeonhole principle). """ #map_to_load = "testinput" map_to_load = "input" if __name__ == "__main__": m = Map() m.load_map(map_to_load) # Prepare forked map for speed forked_map = m.copy() #forked_map = Map() #forked_map.load_map(map_to_load) begin_pos = m.pos begin_direction = m.direction trace = [m.pos] while m.step(): trace.append(m.pos) #print(trace) loop_obstacles = [] for i in range(1, len(trace)): pos, next_pos = trace[i - 1], trace[i] if not forked_map.pos_in_map(next_pos): continue if verbose: print(m.pos, m.direction) # Setup the fork forked_map.map[next_pos] = Map.Tiles.OBSTACLE.value forked_map.map[pos] = m.map[pos] forked_map.pos = begin_pos forked_map.direction = begin_direction forked_map.trace = [begin_pos] forked_map.pos_counter *= 0 #print(forked_map.trace) #forked_map.show() if not sssst: print(f"Forking at {next_pos}... ", end="") try: while forked_map.step(): continue except Map.LoopException: if not sssst: print("loop.") loop_obstacles.append(next_pos) #print(forked_map.trace) #forked_map.show() else: if not sssst: print("no loop.") #print(forked_map.trace) #forked_map.show() print(len(set(loop_obstacles)))