From ba48f135e0b52364c1ac765b227a06b8921a36c1 Mon Sep 17 00:00:00 2001 From: Tomasz Kramkowski Date: Sat, 18 Dec 2021 23:09:47 +0000 Subject: day 18: awful --- 18.py | 103 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 103 insertions(+) create mode 100644 18.py diff --git a/18.py b/18.py new file mode 100644 index 0000000..57d06ce --- /dev/null +++ b/18.py @@ -0,0 +1,103 @@ +from __future__ import annotations +from copy import deepcopy +from dataclasses import dataclass +from functools import reduce +from itertools import combinations +from math import floor, ceil +from utils import open_day + +@dataclass +class Pair: + car: int | Pair + cdr: int | Pair + def __repr__(self) -> str: + return f'[{self.car},{self.cdr}]' + +def car(p, assign=None): + if assign is not None: + p.car = assign + return p.car +def cdr(p, assign=None): + if assign is not None: + p.cdr = assign + return p.cdr + +def is_pair(p): return isinstance(p, Pair) + +def parse(s): return eval(s.replace('[', 'Pair(').replace(']', ')')) + +with open_day(18) as f: + homework = [parse(l) for l in f] + +def try_explode(n): + def try_add(n, val, primary, secondary): + if val == 0: return 0 + if is_pair(primary(n)): + val = try_add(primary(n), val, primary, secondary) + else: + primary(n, primary(n) + val) + return 0 + if val != 0: + if is_pair(secondary(n)): + val = try_add(secondary(n), val, primary, secondary) + else: + secondary(n, secondary(n) + val) + return 0 + return val + def descend(n, depth=0): + if not is_pair(n): return None + if depth == 4: return n + car_val = descend(n.car, depth + 1) + if car_val is not None: + if depth == 3: n.car = 0 + if not is_pair(n.cdr): + n.cdr += car_val.cdr + car_val.cdr = 0 + return Pair(car_val.car, try_add(n.cdr, car_val.cdr, car, cdr)) + else: + cdr_val = descend(n.cdr, depth + 1) + if cdr_val is not None: + if depth == 3: n.cdr = 0 + if not is_pair(n.car): + n.car += cdr_val.car + cdr_val.car = 0 + return Pair(try_add(n.car, cdr_val.car, cdr, car), cdr_val.cdr) + return descend(n) + +tests = [ + ('[[[[[9,8],1],2],3],4]', '[[[[0,9],2],3],4]'), + ('[7,[6,[5,[4,[3,2]]]]]', '[7,[6,[5,[7,0]]]]'), + ('[[6,[5,[4,[3,2]]]],1]', '[[6,[5,[7,0]]],3]'), + ('[[3,[2,[1,[7,3]]]],[6,[5,[4,[3,2]]]]]', '[[3,[2,[8,0]]],[9,[5,[4,[3,2]]]]]'), + ('[[3,[2,[8,0]]],[9,[5,[4,[3,2]]]]]', '[[3,[2,[8,0]]],[9,[5,[7,0]]]]'), +] + +for test, expect in tests: + test = parse(test) + try_explode(test) + assert(test == parse(expect)) + +def try_split(n, access=lambda n: n): + content = access(n) + if is_pair(content): + return try_split(content, car) or try_split(content, cdr) + if content < 10: return False + content /= 2 + access(n, Pair(floor(content), ceil(content))) + return True + +def reduce_num(n): + n = deepcopy(n) + while True: + if try_explode(n): continue + if try_split(n): continue + break + return n + +def magnitude(n): + if is_pair(n): + return 3 * magnitude(n.car) + 2 * magnitude(n.cdr) + return n + +print(magnitude(reduce(lambda a, b: reduce_num(Pair(a, b)), homework))) +print(max(max(magnitude(reduce_num(Pair(a, b))), magnitude(reduce_num(Pair(b, a)))) for a, b in combinations(homework, 2))) -- cgit v1.2.3-54-g00ecf