···1616 # Toggling instructions modifes the program, so operate on a copy instead.
1717 program = deepcopy(program)
18181919- while True:
2020- if pc >= len(program):
2121- return regs
2222-1919+ while pc < len(program):
2320 cmd, x, y = program[pc]
24212522 if cmd == 'cpy':
2626- # The following instructions simply perform multiplication:
2323+ # The following set of instructions performs multiplication:
2724 # cpy b c
2825 # inc a
2926 # dec c
3027 # jnz c -2
3128 # dec d
3229 # jnz d -5
3030+ #
3331 # Perform a peephole optimization by doing the following:
3432 # - Set a to b*d
3533 # - Set c and d to 0.
3636- # - Advance the PC by 5 instructions.
3434+ # - Advance the PC by 6 to jump past the instructions.
3735 next_cmds, next_regs = zip(*program[pc+1:pc+5])[0:2]
38363937 if x.isalpha() and next_cmds == ('inc', 'dec', 'jnz', 'dec'):
···4240 regs[a] = regs[x] * regs[d]
4341 regs[c] = 0
4442 regs[d] = 0
4545- pc += 5
4343+ pc += 6
4644 continue
47454848- # Ignore copy instructions that try to copy a value into an
4646+ # Ignore cpy instructions that try to copy a value into an
4947 # immediate value (occurs when toggling instructions).
5048 if y.isalpha():
5149 regs[y] = reg_or_val(regs, x)
···6462 continue
65636664 elif cmd == 'tgl':
6767- x = reg_or_val(regs, x)
6868- to_toggle = pc + x
6565+ i = pc + reg_or_val(regs, x)
6966 try:
7070- cng, nx, ny = program[to_toggle]
7171- except:
7272- pc += 1
7373- continue
7474-7575- if ny == 'null':
7676- if cng == 'inc':
7777- program[to_toggle][0] = 'dec'
7878- else:
7979- program[to_toggle][0] = 'inc'
6767+ ncmd, nx, ny = program[i]
6868+ except IndexError:
6969+ pass
8070 else:
8181- if cng == 'jnz':
8282- program[to_toggle][0] = 'cpy'
7171+ if ny == 'null':
7272+ program[i][0] = 'dec' if ncmd == 'inc' else 'inc'
8373 else:
8484- program[to_toggle][0] = 'jnz'
7474+ program[i][0] = 'cpy' if ncmd == 'jnz' else 'jnz'
85758676 pc += 1
7777+7878+ return regs
877988808981PROGRAM = []