| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798 |
- import os, sys
- task_dir = os.path.dirname(__file__)
- sys.path.append(f"{task_dir}/..")
- from functools import reduce
- from get_tasks import get_input, generate_readme, check_example
- def read_litval():
- global cur
- blitval = ""
- while b[cur : cur + 1] == "1":
- cur += 1
- blitval += b[cur : cur + 4]
- cur += 4
- cur += 1
- blitval += b[cur : cur + 4]
- cur += 4
- litval = int(blitval, 2)
- return litval
- def read_header():
- global typeID, packver, cur
- packver = int(b[cur : cur + 3], 2)
- cur += 3
- typeID = int(b[cur : cur + 3], 2)
- cur += 3
- def read_op():
- global cur
- litsub = []
- if b[cur : cur + 1] == "0":
- cur += 1
- nbits = int(b[cur : cur + 15], 2)
- cur += 15
- end_subpackets = cur + nbits
- while cur != end_subpackets:
- litsub += [parse_block()]
- return litsub
- else:
- cur += 1
- npacks = int(b[cur : cur + 11], 2)
- cur += 11
- n = 0
- while n != npacks:
- n += 1
- litsub += [parse_block()]
- return litsub
- def parse_block():
- global typeID, cur, sumpackver, sumval
- read_header()
- sumpackver += packver
- match typeID:
- case 4: return read_litval()
- case 0: return sum(read_op())
- case 1: return reduce(lambda x, y: x * y, read_op(), 1)
- case 2: return min(read_op())
- case 3: return max(read_op())
- case 5: subs = read_op(); return 1 if subs[0] > subs[1] else 0
- case 6: subs = read_op(); return 1 if subs[0] < subs[1] else 0
- case 7: subs = read_op(); return 1 if subs[0] == subs[1] else 0
- def part1(input):
- global b, cur, sumpackver
- cur = 0
- sumpackver = 0
- packet = input[0]
- b = bin(int(packet, 16))[2:].zfill(len(packet)*4)
- parse_block()
- print("The answer of part1 is:", sumpackver)
-
- def part2(input):
- global b, cur, sumpackver
- cur = 0
- sumpackver = 0
- packet = input[0]
- b = bin(int(packet, 16))[2:].zfill(len(packet)*4)
- val = parse_block()
- print("The answer of part1 is:", val)
- if __name__ == "__main__":
-
- input, example = get_input(task_dir, 16)
- print("PART1")
- for packet in example[3:7]:
- check_example([packet], part1)
- print("PART2")
- for packet in example[7:]:
- check_example([packet], part2)
-
- part1(input)
- part2(input)
-
- generate_readme(task_dir, 16)
|