My solutions to Advent of Code.
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.
 
 
 
 

75 lines
2.3 KiB

class Instruction:
LEGAL_CMDS = ['acc', 'jmp', 'nop']
def __init__(self, line):
self.cmd, self.arg = line.strip().split(' ')
if self.cmd not in self.LEGAL_CMDS:
raise ValueError('invalid command: {0}'.format(
line.strip()))
self.arg = int(self.arg)
self.run_count = 0
class GameConsole:
def __init__(self):
self.accumulator = 0
self.instr_idx = 0
self.instructions = []
with open('input.txt', 'r') as f:
while True:
line = f.readline()
if not len(line):
break
self.instructions.append(Instruction(line))
def run(self):
while True:
if self.instr_idx == len(self.instructions):
break
if self.instr_idx >= len(self.instructions) \
or self.instr_idx < 0:
raise IndexError('instruction index out of range')
instr = self.instructions[self.instr_idx]
if instr.run_count != 0:
raise RuntimeError('second execution, acc is {0}'.format(
self.accumulator))
instr.run_count += 1
if instr.cmd == 'nop':
pass
elif instr.cmd == 'acc':
self.accumulator += instr.arg
elif instr.cmd == 'jmp':
self.instr_idx += instr.arg
else:
raise ValueError('unknown command "{0}"'.format(instr.cmd))
if instr.cmd != 'jmp':
self.instr_idx += 1
def find_bad_instruction():
orig_gc = GameConsole()
instr_count = len(orig_gc.instructions)
for instr_idx in range(instr_count):
if orig_gc.instructions[instr_idx].cmd == 'acc':
continue
print('{0:.2f} %'.format(instr_idx / instr_count * 100))
gc = GameConsole()
instr = gc.instructions[instr_idx]
instr.cmd = 'jmp' if instr.cmd == 'nop' else 'nop'
try:
gc.run()
except (IndexError, RuntimeError):
continue
return instr_idx, gc.accumulator
raise RuntimeError('did not find the bad instruction')
if __name__ == '__main__':
print('bad instruction was #{0}, acc is {1}'.format(
*find_bad_instruction()))