18.py 2.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192
  1. from util import get_input
  2. from math import floor, ceil
  3. from functools import reduce
  4. from itertools import product
  5. def parse(line):
  6. return eval(line)
  7. input = get_input("18.input", parse)
  8. def add(a, b):
  9. return red([a, b])
  10. def red(a_in):
  11. a = list(a_in)
  12. while True:
  13. old_a = list(a)
  14. a = try_explode(a, 0)[0]
  15. if a != old_a:
  16. continue
  17. a = try_split(a)
  18. if old_a == a:
  19. break
  20. return a
  21. def add_const(a, c, left):
  22. if type(a) == int:
  23. return a + c
  24. elif left:
  25. return [add_const(a[0], c, left), a[1]]
  26. else:
  27. return [a[0], add_const(a[1], c, left)]
  28. def try_explode(a, depth):
  29. if type(a) == int:
  30. return a, [0, 0], False
  31. if depth == 4:
  32. return 0, a, True
  33. a0, [l, r], ex = try_explode(a[0], depth + 1)
  34. if ex:
  35. return [a0, add_const(a[1], r, True)], [l, 0], True
  36. a1, [l, r], ex = try_explode(a[1], depth + 1)
  37. if ex:
  38. return [add_const(a[0], l, False), a1], [0, r], True
  39. return [a0, a1], [0, 0], False
  40. def test_explode():
  41. print(try_explode([[[[[9,8],1],2],3],4], 0)[0])
  42. print(try_explode([7,[6,[5,[4,[3,2]]]]], 0)[0])
  43. print(try_explode([[6,[5,[4,[3,2]]]],1], 0)[0])
  44. print(try_explode([[3,[2,[1,[7,3]]]],[6,[5,[4,[3,2]]]]], 0)[0])
  45. print(try_explode([[3,[2,[8,0]]],[9,[5,[4,[3,2]]]]], 0)[0])
  46. def try_split(a):
  47. if type(a) == int:
  48. if a >= 10:
  49. return [floor(a / 2), ceil(a / 2)]
  50. else:
  51. return a
  52. else:
  53. l = try_split(a[0])
  54. if l != a[0]:
  55. return [l, a[1]]
  56. else:
  57. return [a[0], try_split(a[1])]
  58. def test_add():
  59. print(add([[[[4,3],4],4],[7,[[8,4],9]]], [1,1]))
  60. t2 = [[1,1],
  61. [2,2],
  62. [3,3],
  63. [4,4]]
  64. print(reduce(add, t2))
  65. t3 = [[1,1],
  66. [2,2],
  67. [3,3],
  68. [4,4],
  69. [5,5],
  70. [6,6]]
  71. print(reduce(add, t3))
  72. def magnitude(a):
  73. if type(a) == int:
  74. return a
  75. else:
  76. return 3 * magnitude(a[0]) + 2 * magnitude(a[1])
  77. print("Part 1:", magnitude(reduce(add, input)))
  78. print("Part 2:", max(magnitude(add(a, b)) for [a, b] in product(input, repeat=2)))