Advertisement
Guest User

Untitled

a guest
Dec 10th, 2024
55
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 3.54 KB | None | 0 0
  1. def add_vecs(vec1, vec2):
  2.     return (vec1[0] + vec2[0], vec1[1] + vec2[1])
  3.  
  4. class Walker:
  5.     destinations_found = {}
  6.     walkers = []
  7.     def __init__(self, start: tuple, themap: list[str], current_location: tuple = None) -> None:
  8.         self._start = start
  9.         self._current_location = current_location
  10.         if not self._current_location:
  11.             self._current_location = self._start
  12.         self._themap = themap
  13.         self._map_height = len(themap)
  14.         self._map_width = len(themap[0])
  15.         self._done = False
  16.         self._found_peak = False
  17.         self._peak_location = None
  18.  
  19.         if self._start not in Walker.destinations_found:
  20.             Walker.destinations_found[self._start] = set()
  21.  
  22.         Walker.walkers.append(self) # add self to list
  23.  
  24.     def step(self) -> None:
  25.         if self._done:
  26.             return
  27.         # at each step I look at the numbers around me and if any are
  28.         # 1 step higher then that's a direction I can go. If there are
  29.         # more than one possibility, I choose one and create new
  30.         # Walkers for the other choices
  31.         current_elevation = int(self._themap[self._current_location[1]][self._current_location[0]])
  32.         if current_elevation == 9: # This walker is done
  33.             self._done = True
  34.             self._found_peak = True
  35.             self._peak_location = self._current_location
  36.             Walker.destinations_found[self._start].add(self._current_location)
  37.             return
  38.         new_locations = self._get_possible_next_locations(current_elevation)
  39.         if len(new_locations) == 0: # this walker is done, it hit a dead end
  40.             self._done = True
  41.             self._found_peak = False
  42.             return
  43.         self._current_location = new_locations[0]
  44.         if len(new_locations) > 1:
  45.             for location in new_locations[1:]:
  46.                 Walker(self._start, self._themap, location) # create new Walker for each remaining location
  47.  
  48.     def _get_from_map(self, loc):
  49.         if loc[0] < 0 or loc[0] >= self._map_width:
  50.             return None
  51.         if loc[1] < 0 or loc[1] >= self._map_height:
  52.             return None
  53.         return int(self._themap[loc[1]][loc[0]])
  54.  
  55.     def _get_possible_next_locations(self, current_elevation):
  56.         possible_locations = []
  57.         for direction in [(0,-1), (1,0), (0,1), (-1,0)]:
  58.             new_loc = add_vecs(self._current_location, direction)
  59.             elevation = self._get_from_map(new_loc)
  60.             if elevation and elevation == current_elevation + 1:
  61.                 possible_locations.append(new_loc)
  62.         return possible_locations
  63.  
  64.     def __repr__(self):
  65.         return f"Walker at {self._current_location} done: {self._done}"
  66.  
  67.     @property
  68.     def done(self) -> bool:
  69.         return self._done
  70.  
  71.     @property
  72.     def found_peak(self) -> bool:
  73.         return self._found_peak
  74.  
  75.  
  76. with open('data.txt', 'r') as f:
  77.     input = f.read()
  78.  
  79. lines = input.split('\n')
  80.  
  81. starting_locations = []
  82. for j in range(len(lines)):
  83.     line = lines[j]
  84.     for i in range(len(line)):
  85.         if line[i] == '0':
  86.             starting_locations.append((i, j))
  87.  
  88. for loc in starting_locations:
  89.     Walker(loc, lines)
  90.  
  91. while not all([w.done for w in Walker.walkers]): # while not all walkers done
  92.     for w in Walker.walkers:
  93.         w.step()
  94.  
  95. sum = 0
  96. for k in Walker.destinations_found.keys():
  97.     sum += len(Walker.destinations_found[k])
  98.  
  99. print(f"Part 1: {sum}")
  100.  
  101. count = 0
  102. for w in Walker.walkers:
  103.     if w._found_peak:
  104.         count += 1
  105.  
  106. print(f"Part 2: {count}")
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement