import math import sys def check_nested(inp): peg_counter = 0 found = False found2 = False pair = '' high_peg = None for i in range(len(inp)): if inp[i] == '[': peg_counter += 1 if peg_counter > 4: found = True high_peg = peg_counter pair = '' start = i if inp[i] == ']': peg_counter -= 1 if found: pair += inp[i] if found and peg_counter == high_peg - 1: end = i found2 = True break if found2: #print('Exploding ', pair) pair = pair[1:-1] left, rigth = pair.split(',') tempnum = '' digit_check = False for i in range(end, len(inp)): if inp[i].isdigit(): digit_check = True digit_start = i tempnum += inp[i] #print('tempnum: ', tempnum) if (inp[i] == ',' or inp[i] == ']') and digit_check: # print('Replacing ', inp[i - len(tempnum):i], ' with ', str(int(tempnum) + int(rigth)), ' (', str(tempnum), ' + ' , str(rigth) + ')') inp = inp[:i - len(tempnum)] + str(int(tempnum) + int(rigth)) + inp[i:] break # print('Replacing ', inp[start:end+1], ' with zero') # print('B: ', inp) inp = inp[:start] + '0' + inp[end + 1:] # print('A: ', inp) tempnum = '' digit_check = False for i in range(start - 1, 0, -1): if inp[i].isdigit(): digit_check = True digit_start = i tempnum = inp[i] + tempnum if (inp[i] == ',' or inp[i] == '[' ) and digit_check: # print('Replacing ', inp[i+1:i+len(tempnum)+1], ' with ', str(int(tempnum) + int(left))) inp = inp[:i + 1] + str(int(tempnum) + int(left)) + inp[len(tempnum) + i + 1:] break # print(inp) return (inp, found2) def check_split(inp): checkmarker = 0 found = False for i in range(len(inp)): if inp[i].isdigit(): checkmarker += 1 else: checkmarker = 0 if checkmarker == 2: number_pos = i number = int(inp[i-1] + inp[i]) number = number/2 found = True break if found: new_pair = '[' + str(math.trunc(number)) + ',' + str(math.ceil(number)) + ']' #print('Replacing ', inp[number_pos - 1:number_pos+1], ' with ', new_pair) inp = inp[:number_pos - 1] + new_pair + inp[number_pos + 1:] #print(inp) return (inp, found) def magnitude(inp): found = False number = '' start = None end = None for i in range(len(inp)): if inp[i] == '[': start = i if inp[i] == ']': end = i break if start is None: start = 0 if end is None: end = len(inp) for i in range(start, end): number += inp[i] if ',' in number: found = True left, rigth = number.split(',') left = left[1:] number = str(int(left)*3 + int(rigth)*2) inp = inp[:start] + number + inp[end + 1:] else: inp = number return (inp, found) def reduct(inp): reduction = True while reduction: eplode = True split = True while eplode: inp, eplode = check_nested(inp) reduction = False inp, split = check_split(inp) if split: reduction = True return(inp) inp = [] with open(sys.argv[1], 'r') as f: for g in f.readlines(): g = g.strip() inp.append(g) if sys.argv[2] == 'part1': imp = inp[0] inp.pop(0) while len(inp) > 0: print('___________________') print(imp) print('+', inp[0]) imp = '[' + imp + ',' + inp[0] + ']' inp.pop(0) imp = reduct(imp) print('=', imp) print('___________________') done_check = True while done_check: imp, done_check = magnitude(imp) print(imp, done_check) if sys.argv[2] == 'part2': high_mag = 0 for i in inp: for f in inp: if f != i: imp = '[' + i + ',' + f + ']' imp = reduct(imp) done_check = True while done_check: imp, done_check = magnitude(imp) if int(imp) > high_mag: high_mag = int(imp) print(high_mag)