|
| 1 | +test = '''C200B40A82''' |
| 2 | +inp = open('Day 16.txt','r').read() |
| 3 | + |
| 4 | +def subpacket(inp): |
| 5 | + packet_version = int(inp[0:3],2) |
| 6 | + packet_type = int(inp[3:6],2) |
| 7 | + if packet_type == 4: |
| 8 | + current_bit = 6 |
| 9 | + while inp[current_bit] != '0': |
| 10 | + current_bit += 5 |
| 11 | + current_bit += 5 |
| 12 | + return current_bit, packet_version |
| 13 | + else: |
| 14 | + if inp[6] == '0': |
| 15 | + sub_length = int(inp[7:22],2) |
| 16 | + sub_inp = 22 |
| 17 | + elif inp[6] == '1': |
| 18 | + sub_length = int(inp[7:18],2) |
| 19 | + sub_inp = 18 |
| 20 | + while sub_length != 0: |
| 21 | + sub_bit, sub_version = subpacket(inp[sub_inp:]) |
| 22 | + sub_inp += sub_bit |
| 23 | + packet_version += sub_version |
| 24 | + if inp[6] == '0': sub_length -= sub_bit |
| 25 | + elif inp[6] == '1': sub_length -= 1 |
| 26 | + return sub_inp, packet_version |
| 27 | + |
| 28 | +def part1(inp): |
| 29 | + h_size = len(inp) * 4 |
| 30 | + h = (bin(int(inp, 16))[2:] ).zfill(h_size) |
| 31 | + print(subpacket(h)[1]) |
| 32 | + |
| 33 | +from math import prod |
| 34 | +def subpacket2(inp): |
| 35 | + packet_type = int(inp[3:6],2) |
| 36 | + if packet_type == 4: |
| 37 | + current_bit = 6 |
| 38 | + value = '' |
| 39 | + while inp[current_bit] != '0': |
| 40 | + value += inp[current_bit+1:current_bit+5] |
| 41 | + current_bit += 5 |
| 42 | + value += inp[current_bit+1:current_bit+5] |
| 43 | + current_bit += 5 |
| 44 | + value = int(value,2) |
| 45 | + return current_bit, value |
| 46 | + else: |
| 47 | + if inp[6] == '0': |
| 48 | + sub_length = int(inp[7:22],2) |
| 49 | + sub_inp = 22 |
| 50 | + elif inp[6] == '1': |
| 51 | + sub_length = int(inp[7:18],2) |
| 52 | + sub_inp = 18 |
| 53 | + sub_values = [] |
| 54 | + while sub_length != 0: |
| 55 | + sub_bit, sub_value = subpacket2(inp[sub_inp:]) |
| 56 | + sub_inp += sub_bit |
| 57 | + sub_values.append(sub_value) |
| 58 | + if inp[6] == '0': sub_length -= sub_bit |
| 59 | + elif inp[6] == '1': sub_length -= 1 |
| 60 | + match packet_type: |
| 61 | + case 0: return sub_inp, sum(sub_values) |
| 62 | + case 1: return sub_inp, prod(sub_values) |
| 63 | + case 2: return sub_inp, min(sub_values) |
| 64 | + case 3: return sub_inp, max(sub_values) |
| 65 | + case 5: return sub_inp, 1 if sub_values[0] > sub_values[1] else 0 |
| 66 | + case 6: return sub_inp, 1 if sub_values[0] < sub_values[1] else 0 |
| 67 | + case 7: return sub_inp, 1 if sub_values[0] == sub_values[1] else 0 |
| 68 | + |
| 69 | +def part2(inp): |
| 70 | + h_size = len(inp) * 4 |
| 71 | + h = (bin(int(inp, 16))[2:]).zfill(h_size) |
| 72 | + print(subpacket2(h)[1]) |
| 73 | + |
| 74 | +part1(inp) |
| 75 | +part2(inp) |
0 commit comments