main.py 2.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798
  1. import os, sys
  2. task_dir = os.path.dirname(__file__)
  3. sys.path.append(f"{task_dir}/..")
  4. from functools import reduce
  5. from get_tasks import get_input, generate_readme, check_example
  6. def read_litval():
  7. global cur
  8. blitval = ""
  9. while b[cur : cur + 1] == "1":
  10. cur += 1
  11. blitval += b[cur : cur + 4]
  12. cur += 4
  13. cur += 1
  14. blitval += b[cur : cur + 4]
  15. cur += 4
  16. litval = int(blitval, 2)
  17. return litval
  18. def read_header():
  19. global typeID, packver, cur
  20. packver = int(b[cur : cur + 3], 2)
  21. cur += 3
  22. typeID = int(b[cur : cur + 3], 2)
  23. cur += 3
  24. def read_op():
  25. global cur
  26. litsub = []
  27. if b[cur : cur + 1] == "0":
  28. cur += 1
  29. nbits = int(b[cur : cur + 15], 2)
  30. cur += 15
  31. end_subpackets = cur + nbits
  32. while cur != end_subpackets:
  33. litsub += [parse_block()]
  34. return litsub
  35. else:
  36. cur += 1
  37. npacks = int(b[cur : cur + 11], 2)
  38. cur += 11
  39. n = 0
  40. while n != npacks:
  41. n += 1
  42. litsub += [parse_block()]
  43. return litsub
  44. def parse_block():
  45. global typeID, cur, sumpackver, sumval
  46. read_header()
  47. sumpackver += packver
  48. match typeID:
  49. case 4: return read_litval()
  50. case 0: return sum(read_op())
  51. case 1: return reduce(lambda x, y: x * y, read_op(), 1)
  52. case 2: return min(read_op())
  53. case 3: return max(read_op())
  54. case 5: subs = read_op(); return 1 if subs[0] > subs[1] else 0
  55. case 6: subs = read_op(); return 1 if subs[0] < subs[1] else 0
  56. case 7: subs = read_op(); return 1 if subs[0] == subs[1] else 0
  57. def part1(input):
  58. global b, cur, sumpackver
  59. cur = 0
  60. sumpackver = 0
  61. packet = input[0]
  62. b = bin(int(packet, 16))[2:].zfill(len(packet)*4)
  63. parse_block()
  64. print("The answer of part1 is:", sumpackver)
  65. def part2(input):
  66. global b, cur, sumpackver
  67. cur = 0
  68. sumpackver = 0
  69. packet = input[0]
  70. b = bin(int(packet, 16))[2:].zfill(len(packet)*4)
  71. val = parse_block()
  72. print("The answer of part1 is:", val)
  73. if __name__ == "__main__":
  74. input, example = get_input(task_dir, 16)
  75. print("PART1")
  76. for packet in example[3:7]:
  77. check_example([packet], part1)
  78. print("PART2")
  79. for packet in example[7:]:
  80. check_example([packet], part2)
  81. part1(input)
  82. part2(input)
  83. generate_readme(task_dir, 16)