Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- from tools import *
- from math import *
- DAY = 18
- DEBUG = False
- def raw_input_data(
- day: int,
- ):
- if not DEBUG:
- path = f"day{day}_input.txt"
- else:
- path = f"day{day}_input2.txt"
- with open(path, "r") as f:
- return [line[:-1] for line in f]
- data = raw_input_data(DAY)
- print("\ndata:")
- print(data)
- print("\n")
- # data = "\n".join(data).split("\n\n")
- # data = [scanf("%d %s", line_str) for line_str in data]
- # data = [[int(c) for c in line] for line in data ]
- # scanf("%d %s", line_str)
- data = [eval(line) for line in data]
- try:
- print("\n" + "data:")
- pprint(data)
- print("\n")
- except:
- pass
- def items_by_path(expr):
- if isinstance(expr, int):
- return {(): expr}
- return {
- **{
- (child_index,) + path: item
- for child_index, child in enumerate(expr)
- for path, item in items_by_path(child).items()
- },
- **{(): expr},
- }
- def at_path(expr, path):
- if len(path) > 0:
- return at_path(expr[path[0]], path[1:])
- else:
- return expr
- def set_path(expr, path, item):
- if len(path) > 0:
- index = path[0]
- return (
- expr[:index] + [set_path(expr[index], path[1:], item)] + expr[index + 1 :]
- )
- else:
- return item
- def exploded(expr):
- items = items_by_path(expr)
- deep_pairs = [
- path for path, item in items.items() if isinstance(item, list) if len(path) == 4
- ]
- if not deep_pairs:
- raise ValueError
- exploding_pair_path = sorted(deep_pairs)[0]
- left, right = at_path(expr, exploding_pair_path)
- expr = set_path(expr, exploding_pair_path, 0)
- left_paths = [
- (path, item)
- for path, item in items.items()
- if isinstance(item, int)
- if path < exploding_pair_path
- if path[: len(exploding_pair_path)] != exploding_pair_path
- ]
- if left_paths:
- left_number_path = max(
- left_paths,
- )[0]
- prev_value = at_path(expr, left_number_path)
- expr = set_path(expr, left_number_path, prev_value + left)
- right_paths = [
- (path, item)
- for path, item in items.items()
- if isinstance(item, int)
- if path > exploding_pair_path
- if path[: len(exploding_pair_path)] != exploding_pair_path
- ]
- if right_paths:
- right_number_path = min(
- right_paths,
- )[0]
- prev_value = at_path(expr, right_number_path)
- expr = set_path(expr, right_number_path, prev_value + right)
- return expr
- def split(expr):
- items = items_by_path(expr)
- large_ints = [
- (path, value)
- for path, value in items.items()
- if isinstance(value, int)
- if value > 9
- ]
- assert len(large_ints)
- first_large_num_path, large_num = min(large_ints)
- return set_path(
- expr, first_large_num_path, [floor(large_num / 2), ceil(large_num / 2)]
- )
- def simplify_step(expr):
- try:
- return exploded(expr)
- except ValueError:
- pass
- try:
- return split(expr)
- except AssertionError:
- pass
- return expr
- def simplify(expr):
- while True:
- next_expr = simplify_step(expr)
- if next_expr == expr:
- return expr
- expr = next_expr
- value = data[0]
- for i, line in enumerate(data[1:]):
- value = [value, line]
- value = simplify(value)
- print(value)
- def magnitude(value):
- if isinstance(value, list):
- return 3 * magnitude(value[0]) + 2 * magnitude(value[1])
- else:
- return value
- print(magnitude(value))
- print(
- max(
- magnitude(simplify([a, b]))
- for ai, a in enumerate(data)
- for bi, b in enumerate(data)
- if ai != bi
- )
- )
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement