10_knots.py 1.2 KB

1234567891011121314151617181920212223242526272829303132333435363738
  1. #!/usr/bin/env python3
  2. import sys
  3. from functools import reduce
  4. from operator import xor
  5. def knot_round(nums, lengths, pos=0, skip=0, n=256):
  6. for length in lengths:
  7. for i in range(length // 2):
  8. left = (pos + i) % n
  9. right = (pos + length - i - 1) % n
  10. nums[left], nums[right] = nums[right], nums[left]
  11. pos = (pos + length + skip) % n
  12. skip = (skip + 1) % n
  13. return pos, skip
  14. def knot_hash(inp, rounds=64):
  15. lengths = tuple(map(ord, inp)) + (17, 31, 73, 47, 23)
  16. pos = skip = 0
  17. sparse = list(range(256))
  18. for r in range(rounds):
  19. pos, skip = knot_round(sparse, lengths, pos, skip)
  20. dense = [reduce(xor, sparse[i:i + 16]) for i in range(0, 256, 16)]
  21. return ''.join('%02x' % d for d in dense)
  22. # part 1
  23. inp = sys.stdin.readline().rstrip()
  24. sparse = list(range(256))
  25. knot_round(sparse, map(int, inp.split(',')))
  26. print(sparse[0] * sparse[1])
  27. # part 2
  28. assert knot_hash('') == 'a2582a3a0e66e6e86e3812dcb672a272'
  29. assert knot_hash('AoC 2017') == '33efeb34ea91902bb2f59c9920caa6cd'
  30. assert knot_hash('1,2,3') == '3efbe78a8d82f29979031a4aa0b16a9d'
  31. assert knot_hash('1,2,4') == '63960835bcdc130f0b66d7ff4f6a5a8e'
  32. print(knot_hash(inp))