From 4acc229c5a795715fef2226f92ef87f7b2795c47 Mon Sep 17 00:00:00 2001 From: felixm Date: Sun, 24 Nov 2024 18:50:28 -0500 Subject: [PATCH] Solve 2021 day 18 --- 2021/d18.py | 115 ++++++++++++++++++++++++++++++++++++++++++++++++++++ README.md | 38 +++++++++-------- 2 files changed, 135 insertions(+), 18 deletions(-) create mode 100644 2021/d18.py diff --git a/2021/d18.py b/2021/d18.py new file mode 100644 index 0000000..1a509c9 --- /dev/null +++ b/2021/d18.py @@ -0,0 +1,115 @@ +from lib import get_data +from math import ceil, floor +from itertools import combinations + +data = """[[[0,[5,8]],[[1,7],[9,6]]],[[4,[1,2]],[[1,4],2]]] +[[[5,[2,8]],4],[5,[[9,9],0]]] +[6,[[[6,2],[5,6]],[[7,6],[4,7]]]] +[[[6,[0,7]],[0,9]],[4,[9,[9,0]]]] +[[[7,[6,4]],[3,[1,3]]],[[[5,5],1],9]] +[[6,[[7,3],[3,2]]],[[[3,8],[5,7]],4]] +[[[[5,4],[7,7]],8],[[8,3],8]] +[[9,3],[[9,9],[6,[4,9]]]] +[[2,[[7,7],7]],[[5,8],[[9,3],[0,2]]]] +[[[[5,2],5],[8,[3,7]]],[[5,[7,5]],[4,4]]]""" +data = get_data(__file__) + + +def parse(line): + xs = list(line) + for i in range(len(xs)): + try: + xs[i] = int(xs[i]) + except ValueError: + pass + assert line == "".join(map(str, xs)) + return xs + + +def reduce(xs): + reduced, nesting = False, 0 + for i in range(len(xs)): + c = xs[i] + if c == "[" and nesting == 4 and not reduced: + lhs, rhs = xs[i + 1], xs[i + 3] + if not (type(lhs) is int and type(rhs) is int): + continue + xs = xs[:i] + [0] + xs[i + 5 :] + + for j in range(i - 1, -1, -1): + if type(xs[j]) is int: + xs[j] += lhs + break + + for j in range(i + 1, len(xs)): + if type(xs[j]) is int: + xs[j] += rhs + break + reduced = True + break + elif c == "[": + nesting += 1 + elif c == "]": + nesting -= 1 + + if not reduced: + for i in range(len(xs)): + c = xs[i] + if type(c) is int and c >= 10: + p = [floor(c / 2), ceil(c / 2)] + xs = xs[:i] + ["[", p[0], ",", p[1], "]"] + xs[i + 1 :] + reduced = True + break + return xs + + +def restore(xs): + return "".join(map(str, xs)) + + +assert restore(reduce(parse("[[[[[9,8],1],2],3],4]"))) == "[[[[0,9],2],3],4]" +assert restore(reduce(parse("[7,[6,[5,[4,[3,2]]]]]"))) == "[7,[6,[5,[7,0]]]]" +assert ( + restore(reduce(parse("[[3,[2,[1,[7,3]]]],[6,[5,[4,[3,2]]]]]"))) + == "[[3,[2,[8,0]]],[9,[5,[4,[3,2]]]]]" +) +assert ( + restore(reduce(parse("[[3,[2,[8,0]]],[9,[5,[4,[3,2]]]]]"))) + == "[[3,[2,[8,0]]],[9,[5,[7,0]]]]" +) + + +def add(a, b): + s = ["["] + a + [","] + b + ["]"] + while True: + ns = reduce(s) + if s == ns: + break + s = ns + return s + + +a = "[[[[4,3],4],4],[7,[[8,4],9]]]" +b = "[1,1]" +assert restore(add(parse(a), parse(b))) == "[[[[0,7],4],[[7,8],[6,0]]],[8,1]]" + +lines = list(data.splitlines()) +s = parse(lines[0].strip()) +for line in lines[1:]: + s = add(s, parse(line.strip())) + + +def get_mag(xs): + if type(xs) is int: + return xs + return get_mag(xs[0]) * 3 + get_mag(xs[1]) * 2 + + +print(get_mag(eval(restore(s)))) + +lines = list(data.splitlines()) +m = 0 +for a, b in combinations(lines, 2): + m = max(m, get_mag(eval(restore(add(parse(a), parse(b)))))) + m = max(m, get_mag(eval(restore(add(parse(b), parse(a)))))) +print(m) diff --git a/README.md b/README.md index fecf1cd..7906b29 100644 --- a/README.md +++ b/README.md @@ -172,24 +172,26 @@ Solutions and utility script for Advent of Code challenges in Python. ## AoC 2021 -- Day 1: 4:01 (Haha. Why am I so bad?!?!) -- Day 2: 6:36 (Okay. I might as well stop doing these.) -- Day 3: 23:46 (How long can I take when I try to take long?) -- Day 4: 22:18 (No way. Such stupid bugs.) -- Day 5: 13:30 (Decent, but obviously too slow.) -- Day 6: 16:33 (Right idea quickly but then struggled to implement.) -- Day 7: 6:12 (Decent, but too slow again, obviously. Maybe fast enough for part 1.) -- Day 8: 72:00 (Yeah, that was too much of a struggle.) -- Day 9: 8:07 (37th okay, okay) -- Day 10: 15:50 (I was pretty happy with that but double the 100th place.) -- Day 11: 11:43 (Could have been much faster here.) -- Day 12: 19:11 (Okayish, but of course too slow for leaderboard.) -- 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: 50:01 (Way too slow. Was non-trivial but fun. Much better was feasible.) -- Day 17: 21:59 (Not tricky again but struggling for no reason.) -- Day 18: +- Day 1: 4:01 (Haha. Why am I so bad?!?!) +- Day 2: 6:36 (Okay. I might as well stop doing these.) +- Day 3: 23:46 (How long can I take when I try to take long?) +- Day 4: 22:18 (No way. Such stupid bugs.) +- Day 5: 13:30 (Decent, but obviously too slow.) +- Day 6: 16:33 (Right idea quickly but then struggled to implement.) +- Day 7: 6:12 (Decent, but too slow again, obviously. Maybe fast enough for part 1.) +- Day 8: 72:00 (Yeah, that was too much of a struggle.) +- Day 9: 8:07 (37th okay, okay) +- Day 10: 15:50 (I was pretty happy with that but double the 100th place.) +- Day 11: 11:43 (Could have been much faster here.) +- Day 12: 19:11 (Okayish, but of course too slow for leaderboard.) +- 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: 50:01 (Way too slow. Was non-trivial but fun. Much better was feasible.) +- Day 17: 21:59 (Not tricky again but struggling for no reason.) +- Day 18: 162:00 (I couldn't figure out how to solve it as a tree so I did the basic way.) +- Day 19: +- Day 20: ## AoC 2022