day16.py 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122
  1. import os
  2. import sys
  3. from collections import Counter
  4. from itertools import chain
  5. sys.setrecursionlimit(5000)
  6. with open(os.path.join(os.path.dirname(__file__), "example.txt")) as example:
  7. example_data = example.read().splitlines()
  8. example_data = [list(n) for n in example_data]
  9. with open(os.path.join(os.path.dirname(__file__), "input.txt")) as example:
  10. input_data = example.read().splitlines()
  11. input_data = [list(n) for n in input_data]
  12. def init(data):
  13. charged = [["."] * len(data[0]) for _ in range(len(data))]
  14. direction = [["."] * len(data[0]) for _ in range(len(data))]
  15. return data, charged, direction
  16. data, charged, direction = init(example_data)
  17. def bounce(i=0, j=0, succ=1, h=True, v=False):
  18. if i >= len(data[0]) or i < 0 or j >= len(data) or j < 0:
  19. return
  20. if h:
  21. if succ > 0 and direction[i][j] == ">":
  22. return
  23. elif succ > 0:
  24. direction[i][j] = ">"
  25. if succ < 0 and direction[i][j] == "<":
  26. return
  27. elif succ < 0:
  28. direction[i][j] = "<"
  29. else:
  30. if succ > 0 and direction[i][j] == "v":
  31. return
  32. elif succ > 0:
  33. direction[i][j] = "v"
  34. if succ < 0 and direction[i][j] == "^":
  35. return
  36. elif succ < 0:
  37. direction[i][j] = "^"
  38. symbol = data[i][j]
  39. charged[i][j] = "#"
  40. if h:
  41. if symbol == "." or symbol == "-":
  42. bounce(i=i, j=j + succ, succ=succ, h=True, v=False)
  43. elif symbol == "|":
  44. bounce(i=i + succ, j=j, succ=succ, h=False, v=True)
  45. bounce(i=i - succ, j=j, succ=-succ, h=False, v=True)
  46. elif symbol == "\\":
  47. bounce(i=i + succ, j=j, succ=succ, h=False, v=True)
  48. elif symbol == "/":
  49. bounce(i=i - succ, j=j, succ=-succ, h=False, v=True)
  50. else:
  51. raise Exception("PIDOR GNOY " + symbol)
  52. elif v:
  53. if symbol == "." or symbol == "|":
  54. bounce(i=i + succ, j=j, succ=succ, h=False, v=True)
  55. elif symbol == "\\":
  56. bounce(i=i, j=j + succ, succ=succ, h=True, v=False)
  57. elif symbol == "/":
  58. bounce(i=i, j=j - succ, succ=-succ, h=True, v=False)
  59. elif symbol == "-":
  60. bounce(i=i, j=j + succ, succ=succ, h=True, v=False)
  61. bounce(i=i, j=j - succ, succ=-succ, h=True, v=False)
  62. else:
  63. raise Exception("PIDOR GNOY " + symbol)
  64. else:
  65. raise Exception(f"PIDOR GNOY + {h} + {v}")
  66. # part 1 1
  67. data, charged, direction = init(example_data)
  68. bounce()
  69. print(c := Counter(chain(*charged))["#"])
  70. # part 1 2
  71. data, charged, direction = init(input_data)
  72. bounce()
  73. print(c := Counter(chain(*charged))["#"])
  74. # part 2 1
  75. m = 0
  76. for i in range(len(data)):
  77. data, charged, direction = init(example_data)
  78. bounce(i=i, j=0, succ=1, h=True, v=False)
  79. m = max(m, Counter(chain(*charged))["#"])
  80. data, charged, direction = init(example_data)
  81. bounce(i=i, j=len(data[0]) - 1, succ=-1, h=True, v=False)
  82. m = max(m, Counter(chain(*charged))["#"])
  83. for j in range(len(data[0])):
  84. data, charged, direction = init(example_data)
  85. bounce(i=0, j=j, succ=1, h=False, v=True)
  86. m = max(m, Counter(chain(*charged))["#"])
  87. data, charged, direction = init(example_data)
  88. bounce(i=len(data) - 1, j=j, succ=-1, h=False, v=True)
  89. m = max(m, Counter(chain(*charged))["#"])
  90. print(m)
  91. # part 2 2
  92. m = 0
  93. for i in range(len(data)):
  94. data, charged, direction = init(input_data)
  95. bounce(i=i, j=0, succ=1, h=True, v=False)
  96. m = max(m, Counter(chain(*charged))["#"])
  97. data, charged, direction = init(input_data)
  98. bounce(i=i, j=len(data[0]) - 1, succ=-1, h=True, v=False)
  99. m = max(m, Counter(chain(*charged))["#"])
  100. for j in range(len(data[0])):
  101. data, charged, direction = init(input_data)
  102. bounce(i=0, j=j, succ=1, h=False, v=True)
  103. m = max(m, Counter(chain(*charged))["#"])
  104. data, charged, direction = init(input_data)
  105. bounce(i=len(data) - 1, j=j, succ=-1, h=False, v=True)
  106. m = max(m, Counter(chain(*charged))["#"])
  107. print(m)