16_decoder.py 1.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152
  1. #!/usr/bin/env python3
  2. import sys
  3. from itertools import islice, starmap
  4. from operator import add, mul, gt, lt, eq
  5. from functools import reduce
  6. def bitstream(hexdata):
  7. for quad in hexdata:
  8. i = int(quad, 16)
  9. yield i >> 3
  10. yield i >> 2 & 1
  11. yield i >> 1 & 1
  12. yield i & 1
  13. def consume(bits, num):
  14. i = 0
  15. for bit in islice(bits, num):
  16. i = i << 1 | bit
  17. return i
  18. def decode(bits):
  19. while True:
  20. try:
  21. version = consume(bits, 3)
  22. ty = consume(bits, 3)
  23. if ty == 4:
  24. has_next = next(bits)
  25. arg = consume(bits, 4)
  26. while has_next:
  27. has_next = next(bits)
  28. arg = arg << 4 | consume(bits, 4)
  29. elif next(bits):
  30. arg = list(islice(decode(bits), consume(bits, 11)))
  31. else:
  32. arg = list(decode(islice(bits, consume(bits, 15))))
  33. yield ty, version, arg
  34. except StopIteration:
  35. break
  36. def version_sum(ty, version, arg):
  37. return version if ty == 4 else version + sum(starmap(version_sum, arg))
  38. OPS = add, mul, min, max, None, gt, lt, eq
  39. def evaluate(ty, version, arg):
  40. return arg if ty == 4 else reduce(OPS[ty], starmap(evaluate, arg))
  41. packet = next(decode(bitstream(sys.stdin.readline().rstrip())))
  42. print(version_sum(*packet))
  43. print(evaluate(*packet))