Advertisement
Guest User

Day 16

a guest
Dec 17th, 2021
340
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 2.44 KB | None | 0 0
  1. from math import prod
  2.  
  3. OPS = [
  4. sum,
  5. prod,
  6. min,
  7. max,
  8. None,
  9. lambda x: 1 if x[0] > x[1] else 0,
  10. lambda x: 1 if x[0] < x[1] else 0,
  11. lambda x: 1 if x[0] == x[1] else 0,
  12. ]
  13.  
  14.  
  15. def get_version(packet, offset=0):
  16. return int(packet[offset:offset + 3], 2)
  17.  
  18.  
  19. def get_type_id(packet, offset=0):
  20. return int(packet[offset + 3:offset + 6], 2)
  21.  
  22.  
  23. def get_len_type_id(packet, offset=0):
  24. return int(packet[offset + 6])
  25.  
  26.  
  27. def get_literal_value(packet, offset=0):
  28. n = len(packet)
  29.  
  30. curr = []
  31. for i in range(offset + 6, n, 5):
  32. curr.append(packet[i + 1:i + 5])
  33. if packet[i] == '0':
  34. break
  35.  
  36. return int(''.join(curr), 2)
  37.  
  38.  
  39. def is_literal(packet, offset=0):
  40. return get_type_id(packet, offset) == 4
  41.  
  42.  
  43. def get_end_of_literal(packet, offset=0):
  44. for i in range(offset + 6, len(packet), 5):
  45. if packet[i] == '0':
  46. return i + 5
  47.  
  48. return -1
  49.  
  50.  
  51. def helper(packet, offset=0):
  52. version_total = get_version(packet, offset)
  53.  
  54. if is_literal(packet, offset):
  55. end = get_end_of_literal(packet, offset)
  56. return end, version_total, get_literal_value(packet, offset)
  57.  
  58. results = []
  59. initial_offset = offset
  60. end = -1
  61.  
  62. if get_len_type_id(packet, offset) == 0:
  63. total_len = int(packet[offset + 7:offset + 22], 2)
  64. offset += 22
  65.  
  66. while total_len > 0:
  67. end, version, expr_res = helper(packet, offset)
  68. results.append(expr_res)
  69. version_total += version
  70. total_len -= end - offset
  71. offset = end
  72. else:
  73. total_count = int(packet[offset + 7:offset + 18], 2)
  74. offset += 18
  75.  
  76. for _ in range(total_count):
  77. end, version, expr_res = helper(packet, offset)
  78. results.append(expr_res)
  79. version_total += version
  80. offset = end
  81.  
  82. return end, version_total, OPS[get_type_id(packet, initial_offset)](results)
  83.  
  84.  
  85. def hex_to_binary(hex):
  86. binary = bin(int(hex, 16))[2:]
  87.  
  88. while (len(binary) < len(hex) * 4):
  89. binary = '0' + binary
  90.  
  91. return binary
  92.  
  93.  
  94. def solve_part_1(packet):
  95. return helper(packet)[1]
  96.  
  97.  
  98. def solve_part_2(packet):
  99. return helper(packet)[2]
  100.  
  101.  
  102. if __name__ == '__main__':
  103. with open('input_01.txt') as f:
  104. packet = hex_to_binary(f.readline().strip())
  105.  
  106. print(solve_part_1(packet))
  107. print(solve_part_2(packet))
  108.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement