Advent of Code 2016 solutions https://adventofcode.com/2016/
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

21.py 2.4KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667
  1. #!/usr/bin/python3
  2. """Solution for day 21 of Advent of Code 2016.
  3. Each operation has an entry in the ops dictionary, which mangles arguments and does pre-processing before handing off
  4. to one of the main methods to perform the actual transformation.
  5. For part two, the reverse_ops dictionary maps most operations to a reverse of their original. The only exception is
  6. 'rotate based on position', which is just brute-forced by rotating the letters and seeing if the forward instruction
  7. puts them back to the expected positions.
  8. """
  9. from functools import reduce
  10. ops = {
  11. 'swap position': lambda l, a: swap_positions(l, int(a[0]), int(a[3])),
  12. 'swap letter': lambda l, a: swap_letter(l, a[0], a[3]),
  13. 'rotate left': lambda l, a: rotate(l, -int(a[0])),
  14. 'rotate right': lambda l, a: rotate(l, int(a[0])),
  15. 'rotate based': lambda l, a: rotate(l, 1 + l.index(a[4]) + (1 if l.index(a[4]) > 3 else 0)),
  16. 'reverse positions': lambda l, a: reverse(l, int(a[0]), int(a[2])),
  17. 'move position': lambda l, a: move(l, int(a[0]), int(a[3])),
  18. }
  19. reverse_ops = {
  20. 'swap position': lambda l, a: swap_positions(l, int(a[3]), int(a[0])),
  21. 'swap letter': ops['swap letter'],
  22. 'rotate left': ops['rotate right'],
  23. 'rotate right': ops['rotate left'],
  24. 'rotate based': lambda l, a: reverse_rotation(l, a),
  25. 'reverse positions': ops['reverse positions'],
  26. 'move position': lambda l, a: move(l, int(a[3]), int(a[0])),
  27. }
  28. def swap_positions(letters, x, y):
  29. letters[x], letters[y] = letters[y], letters[x]
  30. return letters
  31. def swap_letter(letters, a, b):
  32. return [a if l == b else b if l == a else l for l in letters]
  33. def rotate(letters, num):
  34. num %= len(letters)
  35. return letters[-num:] + letters[:-num]
  36. def reverse(letters, start, end):
  37. return letters[:start] + letters[start:end+1][::-1] + letters[end+1:]
  38. def move(letters, start, end):
  39. letters.insert(end, letters.pop(start))
  40. return letters
  41. def reverse_rotation(l, a):
  42. return [rotate(l, i) for i in range(len(l)) if ops['rotate based'](rotate(l, i), a) == l][0]
  43. with open('data/21.txt', 'r') as file:
  44. instr = list(map(lambda x: [' '.join(x.split(' ')[0:2])] + x.strip().split(' ')[2:], file.readlines()))
  45. print('Part one: %s' % ''.join(reduce(lambda l, o: ops[o[0]](l, o[1:]), instr, list('abcdefgh'))))
  46. print('Part two: %s' % ''.join(reduce(lambda l, o: reverse_ops[o[0]](l, o[1:]), instr[::-1], list('fbgdceah'))))