Advertisement
Guest User

aoc18

a guest
Dec 18th, 2021
365
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 2.52 KB | None | 0 0
  1. import math, itertools
  2.  
  3. class Tree:
  4.     def __init__(self, string = ""):
  5.         depth = 0
  6.         self.left = self.right = self.parent = None
  7.         for pos,ch in enumerate(string[1:-1]):
  8.             if ch == '[':
  9.                 depth += 1
  10.             elif ch == ']':
  11.                 depth -= 1
  12.             elif ch == ',' and depth == 0:
  13.                 self.left = Tree(string[1:pos+1])
  14.                 self.right = Tree(string[pos+2:-1])
  15.                 self.left.parent = self.right.parent = self
  16.                 break
  17.         self.value = int(string) if string.isnumeric() and not self.left else None
  18.  
  19.     def __add__(self, other):
  20.         tree = Tree()
  21.         tree.left = Tree(str(self))
  22.         tree.right = Tree(str(other))
  23.         tree.left.parent = tree
  24.         tree.right.parent = tree
  25.         while (tree.explode(0) or tree.split()) : continue
  26.         return tree
  27.  
  28.     def __radd__(self, other):
  29.         if other == 0: return self
  30.         else: return self.__add__(other)
  31.  
  32.     def  __repr__(self):
  33.         if bool(not self.left): return str(self.value);
  34.         else: return "[" + str(self.left) + "," + str(self.right) + "]"
  35.  
  36.     def split(self):
  37.         if self.value and self.value > 9:
  38.             self.left = Tree(str(math.floor(self.value/2)))
  39.             self.right = Tree(str(math.ceil(self.value/2)))
  40.             self.left.parent = self.right.parent = self
  41.             self.value = None
  42.             return True
  43.         if self.left:
  44.             return self.left.split() or self.right.split()
  45.         return False
  46.  
  47.     def explode(self, depth):
  48.         if self.left:
  49.             if depth == 4 and not self.left.left and not self.right.left:
  50.                
  51.                 leftVal = self.parent
  52.                 oldVal = self
  53.                 while (leftVal and leftVal.left == oldVal):
  54.                     oldVal = leftVal
  55.                     leftVal = leftVal.parent
  56.                 if (leftVal): leftVal = leftVal.left
  57.                 while leftVal and leftVal.right: leftVal = leftVal.right
  58.  
  59.                 rightVal = self.parent
  60.                 oldVal = self
  61.                 while (rightVal and rightVal.right == oldVal):
  62.                     oldVal = rightVal
  63.                     rightVal = rightVal.parent
  64.                 if (rightVal): rightVal = rightVal.right
  65.                 while rightVal and rightVal.left: rightVal = rightVal.left
  66.  
  67.                 if leftVal: leftVal.value += self.left.value
  68.                 if rightVal: rightVal.value += self.right.value
  69.                 self.left = None
  70.                 self.right = None
  71.                 self.value = 0
  72.  
  73.                 return True
  74.             return self.left.explode(depth+1) or self.right.explode(depth+1)
  75.         return False
  76.  
  77.     def magnitude(self):
  78.         if self.left:
  79.             return 3*self.left.magnitude() + 2*self.right.magnitude()
  80.         else:
  81.             return int(self.value)
  82.  
  83. trees = [Tree(line) for line in open('18.data').read().splitlines()]
  84. print("Part 1:", sum(trees).magnitude())
  85. print("Part 2:", max(tree.magnitude() for tree in [a + b for a, b in itertools.permutations(trees, 2)]))
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement