Guest User

Advent of Code day 22 - part 2 Python

a guest
Dec 22nd, 2022
81
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 6.03 KB | Source Code | 0 0
  1. import numpy as np
  2.  
  3. direction_name = {0 : "right", 1 : "down", 2 : "left", 3 : "up"}
  4.  
  5. direction_code = {"right" : 0, "down": 1, "left" : 2, "up" : 3}
  6.  
  7. zone_link = {(1,0):(2,0), (1,1):(4,1), (1,2):(6,0), (1,3):(9,0), \
  8.              (2,0):(7,2), (2,1):(4,2), (2,2):(1,2), (2,3):(9,3), \
  9.              (4,0):(2,3), (4,1):(7,1), (4,2):(6,1), (4,3):(1,3), \
  10.              (6,0):(7,0), (6,1):(9,1), (6,2):(1,0), (6,3):(4,0), \
  11.              (7,0):(2,2), (7,1):(9,2), (7,2):(6,2), (7,3):(4,3), \
  12.              (9,0):(7,3), (9,1):(2,1), (9,2):(1,1), (9,3):(6,3)}
  13.  
  14. direction_coord_change = {0 : (1,0), 1 : (0,1), 2 : (-1,0), 3 : (0,-1)}
  15.  
  16. lines = puzzle_input.split("\n")
  17.  
  18. field_strings = lines[:-2]
  19. instruction_line = lines[-1]
  20.  
  21. complete_field = np.zeros((len(max(field_strings,key=len)),len(field_strings)))
  22.  
  23. for y_pos,line in enumerate(field_strings):
  24.     for x_pos in range(len(line)):
  25.         if line[x_pos] == ".":
  26.             complete_field[x_pos,y_pos] = 1
  27.         elif  line[x_pos] == "#":
  28.             complete_field[x_pos,y_pos] = 2
  29.  
  30. # split field in zones
  31. zone_field = np.zeros((12,50,50))
  32. for zone_y in range(4):
  33.     for zone_x in range(3):
  34.         zone_id = zone_x+zone_y*3
  35.         zone_field[zone_id,:,:] = complete_field[zone_x*50:(zone_x+1)*50,zone_y*50:(zone_y+1)*50]
  36.  
  37. # Initialize location
  38. zone = 1
  39. x_pos = 0
  40. y_pos = 0
  41. direction = 0
  42.  
  43. # Process instructions
  44. instructions = []
  45. index = 0
  46. while index < len(instruction_line):
  47.     if instruction_line[index] == "R":
  48.         instructions.append("R")
  49.         index += 1
  50.     elif instruction_line[index] == "L":
  51.         instructions.append("L")
  52.         index += 1
  53.     else:
  54.         length = 0
  55.         eol = False
  56.         while not eol:
  57.             length += 1
  58.             if index+length >= len(instruction_line):
  59.                 eol = True
  60.             elif (instruction_line[index+length] == "R") or (instruction_line[index+length] == "L"):
  61.                 eol = True
  62.         instructions.append(int(instruction_line[index:index+length]))
  63.         index += length
  64. print("Start position: (",x_pos,",",y_pos,")")
  65.  
  66. route = []
  67.  
  68. # Execute instructions:
  69. for instruction in instructions:
  70.     if instruction == "R":
  71.         direction = (direction + 1) % 4
  72.         print("Turning right, now facing",direction_name[direction])
  73.     elif instruction == "L":
  74.         direction = (direction - 1) % 4
  75.         print("Turning left, now facing",direction_name[direction])
  76.     else:
  77.         print("Moving",instruction,"steps forward")
  78.         for step in range(instruction):
  79.             target_x_pos = x_pos + direction_coord_change[direction][0]
  80.             target_y_pos = y_pos + direction_coord_change[direction][1]
  81.             target_zone = zone
  82.             target_direction = direction
  83.            
  84.             # Wraparound!
  85.             if target_y_pos >= zone_field[zone].shape[1]:
  86.                 target_zone,target_direction = zone_link[(zone,direction)]
  87.                 if target_direction == 0: # right
  88.                     target_y_pos = 49 - target_x_pos
  89.                     target_x_pos = 0
  90.                 if target_direction == 1: # down
  91.                     target_y_pos = 0
  92.                 if target_direction == 2: # left
  93.                     target_y_pos = target_x_pos
  94.                     target_x_pos = 49
  95.                 if target_direction == 3: # up
  96.                     target_x_pos = 49 - target_pos_x
  97.                     target_y_pos = 49
  98.             elif target_y_pos < 0:
  99.                 target_zone,target_direction = zone_link[(zone,direction)]
  100.                 if target_direction == 0: # right
  101.                     target_y_pos = target_x_pos
  102.                     target_x_pos = 0
  103.                 if target_direction == 1: # down
  104.                     target_x_pos = 49 - target_pos_x
  105.                     target_y_pos = 0
  106.                 if target_direction == 2: # left
  107.                     target_y_pos = 49 - target_x_pos
  108.                     target_x_pos = 49
  109.                 if target_direction == 3: # up
  110.                     target_y_pos = 49
  111.             elif target_x_pos >= zone_field[zone].shape[0]:
  112.                 target_zone,target_direction = zone_link[(zone,direction)]
  113.                 if target_direction == 0: # right
  114.                     target_x_pos = 0
  115.                 if target_direction == 1: # down
  116.                     target_x_pos = 49 - target_y_pos
  117.                     target_y_pos = 0
  118.                 if target_direction == 2: # left
  119.                     target_x_pos = 49
  120.                     target_y_pos = 49 - target_y_pos
  121.                 if target_direction == 3: # up
  122.                     target_x_pos = target_y_pos
  123.                     target_y_pos = 49
  124.             elif target_x_pos < 0:
  125.                 target_zone,target_direction = zone_link[(zone,direction)]
  126.                 if target_direction == 0: # right
  127.                     target_x_pos = 0
  128.                     target_y_pos = 49 - target_y_pos
  129.                 if target_direction == 1: # down
  130.                     target_x_pos = target_y_pos
  131.                     target_y_pos = 0
  132.                 if target_direction == 2: # left
  133.                     target_x_pos = 49
  134.                 if target_direction == 3: # up
  135.                     target_x_pos = 49 - target_y_pos
  136.                     target_y_pos = 49
  137.             if zone_field[target_zone][target_x_pos][target_y_pos] == 2:
  138.                 print("Hit a wall, stopping!")
  139.                 break
  140.             else:
  141.                 x_pos = target_x_pos
  142.                 y_pos = target_y_pos
  143.                 direction = target_direction
  144.                 zone = target_zone
  145.             route.append((zone,x_pos,y_pos))
  146.         print("Now at position (",x_pos,",",y_pos,")")
  147.  
  148. # Correct coordinates (not just on face of cube but on folded out map:
  149. zone_x = zone % 3
  150. zone_y = (zone - zone_x) // 3
  151. x_pos += zone_x * 50
  152. y_pos += zone_y * 50
  153. print("Final coordinate: (",x_pos+1,",",y_pos+1,")")
  154. print("Final direction:",direction_name[direction])
  155. solution = (y_pos + 1) * 1000 + (x_pos + 1) * 4 + direction
  156. print("Final password:",solution)
Advertisement
Add Comment
Please, Sign In to add comment