Advertisement
Guest User

aoc_2021_18

a guest
Dec 18th, 2021
241
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 3.60 KB | None | 0 0
  1. def parse(s):
  2.     '''
  3.    Parse string into a list of list...
  4.    string e.g. '[1,2]'
  5.    '''
  6.     if s.isnumeric():
  7.         return int(s)
  8.    
  9.     ptr = 1
  10.     open_brack = 0
  11.     v = []
  12.     while ptr < len(s)-1:
  13.         if s[ptr].isnumeric() and open_brack == 0:
  14.             v.append(s[ptr])
  15.         elif s[ptr] == '[':
  16.             open_brack += 1
  17.             if open_brack == 1:
  18.                 begin = ptr
  19.         elif s[ptr] == ']':
  20.             open_brack -= 1
  21.             if open_brack == 0:
  22.                 end = ptr
  23.                 v.append(s[begin:end+1])
  24.                
  25.         ptr += 1
  26.  
  27.     return [parse(v[0]), parse(v[1])]
  28.  
  29. def explode(arr, depth):
  30.     '''
  31.    if the bracket is surrounded by 4 outer bracket
  32.    it will be reduced to 0, and distribute the left and
  33.    right values out to the nearest int
  34.    '''
  35.     if type(arr) == list and depth==4:
  36.         left_v = arr[0]
  37.         right_v = arr[1]
  38.         return 0, left_v, right_v
  39.    
  40.     if type(arr) == int:
  41.         return arr, 0, 0
  42.    
  43.     update = [0, 0]
  44.     for i in range(2):
  45.         if type(arr[i]) == list:
  46.             arr[i], lv, rv= explode(arr[i], depth+1)
  47.             vs = [lv, rv]
  48.             # the left value of a left node will be sent upward
  49.             # same for the right value of a right node
  50.             update[i] = vs[i]
  51.            
  52.             # If there exist a neighbour, distribute the other
  53.             # value to the neighbour
  54.             if vs[(i+1)%2] > 0:
  55.                 if type(arr[(i+1)%2]) == int:
  56.                     arr[(i+1)%2] += vs[(i+1)%2]
  57.                 else:
  58.                     b = arr[(i+1)%2]
  59.                     while type(b) != int:
  60.                         if type(b[i]) == int:
  61.                             b[i] += vs[(i+1)%2]
  62.                             break
  63.                         else:
  64.                             b = b[i]
  65.                        
  66.     return arr, update[0], update[1]
  67.  
  68. def split(arr):
  69.     '''
  70.    Only perform on the left-most >=10 integer
  71.    '''
  72.     if type(arr)==int:
  73.         if arr>=10:
  74.             return [arr//2, arr//2+arr%2], True
  75.         else:
  76.             return arr, False
  77.    
  78.     for i in range(2):
  79.         arr[i], splited = split(arr[i])
  80.         if splited:
  81.             return arr, splited
  82.     return arr, splited
  83.  
  84. def depth(arr):
  85.     if type(arr) == int:
  86.         return 0
  87.     return max(depth(arr[0])+1, depth(arr[1])+1)
  88.  
  89. def value(arr):
  90.     if type(arr) == int:
  91.         if arr >= 10:
  92.             return False
  93.         else:
  94.             return True
  95.     return value(arr[0]) and value(arr[1])
  96.  
  97. def snail_sum(arr):
  98.     if type(arr) == int:
  99.         return arr
  100.    
  101.     return 3*snail_sum(arr[0])+2*snail_sum(arr[1])
  102.  
  103. ####################################################
  104. with open('input_day18.txt') as f:
  105.     snail = f.readlines()
  106.     for i, v in enumerate(snail):
  107.         snail[i] = snail[i].strip()
  108.  
  109. # part 1, find the sum....
  110. s0 = parse(snail[0])
  111. for s in snail[1:]:
  112.     s1 = parse(s)
  113.     new_s = [s0, s1]
  114.     #print(new_s)
  115.     while depth(new_s)>=5 or not value(new_s):
  116.         new_s = explode(new_s, 0)[0]
  117.         new_s = split(new_s)[0]
  118.        
  119.     s0 = new_s
  120. print(snail_sum(s0))
  121.  
  122. # part 2, largest sum?
  123. max_sum = 0
  124. for i in range(len(snail)):
  125.     for j in range(len(snail)):
  126.         if i == j:
  127.             continue
  128.         s0 = parse(snail[i])
  129.         s1 = parse(snail[j])
  130.         new_s = [s0, s1]
  131.         while depth(new_s)>=5 or not value(new_s):
  132.             new_s = explode(new_s, 0)[0]
  133.             new_s = split(new_s)[0]
  134.         max_sum = max(max_sum, snail_sum(new_s))
  135. print(max_sum)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement