Advertisement
Armandur

Untitled

Dec 8th, 2020
869
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 4.55 KB | None | 0 0
  1. import copy
  2.  
  3. program = []
  4.  
  5. with open("8 - input", 'r') as file:
  6.     lines = file.readlines()
  7.     for line in lines:
  8.         line = line.strip("\n")
  9.  
  10.         #Instruction nop +346
  11.         program.append\
  12.         (
  13.                 [line.split(" ")[0],            #   string "nop"
  14.                  line.split(" ")[1][0],         #   string "+"
  15.                  int(line.split(" ")[1][1:])]   #   integer 346
  16.         )
  17.  
  18.  
  19. def execute(index, instruction, acc, printLog=False):
  20.     spacer = "\t"
  21.     if index < 10:
  22.         spacer = spacer * 2
  23.  
  24.     if instruction[0] == "nop":
  25.         if printLog:
  26.             print(f"[{index}]{spacer}{instruction[0]}")
  27.  
  28.         return index + 1, acc   #   For nop instruction, we just move to the next instruction, acc has not been modified but we return it.
  29.  
  30.     elif instruction[0] == "acc":
  31.         if printLog:
  32.             print(f"[{index}]{spacer}{instruction[0]} with arg {instruction[1]}{instruction[2]}", end="")
  33.  
  34.         if instruction[1] == "+":
  35.             acc += instruction[2]   #   Add argument of instruction to acc
  36.  
  37.         elif instruction[1] == "-":
  38.             acc -= instruction[2]   #   Subtract argument of instruction to acc
  39.  
  40.         if printLog:
  41.             print(f", global acc: {acc}")
  42.  
  43.         return index + 1, acc   #   With acc instruction, we go to the next instruction in the program
  44.  
  45.     elif instruction[0] == "jmp":
  46.         if printLog:
  47.             print(f"[{index}]{spacer}{instruction[0]} {instruction[1]}{instruction[2]}", end="")
  48.  
  49.         if instruction[1] == "+":   #   We're jumping forward
  50.             if printLog:
  51.                 print(f", jmping to {index + instruction[2]}")
  52.             return index + instruction[2], acc  #   Return the next index to run, current index + the argument of the instruction, acc has not been modified
  53.  
  54.         elif instruction[1] == "-": #   We're jumping backwards
  55.             if printLog:
  56.                 print(f", jmping to {index - instruction[2]}")
  57.             return index - instruction[2], acc  #   Return the next index to run, current index - the argument of the instruction, acc has not been modified
  58.  
  59.     else:
  60.         print(f"{instruction} not valid!")  #   You have misspelled an instruction
  61.         exit(1)
  62.  
  63. def runProgram(_program, printLog = False):
  64.     acc = 0
  65.     index = 0
  66.     executedInstructions = []
  67.     while True:
  68.         if index >= len(program) or index < 0:      #   Program is about to run code outside of the inputted program
  69.             result = (acc, index, "Out of bounds")  #   Return current value of the acc variable, and the index the program stopped at and the errorcode
  70.             return result
  71.  
  72.         instruction = _program[index]               #   Get the current instruction
  73.         #print(f"\n{executedInstructions}")
  74.         if index not in executedInstructions:       #   No infinte loops allowed
  75.             executedInstructions.append(index)      #   Note that we have already run this instruction
  76.             index, acc = execute(index, instruction, acc, printLog) #   Execute the instruction and get the next instruction index, and the calculated value of acc
  77.         else:
  78.             result = (acc, index, "Infinite loop")  #   As we said - No fun allowed!
  79.             return result
  80.  
  81.  
  82. print(runProgram(program))  #   Run the original program
  83. print()
  84.  
  85. # part 2
  86. 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
  87. triedInstructions = []
  88. for i in range(0, len(program)):
  89.     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
  90.  
  91.     if i not in triedInstructions:      #   We only want to try each instruction once
  92.         if program[i][0] == "nop":
  93.             program[i][0] = "jmp"
  94.             #print(f"Switched instruction {programBak[i]} at {i} to {program[i]}")
  95.             triedInstructions.append(i) #   Note the instruction we've tried
  96.  
  97.         elif program[i][0] == "jmp":
  98.             program[i][0] = "nop"
  99.             #print(f"Switched instruction {programBak[i]} at {i} to {program[i]}")
  100.             triedInstructions.append(i)
  101.  
  102.         else:
  103.             continue    #   We only need to run the program if we've modified a jmp or nop instruction
  104.  
  105.         result = runProgram(program)
  106.         if result[2] == "Out of bounds":    #   We are looking for an out of bounds error
  107.             print(result)
  108.             exit(0)
  109.  
  110. print("Never got errorcode 'Out of bounds'")
  111. exit(1)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement