Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import copy
- program = []
- with open("8 - input", 'r') as file:
- lines = file.readlines()
- for line in lines:
- line = line.strip("\n")
- #Instruction nop +346
- program.append\
- (
- [line.split(" ")[0], # string "nop"
- line.split(" ")[1][0], # string "+"
- int(line.split(" ")[1][1:])] # integer 346
- )
- def execute(index, instruction, acc, printLog=False):
- spacer = "\t"
- if index < 10:
- spacer = spacer * 2
- if instruction[0] == "nop":
- if printLog:
- print(f"[{index}]{spacer}{instruction[0]}")
- return index + 1, acc # For nop instruction, we just move to the next instruction, acc has not been modified but we return it.
- elif instruction[0] == "acc":
- if printLog:
- print(f"[{index}]{spacer}{instruction[0]} with arg {instruction[1]}{instruction[2]}", end="")
- if instruction[1] == "+":
- acc += instruction[2] # Add argument of instruction to acc
- elif instruction[1] == "-":
- acc -= instruction[2] # Subtract argument of instruction to acc
- if printLog:
- print(f", global acc: {acc}")
- return index + 1, acc # With acc instruction, we go to the next instruction in the program
- elif instruction[0] == "jmp":
- if printLog:
- print(f"[{index}]{spacer}{instruction[0]} {instruction[1]}{instruction[2]}", end="")
- if instruction[1] == "+": # We're jumping forward
- if printLog:
- print(f", jmping to {index + instruction[2]}")
- return index + instruction[2], acc # Return the next index to run, current index + the argument of the instruction, acc has not been modified
- elif instruction[1] == "-": # We're jumping backwards
- if printLog:
- print(f", jmping to {index - instruction[2]}")
- return index - instruction[2], acc # Return the next index to run, current index - the argument of the instruction, acc has not been modified
- else:
- print(f"{instruction} not valid!") # You have misspelled an instruction
- exit(1)
- def runProgram(_program, printLog = False):
- acc = 0
- index = 0
- executedInstructions = []
- while True:
- if index >= len(program) or index < 0: # Program is about to run code outside of the inputted program
- result = (acc, index, "Out of bounds") # Return current value of the acc variable, and the index the program stopped at and the errorcode
- return result
- instruction = _program[index] # Get the current instruction
- #print(f"\n{executedInstructions}")
- if index not in executedInstructions: # No infinte loops allowed
- executedInstructions.append(index) # Note that we have already run this instruction
- index, acc = execute(index, instruction, acc, printLog) # Execute the instruction and get the next instruction index, and the calculated value of acc
- else:
- result = (acc, index, "Infinite loop") # As we said - No fun allowed!
- return result
- print(runProgram(program)) # Run the original program
- print()
- # part 2
- programBak = copy.deepcopy(program) # Our program list is a list of a list, if we would've used = or list.copy(), python would've given us only references
- triedInstructions = []
- for i in range(0, len(program)):
- program = copy.deepcopy(programBak) # We only want to change one (1) nop/jmp instruction at a time so we need to use a fresh, original program each time
- if i not in triedInstructions: # We only want to try each instruction once
- if program[i][0] == "nop":
- program[i][0] = "jmp"
- #print(f"Switched instruction {programBak[i]} at {i} to {program[i]}")
- triedInstructions.append(i) # Note the instruction we've tried
- elif program[i][0] == "jmp":
- program[i][0] = "nop"
- #print(f"Switched instruction {programBak[i]} at {i} to {program[i]}")
- triedInstructions.append(i)
- else:
- continue # We only need to run the program if we've modified a jmp or nop instruction
- result = runProgram(program)
- if result[2] == "Out of bounds": # We are looking for an out of bounds error
- print(result)
- exit(0)
- print("Never got errorcode 'Out of bounds'")
- exit(1)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement