main.py 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100
  1. import os, sys
  2. task_dir = os.path.dirname(__file__)
  3. sys.path.append(f"{task_dir}/..")
  4. from math import prod
  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] == "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 prod(read_op())
  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, verbose=True):
  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. if verbose:
  65. print("The answer of part1 is:", sumpackver)
  66. def part2(input, verbose=True):
  67. global b, cur, sumpackver
  68. cur = 0
  69. sumpackver = 0
  70. packet = input[0]
  71. b = bin(int(packet, 16))[2:].zfill(len(packet)*4)
  72. val = parse_block()
  73. if verbose:
  74. print("The answer of part1 is:", val)
  75. if __name__ == "__main__":
  76. input, example = get_input(task_dir, 16)
  77. print("PART1")
  78. for packet in example[3:7]:
  79. check_example([packet], part1)
  80. print("PART2")
  81. for packet in example[7:]:
  82. check_example([packet], part2)
  83. part1(input)
  84. part2(input)
  85. generate_readme(task_dir, 16)