Advent of Code 2016 solutions https://adventofcode.com/2016/
選択できるのは25トピックまでです。 トピックは、先頭が英数字で、英数字とダッシュ('-')を使用した35文字以内のものにしてください。

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798
  1. #!/usr/bin/python3
  2. """Solution for day 23 of Advent of Code 2016.
  3. This is loosely based on day 12's solution. As instructions can now be modified (by the TGL opcode), they're kept
  4. in a 'register' as well.
  5. For part two to work in a reasonable amount of time, try_multiply implements a look-ahead optimisation for
  6. basic multiplication. Instructions of the form
  7. cpy b c
  8. inc a
  9. dec c
  10. jnz c -2
  11. dec d
  12. jnz d -5
  13. Are actually incrementing a by b*d, and setting both c and d to 0. The optimisation supports any registers, as long
  14. as they're distinct. It also only applies if the whole block of six instructions is reached naturally (i.e., execution
  15. doesn't jump into the middle of it).
  16. """
  17. def value(registers, x):
  18. try:
  19. return int(x)
  20. except ValueError:
  21. return registers[x]
  22. def cpy(registers, src, dst):
  23. registers[dst] = value(registers, src)
  24. def inc(registers, reg):
  25. registers[reg] += 1
  26. def dec(registers, reg):
  27. registers[reg] -= 1
  28. def jnz(registers, val, tar):
  29. registers['pc'] += 0 if value(registers, val) == 0 else value(registers, tar) - 1
  30. def tgl(registers, ins):
  31. mappings = {inc: dec, dec: inc, tgl: inc, jnz: cpy, cpy: jnz}
  32. target = registers['pc'] + value(registers, ins)
  33. registers['in'][target] = (mappings[registers['in'][target][0]], registers['in'][target][1])
  34. def try_multiply(registers):
  35. try:
  36. pc = registers['pc']
  37. chunk = registers['in'][pc:pc+6]
  38. instr, args = map(list, zip(*chunk))
  39. if instr == [cpy, inc, dec, jnz, dec, jnz] \
  40. and args[0][1] == args[2][0] == args[3][0] \
  41. and args[4][0] == args[5][0] \
  42. and args[1][0] != args[0][1] != args[4][0] != args[0][0] \
  43. and args[3][1] == '-2' and args[5][1] == '-5':
  44. registers[args[1][0]] += value(registers, args[0][0]) * value(registers, args[4][0])
  45. registers[args[2][0]] = 0
  46. registers[args[4][0]] = 0
  47. registers['pc'] += 5
  48. return True
  49. except:
  50. pass
  51. return False
  52. def step(registers):
  53. if not try_multiply(registers):
  54. try:
  55. registers['in'][registers['pc']][0](registers, *registers['in'][registers['pc']][1])
  56. except:
  57. pass
  58. def run(values):
  59. registers = values
  60. registers['pc'] = 0
  61. registers['in'] = instr.copy()
  62. while registers['pc'] < len(instr):
  63. step(registers)
  64. registers['pc'] += 1
  65. return registers['a']
  66. with open('data/23.txt', 'r') as file:
  67. instr = map(str.split, map(str.strip, file.readlines()))
  68. instr = [(globals()[i[0]], i[1:]) for i in instr]
  69. print("Stage 1: %s" % run({'a': 7, 'b': 0, 'c': 0, 'd': 0}))
  70. print("Stage 2: %s" % run({'a': 12, 'b': 0, 'c': 0, 'd': 0}))