from lib import get_data, str_to_ints, A_Star data = get_data(__file__) depth, x_target, y_target = str_to_ints(data) # depth, x_target, y_target = 510, 10, 10 # depth, x_target, y_target = 9171, 7, 721 # print(depth, x_target, y_target) x_area_max = x_target * 10 y_area_max = y_target * 10 maze = [[None for _ in range(x_area_max + 1)] for _ in range(y_area_max + 1)] maze[0][0] = 0 maze[y_target][x_target] = 0 mod = 20183 for x in range(x_area_max + 1): maze[0][x] = x * 16807 % mod for y in range(y_area_max + 1): maze[y][0] = y * 48271 % mod for y in range(1, y_area_max + 1): for x in range(1, x_area_max + 1): if x == x_target and y == y_target: continue assert maze[y][x] is None geo_index = ((maze[y][x - 1] + depth) * (maze[y - 1][x] + depth)) % mod maze[y][x] = geo_index t = 0 for y in range(y_target + 1): for x in range(x_target + 1): t += ((maze[y][x] + depth) % mod) % 3 print(t) for y in range(y_area_max + 1): for x in range(x_area_max + 1): maze[y][x] = ((maze[y][x] + depth) % mod) % 3 def allowed(area, tool): # 0 = rocky, 1 = wet, 2 = narrow # 0 = torch, 1 = climbing, 2 = neither return ( (area == 0 and (tool in [0, 1])) or (area == 1 and (tool in [1, 2])) or (area == 2 and (tool in [0, 2])) ) def neighbors(state): x, y, tool = state r = [] area = maze[y][x] for t in range(3): if allowed(area, t) and t != tool: r.append((x, y, t)) for dx, dy in [(0, 1), (0, -1), (1, 0), (-1, 0)]: nx, ny = x + dx, y + dy if not (nx >= 0 and nx < x_area_max and ny >= 0 and ny < y_area_max): continue if not allowed(maze[ny][nx], tool): continue r.append((nx, ny, tool)) return r def distance(a, b): if a == 0: return 0 elif a[2] != b[2]: assert a[0] == b[0] and a[1] == b[1] return 7 else: return 1 a = A_Star( starts=[(0, 0, 0)], is_goal=lambda s: s[0] == x_target and s[1] == y_target and s[2] == 0, h=lambda s: abs(s[0] - x_target) + abs(s[1] - y_target), d=distance, neighbors=neighbors, ) print(a.cost)