Advertisement
Guest User

Untitled

a guest
Dec 16th, 2024
87
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 4.61 KB | None | 0 0
  1. # Input: grid of # . S (initially facing east) E
  2. # Output: cheapest path from S to E, 1 point per move + 1000 per turn
  3. #         how many tiles (including S and E) are part of 1+ cheapest paths?
  4.  
  5. def get_number_adjacent_walls(r, c):
  6.   adjacent_walls = 0
  7.   if grid[r - 1][c] == "#":
  8.     adjacent_walls += 1
  9.   if grid[r + 1][c] == "#":
  10.     adjacent_walls += 1
  11.   if grid[r][c - 1] == "#":
  12.     adjacent_walls += 1
  13.   if grid[r][c + 1] == "#":
  14.     adjacent_walls += 1
  15.   return adjacent_walls
  16.  
  17. def get_node_key(r, c, dr, dc):
  18.   return str(r) + "," + str(c) + "," + str(dr) + "," + str(dc)
  19.  
  20. def get_node_values(node):
  21.   return list(map(int, node.split(",")))
  22.  
  23. def get_cheapest_unvisited_node():
  24.   cheapest_node = None
  25.   cheapest_cost = -1
  26.   for node in unvisited_nodes:
  27.     if nodes[node] >= 0:
  28.       if cheapest_cost == -1 or cheapest_cost > nodes[node]:
  29.         cheapest_node = node
  30.         cheapest_cost = nodes[node]
  31.   return cheapest_node
  32.  
  33. grid = []
  34.  
  35. sr, sc, er, ec = -1, -1, -1, -1
  36.  
  37. r = 0
  38. file = open("16_input.txt", "r")
  39. for line in file:
  40.   line = line.replace("\n", "")
  41.   c = 0
  42.   row = []
  43.   for character in line:
  44.     if character == "S":
  45.       sr, sc = r, c
  46.       character = "."
  47.     if character == "E":
  48.       er, ec = r, c
  49.       character = "."
  50.     row.append(character)
  51.     c += 1
  52.   grid.append(row)
  53.   r += 1
  54.  
  55. # set of all nodes and their known distance from the start
  56. nodes = {}
  57. for r in range(1, len(grid) - 1):
  58.   for c in range(1, len(grid[0]) - 1):
  59.     if grid[r][c] == ".":
  60.       nodes[get_node_key(r, c, -1, 0)] = -1
  61.       nodes[get_node_key(r, c, 1, 0)] = -1
  62.       nodes[get_node_key(r, c, 0, -1)] = -1
  63.       nodes[get_node_key(r, c, 0, 1)] = -1
  64. nodes[get_node_key(sr, sc, 0, 1)] = 0
  65.  
  66. unvisited_nodes = []
  67. for node in nodes:
  68.   unvisited_nodes.append(node)
  69.  
  70. cheapest_path_length = -1
  71. while len(unvisited_nodes) > 0:
  72.   node = get_cheapest_unvisited_node()
  73.   unvisited_nodes.remove(node)
  74.   nv = get_node_values(node)
  75.   if nv[0] == er and nv[1] == ec:
  76.     cheapest_path_length = nodes[node]
  77.     print ("Cheapest path length", cheapest_path_length)
  78.     break
  79.   cr, cc, dr, dc = nv[0], nv[1], nv[2], nv[3]
  80.   # evaluate continuing in current direction
  81.   new_node = get_node_key(cr + dr, cc + dc, dr, dc)
  82.   distance = nodes[node] + 1
  83.   if new_node in nodes and (nodes[new_node] == -1 or nodes[new_node] >= distance):
  84.     nodes[new_node] = distance
  85.   # evaluate turning counterclockwise
  86.   new_node = get_node_key(cr, cc, -dc, dr)
  87.   distance = nodes[node] + 1000
  88.   if new_node in nodes and (nodes[new_node] == -1 or nodes[new_node] >= distance):
  89.     nodes[new_node] = distance
  90.   # evaluate turning clockwise
  91.   new_node = get_node_key(cr, cc, dc, -dr)
  92.   distance = nodes[node] + 1000
  93.   if new_node in nodes and (nodes[new_node] == -1 or nodes[new_node] >= distance):
  94.     nodes[new_node] = distance
  95.  
  96. paths_to_extend = [[[sr, sc, 0, 1, 0]]] # r, c, dr, dc, cost
  97. complete_paths = []
  98. while len(paths_to_extend) > 0:
  99.   path = paths_to_extend[0]
  100.   paths_to_extend.remove(path)
  101.   r, c, dr, dc, cost = path[-1][0], path[-1][1], path[-1][2], path[-1][3], path[-1][4]
  102.   nk = get_node_key(r, c, dr, dc)
  103.   # if we could have gotten to this point cheaper, then ditch this path
  104.   if nodes[nk] == -1 or nodes[nk] < cost:
  105.     continue
  106.   if r == er and c == ec:
  107.     complete_paths.append(path)
  108.     continue
  109.   # evaluate continuing in current direction
  110.   if grid[r + dr][c + dc] == ".":
  111.     add_new_path = True
  112.     for step in path:
  113.       if step[0] == r + dr and step[1] == c + dc: # would form a loop
  114.         add_new_path = False
  115.         break
  116.     if add_new_path:
  117.       new_path = path.copy()
  118.       new_path.append([r + dr, c + dc, dr, dc, cost + 1])
  119.       paths_to_extend.append(new_path)
  120.   # evaluate turning counterclockwise
  121.   if grid[r - dc][c + dr] == ".":
  122.     add_new_path = True
  123.     for step in path:
  124.       if step[0] == r - dc and step[1] == c + dr:
  125.         add_new_path = False
  126.         break
  127.     if add_new_path:
  128.       new_path = path.copy()
  129.       new_path.append([r - dc, c + dr, -dc, dr, cost + 1001]) # turn and move
  130.       paths_to_extend.append(new_path)
  131.   # evaluate turning clockwise
  132.   if grid[r + dc][c - dr] == ".":
  133.     add_new_path = True
  134.     for step in path:
  135.       if step[0] == r + dc and step[1] == c - dr:
  136.         add_new_path = False
  137.         break
  138.     if add_new_path:
  139.       new_path = path.copy()
  140.       new_path.append([r + dc, c - dr, dc, -dr, cost + 1001])
  141.       paths_to_extend.append(new_path)
  142.  
  143. tiles = []
  144. for path in complete_paths:
  145.   for step in path:
  146.     tile = [step[0], step[1]]
  147.     if not (tile in tiles):
  148.       tiles.append(tile)
  149. print (len(tiles))
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement