DEV Community

Cover image for Advent of code - Day 8
Quentin Ménoret
Quentin Ménoret

Posted on

Advent of code - Day 8

Are you participating in the Advent of code this year?

If you don't know what the advent of code is, it's a website where you'll find a daily challenge (every day it gets harder). It's a really fun event, you should participate!

I try to solve the exercises using either JavaScript or TypeScript and will share my solutions daily (with one day delay so no one can cheat!). I only share the solution for the second part.

When I saw the exercise for day #8, I really though "oh boy, this one is going to be hardcore". I thought we'd need to implement a runtime for their weird assembly-like language. Lucky for us, this was way easier than what I assumed!

I basically just wrote a function that determines if the program exits successfully or not, and then run it agains every possible version of the assembly-like code. Here is what it looks like:

const SUCCESS = "SUCCESS";
const ERROR = "ERROR";

// Runs the program, and return SUCCESS or ERROR
// Depending on whether or not it finished (line number > code.length)
function runProgram(code) {
  // If a line is processed 2 times, it's an error
  const alreadyProcessed = [];
  let global = 0;
  let currentLine = 0;

  while (true) {
    if (alreadyProcessed[currentLine] === true) return { global, status: ERROR, alreadyProcessed };
    if (code[currentLine] === undefined)
      return { global, status: SUCCESS, alreadyProcessed };
    alreadyProcessed[currentLine] = true;
    const [inst, argument] = code[currentLine];
    switch (inst) {
      case "acc":
        global += parseInt(argument, 10);
        currentLine += 1;
        break;
      case "jmp":
        currentLine += parseInt(argument, 10);
        break;
      case "nop":
        currentLine += 1;
        break;
      default:
        throw new Error(inst);
    }
  }
}

// Let's just bruteforce, and run the program changing any
// line that is a nop or a jmp to find which one is corrupted
input.forEach((_value, index) => {
  const code = [...input];
  const [inst, argument] = code[index];
  if (inst === "jmp") code[index] = ["nop", argument];
  else if (inst === "nop") code[index] = ["jmp", argument];
  const altResult = runProgram(code);
  if (altResult.status === "SUCCESS") console.log(altResult);
});
Enter fullscreen mode Exit fullscreen mode

Feel free to share your solution in the comments!


Photo by Markus Spiske on Unsplash

Top comments (1)

Collapse
 
saukha profile image
Sau K • Edited

Dec 8, 2020

Part 1

import pandas as pd

df = pd.read_csv('12082020adventofcode.txt', sep=' ',
header=None, names=['Instruction', 'Argument'])

ind_list = list(range(0, len(df)))
ind_flip = []
acc_value = 0
ind = 0
copy_ind = 0

def acc(arg):
global acc_value
acc_value += arg
global ind
ind += 1

def jmp(arg):
global ind
ind += arg

def nop(arg):
global ind
ind += 1

while ind in ind_list:
copy_ind = ind
instr = df.loc[ind,'Instruction']
argu = df.loc[ind,'Argument']
ind_list.remove(ind)
global ind_flip
ind_flip.append(ind)
if instr == 'acc':
acc(argu)
elif instr == 'jmp':
jmp(argu)
elif instr == 'nop':
nop(argu)

print('#####################################')
print('Part 1:')
print('final acc_value:', acc_value)
print('last run ind:', copy_ind)
print(df.loc[copy_ind,:])
print('repeated ind:', ind)
print(df.loc[ind,:])
print('ind_flip for part 2:', ind_flip)
print('#####################################')

part 2

ind_list = list(range(0, len(df)))
acc_value = 0
ind = 0
copy_ind = 0

def flip(row):
instru = df.loc[row,'Instruction']
if instru == 'jmp':
df.loc[row,'Instruction'] = 'nop'
elif instru == 'nop':
df.loc[row,'Instruction'] = 'jmp'

def while_loop(x):
global ind
ind = x
while ind in ind_list:
instr = df.loc[ind,'Instruction']
argu = df.loc[ind,'Argument']
global copy_ind
copy_ind = ind
ind_list.remove(ind)
if instr == 'acc':
acc(argu)
elif instr == 'jmp':
jmp(argu)
elif instr == 'nop':
nop(argu)

for i in ind_flip:
flip(int(i))
while_loop(ind)
flip(int(i))
if copy_ind == len(df)-1:
break
ind_list = list(range(0, len(df)))
acc_value = 0
ind = 0
copy_ind = 0

print('#####################################')
print('Part 2:')
print('last run ind:', copy_ind)
print('final acc_value:', acc_value)

print(df.loc[copy_ind,:])
print('#####################################')