Advertisement
illuminati229

AoC Day 12

Dec 13th, 2021
238
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 3.14 KB | None | 0 0
  1. from collections import Counter
  2.  
  3. class NodeList:
  4.  
  5.     def __init__(self):
  6.         self.nodes =[]
  7.        
  8.     def add_node(self,name):
  9.         self.nodes.append(Node(name))
  10.  
  11.  
  12.     def get_names(self):
  13.         return [x.name for x in self.nodes]
  14.  
  15.     def find_by_name(self, name):
  16.         return self.nodes[self.get_names().index(name)]
  17.  
  18.     def __getitem__(self, i):
  19.         return self.nodes[i]
  20.  
  21.     def __len__(self):
  22.         return len(self.nodes)
  23.        
  24. class Node:
  25.  
  26.     def __init__(self, name):
  27.         self.name = name
  28.         self.neighbors = []
  29.         if name.islower():
  30.             self.size = 'small'
  31.         else:
  32.             self.size = 'big'
  33.  
  34.     def add_neighbor(self, nb):
  35.         self.neighbors.append(nb)
  36.  
  37. def sde(check_path):
  38.  
  39.     smalls = []
  40.     for entry in check_path:
  41.         if entry.size == 'small':
  42.             smalls.append(entry)
  43.            
  44.     counted = Counter(smalls)
  45.  
  46.     for count in counted.values():
  47.         if count == 2:
  48.             return True
  49.  
  50.     return False
  51.  
  52. def take_a_step(path, found_paths, sda):
  53.  
  54.     for nb in path[-1].neighbors:
  55.         if nb.name == 'end':
  56.             found_paths.append(path + [nb])
  57.         elif nb.name == 'start':
  58.             pass                
  59.         elif nb.size =='big':            
  60.             found_paths = take_a_step(path +[nb], found_paths, sda)
  61.         elif not sda:
  62.             if nb.size == 'small' and nb not in path:
  63.                 found_paths = take_a_step(path + [nb], found_paths, sda)
  64.             elif nb.size == 'small' and nb in path:
  65.                 pass
  66.         elif sda:
  67.             if nb.size == 'small' and nb not in path:
  68.                 found_paths = take_a_step(path + [nb], found_paths, sda)
  69.             elif nb.size == 'small' and nb in path and not sde(path):
  70.                 found_paths = take_a_step(path + [nb], found_paths, sda)
  71.             else:
  72.                 pass          
  73.  
  74.     return found_paths
  75.  
  76.  
  77. def find_path(file_path, sda):
  78.  
  79.     with open(file_path) as fin:
  80.         connections = [x.split('-') for x in fin.read().strip().split('\n')]
  81.  
  82.     nodes = NodeList()
  83.    
  84.     for conn in connections:
  85.         if conn[0] not in nodes.get_names():
  86.             nodes.add_node(conn[0])
  87.         if conn[1] not in nodes.get_names():
  88.             nodes.add_node(conn[1])
  89.  
  90.     for conn in connections:
  91.         nodes.find_by_name(conn[0]).add_neighbor(nodes.find_by_name(conn[1]))
  92.         nodes.find_by_name(conn[1]).add_neighbor(nodes.find_by_name(conn[0]))
  93.        
  94.     start = nodes.find_by_name('start')
  95.  
  96.     path = [start]
  97.     found_paths = []
  98.  
  99.     found_paths = take_a_step(path, found_paths, sda)
  100.  
  101.     return len(found_paths)
  102.    
  103.    
  104. def main():
  105.  
  106.     assert find_path('test_input1.txt', False) == 10
  107.     assert find_path('test_input2.txt', False) == 19
  108.     assert find_path('test_input3.txt', False) == 226
  109.     print(find_path('input.txt', False))
  110.  
  111.     assert find_path('test_input1.txt', True) == 36
  112.     assert find_path('test_input2.txt', True) == 103
  113.     assert find_path('test_input3.txt', True) == 3509
  114.     print(find_path('input.txt', True))
  115.  
  116. if __name__ == '__main__':
  117.     main()
  118.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement