Advertisement
Guest User

advent_of_code_2019_day6

a guest
Dec 7th, 2019
769
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 4.19 KB | None | 0 0
  1. import re
  2.  
  3.  
  4. class GraphNode:
  5.     '''a Node class for representing nodes in a graph'''
  6.     def __init__(self, name=None, jumps=0, children=set(), path=[]):
  7.         self.name = name
  8.         self.jumps = jumps # jumps represents the number of jumps/'links' from the root node
  9.         self.children = children # this is a set with pointers to child nodes
  10.         self.path = path # this is a list with the names of all nodes leading from the root node to the self node
  11.    
  12.     def __str__(self):
  13.         return str(self.name)
  14.    
  15.     def add_connection(self, connect_node):
  16.         '''adds a Node instance to the set of children'''
  17.         self.children.add(connect_node)
  18.  
  19.  
  20. class QueueNode:
  21.     '''a Node class for representing nodes in a queue (that can only have one child node)'''
  22.     def __init__(self, cargo=None):
  23.         self.cargo = cargo
  24.         self.next = None
  25.    
  26.     def __str__(self):
  27.         return str(self.cargo)
  28.  
  29.  
  30. class Queue:
  31.     '''a Queue class that uses QueueNodes for implementing a FIFO data structure'''
  32.     def __init__(self):
  33.         self.head = None
  34.         self.tail = None
  35.    
  36.     def insert(self, cargo):
  37.         '''inserts a QueueNode instance with the specified cargo (i. e. GraphNode instance) to the end of the queue'''
  38.         node = QueueNode(cargo)
  39.         if self.head is None:
  40.             self.tail = self.head = node
  41.         else:
  42.             self.tail.next = node
  43.             self.tail = node
  44.    
  45.     def remove(self):
  46.         '''removes the QueueNode instance at the front of the queue and returns its cargo (i. e. GraphNode instance)'''
  47.         rmcargo = self.head.cargo
  48.         if self.head.next:
  49.             self.head = self.head.next
  50.         else:
  51.             self.head = None
  52.         return rmcargo
  53.  
  54.  
  55. with open('/Users/lowe/Documents/Programmering/Python/Python projects/advent_of_code/day6/input', 'r') as f:
  56.     instr = f.read()
  57.  
  58. orb_str_ls = instr.split('\n')
  59. orb_str_ls = orb_str_ls[:len(orb_str_ls)-1] # creates a list of all children (removing the empty string in the last list pos)
  60.  
  61. # dir_orb = len(orb_str_ls) # number of direct orbits is number of children (not actually needed I think)
  62.  
  63. orb_dict = {} # creates a dictionary object for orbits, where keys are center objects and values are sets of objects orbiting the center obj
  64.  
  65. for i in orb_str_ls:
  66.     cent_obj, orb_obj = re.search("^(.+)\)(.+)", i).groups()
  67.     if orb_dict.get(cent_obj):
  68.         orb_dict[cent_obj].add(orb_obj)
  69.     else:
  70.         orb_dict[cent_obj] = {orb_obj}
  71.  
  72. gnod1 = GraphNode(name="COM", jumps=0, children=set())
  73. orb_q = Queue()
  74. orb_q.insert(gnod1)
  75. tot_jumps = 0
  76. targ_dict = {} # target dictionary for 'SAN' and 'YOU'
  77.  
  78. while orb_q.head: # while queue isn't empty
  79.     par_nod = orb_q.remove() # remove the node first in line from the queue and refer to it by 'par_nod'
  80.     tot_jumps += par_nod.jumps
  81.     if not orb_dict.get(par_nod.name):
  82.         continue
  83.     for i in orb_dict[par_nod.name]: # for each orbit name connected to the parent node name key in orb_dict
  84.         child_nod = GraphNode(name=i, jumps=par_nod.jumps+1, children = set(), path = par_nod.path + [par_nod.name]) # create a graph node with the orbit name, and 1 more jump than the par_node
  85.         if i in ['SAN', 'YOU']:
  86.             targ_dict[i] = child_nod # add direct references to the 'SAN' and 'YOU' nodes
  87.         par_nod.children.add(child_nod) # add the new graph node to the parent node's children
  88.         orb_q.insert(child_nod) # add the child node to the queue so its children will be added to it in a later iteration
  89.  
  90. san_path = targ_dict['SAN'].path # get full path to 'SAN'
  91. you_path = targ_dict['YOU'].path
  92. total_dist = 0
  93. for i in range(len(you_path)-1, -1, -1):
  94.     for j in range(len(san_path)):
  95.         if you_path[i] == san_path[j]:
  96.             total_dist = len(you_path) - i + len(san_path) - j - 2 # len(you_path) - i gives the number of nodes from the common path node (inclusive) to the 'YOU' node. 2 has to be subtracted to make sure that 1) the common node isn't counted twice, and 2) to count the number of 'orbital transfers', see the homepage for explanation
  97.             break
  98.     if total_dist:
  99.         break
  100.  
  101. print("The total distance is: {}".format(total_dist))
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement