Advertisement
Guest User

Untitled

a guest
Dec 16th, 2021
176
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 3.50 KB | None | 0 0
  1. class Packet:
  2. def pprint(self, indent=0):
  3. print(indent*' ' + f'version={self.version}, type_id={self.type_id}, content={self.content}')
  4. if self.type_id == 4:
  5. return
  6.  
  7. for packet in self.content:
  8. packet.pprint(indent=indent+4)
  9.  
  10. def __init__(self, version, type_id, content):
  11. self.version = version
  12. self.type_id = type_id
  13. self.content = content
  14.  
  15. def sum_version(self):
  16. if not isinstance(self.content, list):
  17. return self.version
  18.  
  19. s = 0
  20. for content in self.content:
  21. if isinstance(content, self.__class__):
  22. s += content.sum_version()
  23. return self.version + s
  24.  
  25. def evaluate_packet(self):
  26. if self.type_id == 4:
  27. return self.content
  28. if self.type_id == 0:
  29. return sum([packet.evaluate_packet() for packet in self.content])
  30. if self.type_id == 1:
  31. return reduce(lambda x, y: x * y, [packet.evaluate_packet() for packet in self.content])
  32. if self.type_id == 2:
  33. return min([packet.evaluate_packet() for packet in self.content])
  34. if self.type_id == 3:
  35. return max([packet.evaluate_packet() for packet in self.content])
  36. if self.type_id == 5:
  37. return 1 if self.content[0].evaluate_packet() > self.content[1].evaluate_packet() else 0
  38. if self.type_id == 6:
  39. return 1 if self.content[0].evaluate_packet() < self.content[1].evaluate_packet() else 0
  40. if self.type_id == 7:
  41. return 1 if self.content[0].evaluate_packet() == self.content[1].evaluate_packet() else 0
  42.  
  43.  
  44. class PacketDecoder:
  45. @staticmethod
  46. def decode(stream):
  47. if not stream or set(stream) == set('0'):
  48. return []
  49.  
  50. version = int(stream[:3], 2)
  51. type_id = int(stream[3:6], 2)
  52. content = []
  53.  
  54. if type_id == 4:
  55. return PacketDecoder.decode_literal_packet(version, type_id, stream)
  56.  
  57. return PacketDecoder.decode_operator_packet(version, type_id, stream)
  58.  
  59. @staticmethod
  60. def decode_literal_packet(version, type_id, stream):
  61. curr_idx = 6
  62. bin_num = ''
  63. ended = False
  64. while not ended:
  65. if stream[curr_idx] == '0':
  66. ended=True
  67. bin_num += stream[curr_idx+1:curr_idx+5]
  68. curr_idx += 5
  69.  
  70. if curr_idx == len(stream) - 1:
  71. return []
  72.  
  73. return [Packet(version, type_id, int(bin_num, 2)), *PacketDecoder.decode(stream[curr_idx:])]
  74.  
  75. @staticmethod
  76. def decode_operator_packet(version, type_id, stream):
  77. if stream[6] == '0':
  78. subpacket_stream_len = int(stream[7:7+15], 2)
  79.  
  80. subpacket_data = stream[7+15:7+15+subpacket_stream_len]
  81.  
  82. return [Packet(version, type_id, PacketDecoder.decode(subpacket_data)), *PacketDecoder.decode(stream[7+15+subpacket_stream_len:])]
  83. else:
  84. subpacket_amount = int(stream[7:7+11], 2)
  85. subdata = PacketDecoder.decode(stream[7+11:])
  86. return [Packet(version, type_id, subdata[:subpacket_amount]), *subdata[subpacket_amount:]]
  87.  
  88.  
  89. def p1(stream):
  90. agg_version_sum = 0
  91. packets = PacketDecoder.decode(stream)
  92. for packet in packets:
  93. agg_version_sum += packet.sum_version()
  94.  
  95. return agg_version_sum
  96.  
  97. def p2(stream):
  98. return PacketDecoder.decode(stream)[0].evaluate_packet()
  99.  
  100.  
  101. stream = read('sample.txt')
  102. print(p1(stream))
  103. print(p2(stream))
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement