Tasks 18.1 and 18.2
This commit is contained in:
@@ -0,0 +1,245 @@
|
|||||||
|
from functools import reduce as freduce
|
||||||
|
from itertools import permutations
|
||||||
|
|
||||||
|
class Regular:
|
||||||
|
__slots__ = ['data']
|
||||||
|
def __init__(self, x):
|
||||||
|
self.data = x
|
||||||
|
def __str__(self):
|
||||||
|
return f'r{self.data}'
|
||||||
|
__repr__ = __str__
|
||||||
|
def __eq__(self, other):
|
||||||
|
if isinstance(other, Regular):
|
||||||
|
return self.data == other.data
|
||||||
|
if isinstance(other, int):
|
||||||
|
return self.data == other
|
||||||
|
return False
|
||||||
|
|
||||||
|
def load_file(filename='input'):
|
||||||
|
with open(filename) as f:
|
||||||
|
for line in f:
|
||||||
|
yield line.strip()
|
||||||
|
|
||||||
|
def add(x, y):
|
||||||
|
return reduce(add_numbers(x, y))
|
||||||
|
|
||||||
|
def reduce(x):
|
||||||
|
while True:
|
||||||
|
if can_explode(x):
|
||||||
|
x = explode(x)
|
||||||
|
continue
|
||||||
|
if can_split(x):
|
||||||
|
x = split(x)
|
||||||
|
continue
|
||||||
|
break
|
||||||
|
return x
|
||||||
|
|
||||||
|
def can_split(x):
|
||||||
|
try:
|
||||||
|
return next(filter(lambda k: k.data>=10, numbers(x)))
|
||||||
|
except StopIteration:
|
||||||
|
return False
|
||||||
|
|
||||||
|
def is_int(x):
|
||||||
|
return isinstance(x, int)
|
||||||
|
|
||||||
|
def is_regular(x):
|
||||||
|
return isinstance(x, Regular)
|
||||||
|
|
||||||
|
def is_pair(x):
|
||||||
|
return isinstance(x, list)
|
||||||
|
|
||||||
|
def magnitude(x):
|
||||||
|
if is_regular(x):
|
||||||
|
return x.data
|
||||||
|
return 3*magnitude(first(x)) + 2*magnitude(second(x))
|
||||||
|
|
||||||
|
def numbers(x):
|
||||||
|
if is_regular(x):
|
||||||
|
yield x
|
||||||
|
elif is_pair(x):
|
||||||
|
yield from numbers(first(x))
|
||||||
|
yield from numbers(second(x))
|
||||||
|
|
||||||
|
def height(x, h=0):
|
||||||
|
if is_regular(first(x)) and is_regular(second(x)):
|
||||||
|
yield h, x
|
||||||
|
if is_pair(first(x)):
|
||||||
|
yield from height(first(x), h+1)
|
||||||
|
if is_pair(second(x)):
|
||||||
|
yield from height(second(x), h+1)
|
||||||
|
|
||||||
|
def can_explode(x):
|
||||||
|
try:
|
||||||
|
return next(filter(lambda k: k[0]==4, height(x)))
|
||||||
|
except StopIteration:
|
||||||
|
return None
|
||||||
|
|
||||||
|
def explode(where):
|
||||||
|
what = can_explode(where)[1]
|
||||||
|
replace_once(where, what, Regular(-1))
|
||||||
|
k = list(numbers(where))
|
||||||
|
i = k.index(Regular(-1))
|
||||||
|
if i-1>=0:
|
||||||
|
k[i-1].data += what[0].data
|
||||||
|
if i+1<len(k):
|
||||||
|
k[i+1].data += what[1].data
|
||||||
|
k[i].data = 0
|
||||||
|
update(where, iter(k))
|
||||||
|
return where
|
||||||
|
|
||||||
|
def update(where, k):
|
||||||
|
if where == -1:
|
||||||
|
return
|
||||||
|
if is_regular(first(where)):
|
||||||
|
where[0] = next(k)
|
||||||
|
if is_pair(first(where)):
|
||||||
|
update(first(where), k)
|
||||||
|
if is_pair(second(where)):
|
||||||
|
update(second(where), k)
|
||||||
|
if is_regular(second(where)):
|
||||||
|
where[1] = next(k)
|
||||||
|
|
||||||
|
|
||||||
|
def replace_once(where, what, with_):
|
||||||
|
def replace(where, what, with_):
|
||||||
|
nonlocal found
|
||||||
|
if is_pair(where):
|
||||||
|
if first(where) is what and not found:
|
||||||
|
where[0] = with_
|
||||||
|
found = True
|
||||||
|
elif second(where) is what and not found:
|
||||||
|
where[1] = with_
|
||||||
|
found = True
|
||||||
|
if not found and is_pair(first(where)):
|
||||||
|
replace(first(where), what, with_)
|
||||||
|
if not found and is_pair(second(where)):
|
||||||
|
replace(second(where), what, with_)
|
||||||
|
found = False
|
||||||
|
replace(where, what, with_)
|
||||||
|
|
||||||
|
def split(where):
|
||||||
|
what = can_split(where)
|
||||||
|
with_ = [Regular(what.data//2), Regular((what.data+1)//2)]
|
||||||
|
replace_once(where, what, with_)
|
||||||
|
return where
|
||||||
|
|
||||||
|
def first(x):
|
||||||
|
return x[0]
|
||||||
|
|
||||||
|
def second(x):
|
||||||
|
return x[1]
|
||||||
|
|
||||||
|
def add_numbers(x, y):
|
||||||
|
return [x,y]
|
||||||
|
|
||||||
|
def from_string(s):
|
||||||
|
return regularize(eval(s))
|
||||||
|
|
||||||
|
def regularize(x):
|
||||||
|
def rec(x):
|
||||||
|
if is_pair(x):
|
||||||
|
if is_int(first(x)):
|
||||||
|
x[0] = Regular(x[0])
|
||||||
|
else:
|
||||||
|
regularize(first(x))
|
||||||
|
if is_int(second(x)):
|
||||||
|
x[1] = Regular(x[1])
|
||||||
|
else:
|
||||||
|
regularize(second(x))
|
||||||
|
rec(x)
|
||||||
|
return x
|
||||||
|
|
||||||
|
|
||||||
|
def calculate(xs):
|
||||||
|
return freduce(add, map(from_string, xs))
|
||||||
|
|
||||||
|
def test_magnitude():
|
||||||
|
assert magnitude(regularize([9,1]))==29
|
||||||
|
assert magnitude(regularize([1,9]))==21
|
||||||
|
assert 143==magnitude(regularize([[1,2],[[3,4],5]]))
|
||||||
|
assert 1384==magnitude(regularize([[[[0,7],4],[[7,8],[6,0]]],[8,1]]))
|
||||||
|
assert 445==magnitude(regularize([[[[1,1],[2,2]],[3,3]],[4,4]]))
|
||||||
|
assert 791==magnitude(regularize([[[[3,0],[5,3]],[4,4]],[5,5]]))
|
||||||
|
assert 1137==magnitude(regularize([[[[5,0],[7,4]],[5,5]],[6,6]]))
|
||||||
|
assert 3488==magnitude(regularize([[[[8,7],[7,7]],[[8,6],[7,7]]],[[[0,7],[6,6]],[8,7]]]))
|
||||||
|
|
||||||
|
def test_can_explode():
|
||||||
|
assert can_explode(regularize([[[[[4,3],4],4],[7,[[8,4],9]]],[1,1]]))
|
||||||
|
assert can_explode(regularize([[[[0,7],4],[7,[[8,4],9]]],[1,1]]))
|
||||||
|
assert can_explode(regularize([[[[0,7],4],[[7,8],[0,[6,7]]]],[1,1]]))
|
||||||
|
|
||||||
|
def test_can_split():
|
||||||
|
assert can_split(regularize([[[[0,7],4],[15,[0,13]]],[1,1]]))
|
||||||
|
assert can_split(regularize([[[[0,7],4],[[7,8],[0,13]]],[1,1]]))
|
||||||
|
|
||||||
|
def test_split():
|
||||||
|
assert split(regularize([[[[0,7],4],[15,[0,13]]],[1,1]]))==[[[[0,7],4],[[7,8],[0,13]]],[1,1]]
|
||||||
|
assert split(regularize([[[[0,7],4],[[7,8],[0,13]]],[1,1]]))==[[[[0,7],4],[[7,8],[0,[6,7]]]],[1,1]]
|
||||||
|
|
||||||
|
def test_explode():
|
||||||
|
assert explode(regularize([[[[[4,3],4],4],[7,[[8,4],9]]],[1,1]]))==[[[[0,7],4],[7,[[8,4],9]]],[1,1]]
|
||||||
|
assert explode(regularize([[[[0,7],4],[7,[[8,4],9]]],[1,1]]))==[[[[0,7],4],[15,[0,13]]],[1,1]]
|
||||||
|
assert explode(regularize([[[[0,7],4],[[7,8],[0,[6,7]]]],[1,1]]))==[[[[0,7],4],[[7,8],[6,0]]],[8,1]]
|
||||||
|
|
||||||
|
def test_add_simple():
|
||||||
|
t1 = """
|
||||||
|
[1,1]
|
||||||
|
[2,2]
|
||||||
|
[3,3]
|
||||||
|
[4,4]
|
||||||
|
""".strip().split('\n')
|
||||||
|
assert calculate(t1)==[[[[1,1],[2,2]],[3,3]],[4,4]]
|
||||||
|
t2 = """
|
||||||
|
[1,1]
|
||||||
|
[2,2]
|
||||||
|
[3,3]
|
||||||
|
[4,4]
|
||||||
|
[5,5]
|
||||||
|
""".strip().split('\n')
|
||||||
|
assert calculate(t2)==[[[[3,0],[5,3]],[4,4]],[5,5]]
|
||||||
|
t3 = """
|
||||||
|
[1,1]
|
||||||
|
[2,2]
|
||||||
|
[3,3]
|
||||||
|
[4,4]
|
||||||
|
[5,5]
|
||||||
|
[6,6]
|
||||||
|
""".strip().split('\n')
|
||||||
|
assert calculate(t3)==[[[[5,0],[7,4]],[5,5]],[6,6]]
|
||||||
|
|
||||||
|
def test_add_example():
|
||||||
|
t = '''
|
||||||
|
[[[[4,3],4],4],[7,[[8,4],9]]]
|
||||||
|
[1,1]
|
||||||
|
'''.strip().split('\n')
|
||||||
|
assert calculate(t)==[[[[0,7],4],[[7,8],[6,0]]],[8,1]]
|
||||||
|
|
||||||
|
def test_add_complex():
|
||||||
|
t4 = """
|
||||||
|
[[[0,[4,5]],[0,0]],[[[4,5],[2,6]],[9,5]]]
|
||||||
|
[7,[[[3,7],[4,3]],[[6,3],[8,8]]]]
|
||||||
|
[[2,[[0,8],[3,4]]],[[[6,7],1],[7,[1,6]]]]
|
||||||
|
[[[[2,4],7],[6,[0,5]]],[[[6,8],[2,8]],[[2,1],[4,5]]]]
|
||||||
|
[7,[5,[[3,8],[1,4]]]]
|
||||||
|
[[2,[2,2]],[8,[8,1]]]
|
||||||
|
[2,9]
|
||||||
|
[1,[[[9,3],9],[[9,0],[0,7]]]]
|
||||||
|
[[[5,[7,4]],7],1]
|
||||||
|
[[[[4,2],2],6],[8,7]]
|
||||||
|
""".strip().split('\n')
|
||||||
|
assert calculate(t4[:2])==[[[[4,0],[5,4]],[[7,7],[6,0]]],[[8,[7,7]],[[7,9],[5,0]]]]
|
||||||
|
assert calculate(t4[:3])==[[[[6,7],[6,7]],[[7,7],[0,7]]],[[[8,7],[7,7]],[[8,8],[8,0]]]], 'похоже, при одинаковых заменах происходит пиздец'
|
||||||
|
assert calculate(t4[:4])==[[[[7,0],[7,7]],[[7,7],[7,8]]],[[[7,7],[8,8]],[[7,7],[8,7]]]]
|
||||||
|
assert calculate(t4[:5])==[[[[7,7],[7,8]],[[9,5],[8,7]]],[[[6,8],[0,8]],[[9,9],[9,0]]]]
|
||||||
|
assert calculate(t4[:6])==[[[[6,6],[6,6]],[[6,0],[6,7]]],[[[7,7],[8,9]],[8,[8,1]]]]
|
||||||
|
assert calculate(t4[:7])==[[[[6,6],[7,7]],[[0,7],[7,7]]],[[[5,5],[5,6]],9]]
|
||||||
|
assert calculate(t4[:8])==[[[[7,8],[6,7]],[[6,8],[0,8]]],[[[7,7],[5,0]],[[5,5],[5,6]]]]
|
||||||
|
assert calculate(t4[:9])==[[[[7,7],[7,7]],[[8,7],[8,7]]],[[[7,0],[7,7]],9]]
|
||||||
|
assert calculate(t4)==[[[[8,7],[7,7]],[[8,6],[7,7]]],[[[0,7],[6,6]],[8,7]]]
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
print(magnitude(calculate(load_file())))
|
||||||
|
print(max(magnitude(calculate(x)) for x in permutations(load_file(), 2)))
|
||||||
|
|
||||||
@@ -0,0 +1,100 @@
|
|||||||
|
[[[6,[0,5]],2],3]
|
||||||
|
[[3,9],[[4,[5,5]],[9,4]]]
|
||||||
|
[[3,[2,[0,7]]],[[1,[0,1]],[8,[2,4]]]]
|
||||||
|
[[[[3,0],[8,1]],[[5,6],[3,5]]],[5,[[7,9],[5,1]]]]
|
||||||
|
[[[9,5],1],[[2,6],[4,[4,6]]]]
|
||||||
|
[2,[5,[3,0]]]
|
||||||
|
[[[[3,8],9],[[9,2],[7,7]]],5]
|
||||||
|
[[[[8,5],3],[0,[0,8]]],[9,[6,[8,1]]]]
|
||||||
|
[[[[9,6],[9,1]],[[3,4],3]],[2,2]]
|
||||||
|
[[3,[[7,7],2]],[[[9,9],[8,6]],2]]
|
||||||
|
[[[[3,5],8],[4,[9,4]]],7]
|
||||||
|
[[1,[6,[2,6]]],[[7,0],[[3,1],9]]]
|
||||||
|
[[[[0,5],0],[0,[2,4]]],[7,[6,[1,6]]]]
|
||||||
|
[0,[6,[3,1]]]
|
||||||
|
[4,[[[1,2],0],[[6,3],6]]]
|
||||||
|
[[[[4,3],[8,5]],[9,[0,5]]],[[[8,1],3],[8,8]]]
|
||||||
|
[[3,[6,7]],[[[1,4],[2,1]],[9,[2,8]]]]
|
||||||
|
[[[[3,0],[4,5]],4],[[3,[5,7]],6]]
|
||||||
|
[[8,[5,[3,9]]],[[[1,9],[8,7]],7]]
|
||||||
|
[[[0,[3,4]],[[0,1],6]],[1,5]]
|
||||||
|
[6,[[9,4],[9,0]]]
|
||||||
|
[[4,9],[[[0,9],9],8]]
|
||||||
|
[5,[0,[3,6]]]
|
||||||
|
[[[[3,9],[1,1]],[4,0]],[4,[[5,7],6]]]
|
||||||
|
[[[6,[2,1]],[4,[3,3]]],[[6,[5,6]],[7,[5,0]]]]
|
||||||
|
[[[8,4],[[1,2],[2,0]]],[[6,[5,6]],[6,4]]]
|
||||||
|
[[[5,9],7],[[[3,4],[2,1]],2]]
|
||||||
|
[[[8,8],5],[6,[[9,1],1]]]
|
||||||
|
[[[[3,4],1],[1,[4,2]]],[[[9,1],[2,0]],3]]
|
||||||
|
[[[5,[1,7]],[3,[9,7]]],[[2,0],[[7,7],5]]]
|
||||||
|
[[[6,9],6],[6,[[4,2],[5,3]]]]
|
||||||
|
[[[[6,5],[5,0]],[[6,9],7]],6]
|
||||||
|
[[[[2,8],[3,2]],[8,8]],[[[4,6],7],[2,[2,3]]]]
|
||||||
|
[[[3,4],1],5]
|
||||||
|
[[6,[[7,4],8]],[[6,[9,2]],9]]
|
||||||
|
[[[[0,4],0],[[3,1],[3,6]]],[0,[[2,8],[5,5]]]]
|
||||||
|
[[5,[[1,2],6]],[[[1,9],[2,2]],[9,[1,0]]]]
|
||||||
|
[[[[7,7],5],[[0,0],[0,5]]],[[5,4],[5,[8,1]]]]
|
||||||
|
[[[[8,7],6],[0,[0,3]]],[2,[[9,8],0]]]
|
||||||
|
[6,7]
|
||||||
|
[[[[5,2],[2,2]],[[8,1],[2,7]]],2]
|
||||||
|
[[[1,0],[[9,8],[2,1]]],4]
|
||||||
|
[[[[5,2],[2,0]],7],[[2,[4,4]],[3,3]]]
|
||||||
|
[[8,3],[[7,2],[[1,5],9]]]
|
||||||
|
[[[[9,4],[7,5]],[[4,9],1]],[[[0,6],[1,6]],[[4,2],3]]]
|
||||||
|
[4,[5,[5,3]]]
|
||||||
|
[[1,[[0,1],6]],[[[8,8],6],0]]
|
||||||
|
[[[0,3],[1,2]],[[6,8],[7,[4,7]]]]
|
||||||
|
[3,[[[5,8],[6,9]],[8,[5,4]]]]
|
||||||
|
[[1,1],[[8,[7,0]],9]]
|
||||||
|
[2,2]
|
||||||
|
[[3,[[0,4],1]],[[7,[2,3]],[8,4]]]
|
||||||
|
[[[0,2],[5,[5,6]]],[[[8,1],[5,2]],8]]
|
||||||
|
[[[[9,5],6],[[7,2],[2,1]]],[[[0,0],0],[[7,9],[9,1]]]]
|
||||||
|
[[1,7],[1,[[6,3],8]]]
|
||||||
|
[4,[[[7,4],1],[[1,9],6]]]
|
||||||
|
[[[[7,8],9],3],[[[5,0],9],8]]
|
||||||
|
[[[1,3],[[8,3],[1,9]]],[[[6,2],5],5]]
|
||||||
|
[[8,[[6,6],[1,4]]],[[2,[9,0]],[9,[2,2]]]]
|
||||||
|
[[0,[[1,6],8]],[[[3,7],[9,2]],[3,[3,6]]]]
|
||||||
|
[[0,[5,6]],[[[6,5],1],8]]
|
||||||
|
[[[[9,0],[1,1]],[[1,0],1]],[[[2,5],7],[5,[0,3]]]]
|
||||||
|
[2,[2,[[3,8],[5,5]]]]
|
||||||
|
[[[[4,0],2],[4,2]],[[5,[8,1]],[[2,7],6]]]
|
||||||
|
[[[1,[3,5]],6],0]
|
||||||
|
[[[3,3],[1,[2,1]]],[[3,[1,1]],[7,0]]]
|
||||||
|
[[[[8,5],3],[2,[3,0]]],[[[4,8],[8,8]],[9,[2,0]]]]
|
||||||
|
[[[[8,3],[9,8]],[[8,3],2]],[5,[5,8]]]
|
||||||
|
[[[1,9],8],[[[0,3],[9,1]],[[9,1],[4,2]]]]
|
||||||
|
[[[4,1],6],[[5,2],[4,2]]]
|
||||||
|
[[7,[5,[3,0]]],[[0,[0,1]],[1,[9,6]]]]
|
||||||
|
[[[[0,3],[8,9]],1],[6,2]]
|
||||||
|
[[5,[7,8]],[[5,3],[[9,8],[6,2]]]]
|
||||||
|
[[[[3,6],8],9],[[3,[6,2]],[0,1]]]
|
||||||
|
[[[5,3],[6,[0,3]]],6]
|
||||||
|
[[[2,9],7],[[[4,2],9],8]]
|
||||||
|
[[[7,[3,5]],[6,[5,9]]],[[[3,2],[5,6]],1]]
|
||||||
|
[[0,[[9,1],6]],8]
|
||||||
|
[[[[3,5],[2,2]],[[9,8],9]],[8,8]]
|
||||||
|
[[[[6,9],[2,0]],[6,1]],[1,5]]
|
||||||
|
[[[0,[9,9]],[[3,1],9]],[[[4,8],2],[3,[4,8]]]]
|
||||||
|
[[[5,3],[6,3]],[6,[[2,7],[3,2]]]]
|
||||||
|
[[[5,[7,3]],8],[[2,[0,0]],[9,5]]]
|
||||||
|
[[[7,[4,3]],[[9,6],[5,7]]],[[[1,8],[3,0]],[[2,4],[7,3]]]]
|
||||||
|
[[[3,[2,1]],[1,2]],[7,[[5,4],8]]]
|
||||||
|
[[4,[[2,6],[7,9]]],[[[1,8],3],[[0,1],[5,4]]]]
|
||||||
|
[[[4,0],4],[3,7]]
|
||||||
|
[[[4,[7,7]],5],[2,3]]
|
||||||
|
[[[[7,7],[9,3]],8],[[[3,8],6],[[1,2],[9,6]]]]
|
||||||
|
[[7,[[7,5],[7,8]]],[2,[[4,3],[6,3]]]]
|
||||||
|
[[[7,3],[[8,2],[6,5]]],1]
|
||||||
|
[[8,[7,[9,6]]],[5,[[2,2],2]]]
|
||||||
|
[[[3,[8,9]],[[3,8],[3,3]]],[4,[7,[5,0]]]]
|
||||||
|
[[[[2,0],[1,0]],3],[6,[[1,3],[5,4]]]]
|
||||||
|
[[1,8],[8,[[6,7],3]]]
|
||||||
|
[4,[[[3,4],[7,8]],[7,[7,1]]]]
|
||||||
|
[[[4,8],[9,[7,4]]],6]
|
||||||
|
[[[7,3],[[2,9],7]],[[[2,5],8],[2,5]]]
|
||||||
|
[7,[[[8,7],0],[[3,1],6]]]
|
||||||
|
[[6,[2,[3,2]]],[[[5,4],2],[[2,6],[8,4]]]]
|
||||||
Reference in New Issue
Block a user