diff --git a/2021/d16.py b/2021/d16.py new file mode 100644 index 0000000..e4edc82 --- /dev/null +++ b/2021/d16.py @@ -0,0 +1,85 @@ +from lib import get_data + + +data = get_data(__file__) + +bs = "" +for c in data.strip(): + b = bin(int(c, 16))[2:] + b = "0" * (4 - len(b)) + b + bs += b + +total_v = 0 + + +def parse(bs: str, i: int): + v = int(bs[i : i + 3], 2) + global total_v + total_v += v + i += 3 + t = int(bs[i : i + 3], 2) + i += 3 + + # print(v, t) + if t == 4: + lv = "" + while True: + seg = bs[i : i + 5] + lv += seg[1:] + i += 5 + if seg[0] == "0": + break + lv = int(lv, 2) + return i, lv + + vs = [] + if bs[i] == "0": + # total length of bits + i += 1 + bits = int(bs[i : i + 15], 2) + i += 15 + i_max = i + bits + while True: + i, v = parse(bs, i) + vs.append(v) + if i >= i_max: + break + elif bs[i] == "1": + # number of sub-packets + i += 1 + num_sub = int(bs[i : i + 11], 2) + i += 11 + vs = [] + for _ in range(num_sub): + i, v = parse(bs, i) + vs.append(v) + else: + assert False + + if t == 0: + return i, sum(vs) + elif t == 1: + x = 1 + for v in vs: + x *= v + return i, x + elif t == 2: + return i, min(vs) + elif t == 3: + return i, max(vs) + elif t == 5: + assert len(vs) == 2 + return i, 1 if vs[0] > vs[1] else 0 + elif t == 6: + assert len(vs) == 2 + return i, 1 if vs[0] < vs[1] else 0 + elif t == 7: + assert len(vs) == 2 + return i, 1 if vs[0] == vs[1] else 0 + else: + assert False + + +p2 = parse(bs, 0)[1] +print(total_v) +print(p2) diff --git a/README.md b/README.md index 48acb77..0ab955a 100644 --- a/README.md +++ b/README.md @@ -187,7 +187,8 @@ Solutions and utility script for Advent of Code challenges in Python. - Day 13: 16:48 (Should have been way faster.) - Day 14: 25:52 (Not hard but just too slow.) - Day 15: 19:17 (Not that bad. Multiplying the thing threw me off.) -- Day 16: +- Day 16: 50:01 (Way too slow. Was non-trivial but fun. Much better was feasible.) +- Day 17: ## AoC 2022