Guest User

Untitled

a guest
Dec 7th, 2024
188
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 3.67 KB | None | 0 0
  1. part2.py ========================================================================
  2.  
  3. from lib import find_caret,turn_right, guard_on_map, \
  4.     new_position, guard_facing_obstacle, add_obstacle_to_map, loop_detected
  5.  
  6. with open('data.txt', 'r') as f:
  7.     data = f.read()
  8.  
  9. map = data.split('\n')
  10.  
  11. # This will hold a record of every position the guard will occupy
  12. # and the direction they were going when in that position
  13. position_history = set()
  14.  
  15. caret_position = find_caret(map)
  16. guard_position = caret_position
  17. direction = (0, -1)
  18.  
  19. # first we create a record of all the positions the
  20. # guard will occupy on the normal route.
  21. while guard_on_map(map, guard_position):
  22.  
  23.     if guard_position != caret_position: # we can't put an obstacle in the original guard position
  24.         position_history.add(guard_position)
  25.  
  26.     if guard_facing_obstacle(map, guard_position, direction):
  27.         direction = turn_right(direction)
  28.     else:
  29.         guard_position = new_position(guard_position, direction)
  30.  
  31.  
  32. # go through the position history and try placing an obstacle
  33. # in each location to see if it results in a loop
  34. positions_causing_loops = []
  35.  
  36. for position in position_history:
  37.     new_map = map[:]
  38.     add_obstacle_to_map(new_map, position)
  39.     if loop_detected(new_map, caret_position, (0,-1)):
  40.         positions_causing_loops.append(position)
  41.  
  42. print(len(positions_causing_loops))
  43.  
  44.  
  45. lib.py ==============================================================================
  46.  
  47. def find_caret(map):
  48.     y = 0
  49.     for line in map:
  50.         if '^' in line:
  51.             x = line.find('^')
  52.             return (x, y)
  53.         y += 1
  54.  
  55.     print('caret not found')
  56.     exit()
  57.  
  58. def turn_right(direction):
  59.     if direction == (-1,0):
  60.         return (0,-1)
  61.     if direction == (0,-1):
  62.         return (1,0)
  63.     if direction == (1,0):
  64.         return (0,1)
  65.     if direction == (0,1):
  66.         return (-1,0)
  67.     print('invalid direction')
  68.     exit()
  69.  
  70. def guard_on_map(map, position):
  71.     width = len(map[0])
  72.     height = len(map)    
  73.     if position[0] < 0 or position[1] < 0:
  74.         return False
  75.     if position[0] >= width:
  76.         return False
  77.     if position[1] >= height:
  78.         return False
  79.     return True
  80.  
  81.  
  82. def mark_guard_position(map, position):
  83.     add_char_to_map(map, position, 'X')
  84.  
  85. def add_obstacle_to_map(map, position):
  86.     add_char_to_map(map, position, '#')
  87.    
  88. def add_char_to_map(map, position, char):
  89.     line = map[position[1]]
  90.     char_list = list(line)
  91.     if char_list[position[0]] == '#' and char != '#':
  92.         print("Uh-ohhh, you're overwriting a barrier")
  93.         exit()
  94.     if char_list[position[0]] == '^' and char == '#':
  95.         print("Uh-ohhh, you're overwriting the carrot")
  96.         exit()
  97.     char_list[position[0]] = char
  98.     map[position[1]] = ''.join(char_list)
  99.  
  100. def new_position(pos, dir):
  101.     return (pos[0] + dir[0], pos[1] + dir[1])
  102.  
  103. def guard_facing_obstacle(map, pos, dir):
  104.     new_pos = new_position(pos, dir)
  105.     try:
  106.         if map[new_pos[1]][new_pos[0]] == '#':
  107.             return True
  108.     except IndexError:
  109.         pass
  110.     return False
  111.  
  112. def loop_detected(map, pos, dir):
  113.     # we start following the path until we either
  114.     # revisit a position, in which case we found a loop
  115.     # or we go off the board, in which case there
  116.     # is no loop
  117.     position_history = set() # records position and direction
  118.  
  119.     while guard_on_map(map, pos):
  120.         if pos + dir in position_history:
  121.             return True
  122.         position_history.add(pos + dir)
  123.         if guard_facing_obstacle(map, pos, dir):
  124.             dir = turn_right(dir)
  125.         else:
  126.             pos = new_position(pos, dir)
  127.  
  128.     return False
Advertisement
Add Comment
Please, Sign In to add comment