DEV Community

Discussion on: AoC Day 19: Go With the Flow

Collapse
 
themindfuldev profile image
Tiago Romero Garcia

JavaScript solution

I have a generic solution for Part 1 and a customized solution to my input for Part 2.

For Part 2, because it was taking forever, I decided to print the output and let it run for a few minutes and try to understand how the registers vary and why.

Then I followed the suggestions from @jmgimeno and analyzed my program to understand what should happen and what does the loop try to accomplish, and after some deep thoughts I concluded the register 0 is the sum of the dividers of the number in register 2! So I did that algorithm myself, manually.

I'm gonna omit reader.js which is the same as the other solutions and jump to the point:

19-common.js

const {
    operations
} = require('./16-common');

const readInput = lines => {
    const ipRegex = /^#ip (?<ipRegister>\d)$/;
    const instructionRegex = /^(?<op>\w+) (?<a>\d+) (?<b>\d+) (?<c>\d+)$/;

    let ipRegister;
    const program = [];
    for (const line of lines) {
        if (ipRegister === undefined) {
            const match = line.match(ipRegex);
            if (match) {
                ipRegister = +match.groups.ipRegister;
            }
        }
        else {
            const match = line.match(instructionRegex);
            if (match) {
                const { op, a, b, c } = match.groups;
                program.push([op, +a, +b, +c]);
            }
        }
    }
    return { ipRegister, program };
};

const runProgram = (ipRegister, program, registers) => {
    const n = program.length;
    let ip = registers[ipRegister];
    let i = 0;
    while (ip >= 0 && ip < n) {
        const instruction = program[ip];
        const op = operations[instruction[0]];
        registers = op(instruction)(registers);
        ip = ++registers[ipRegister];
        i++;
        i % 1000000 === 0 && console.log(`${i}, ${registers.join(',')}`);
    }

    return registers;
};

module.exports = {
    readInput,
    runProgram
};

19a.js

const { readFile } = require('./reader');
const {
    readInput,
    runProgram
} = require ('./19-common');

(async () => {
    const lines = await readFile('19-input.txt');

    const { ipRegister, program } = readInput(lines);

    const result = runProgram(ipRegister, program, [0, 0, 0, 0, 0, 0]);

    console.log(`The state of the registers after executing the test program is ${result}`);
})();

19b.js

const { readFile } = require('./reader');
const {
    readInput,
    runProgram
} = require ('./19-common');

const analyzeProgram = (ipRegister, program) => {
    for (let i = 0; i < program.length; i++) {
        const [op, a, b, c] = program[i];
        let analysis;
        const target = c === ipRegister ? 'jumps ip to ' : `[${c}] = `;
        if (op === 'addi') { //result[c] = registers[a] + b; 
            analysis = target + `[${a}] + ${b}`;
        }
        else if (op === 'addr') { //result[c] = registers[a] + registers[b]; 
            analysis = target + `[${a}] + [${b}]`;
        } 
        else if (op === 'seti') { //result[c] = a; 
            analysis = target + `${a}`;
        }
        else if (op === 'setr') { //result[c] = registers[a]; 
            analysis = target + `[${a}]`;
        }
        else if (op === 'muli') { //result[c] = registers[a] * b; 
            analysis = target + `[${a}] * ${b}`;
        }
        else if (op === 'mulr') { //result[c] = registers[a] * registers[b]; 
            analysis = target + `[${a}] * [${b}]`;
        } 
        else if (op === 'eqrr') { //result[c] = registers[a] === registers[b] ? 1 : 0;
            analysis = target + `1 if [${a}] === [${b}] or 0 otherwise`;
        } 
        else if (op === 'gtrr') { //result[c] = registers[a] > registers[b] ? 1 : 0; 
            analysis = target + `1 if [${a}] > [${b}] or 0 otherwise`;
        } 
        console.log(`${i}: ${analysis}`);
    }
};

const runOptimizedProgram = () => {
    const number = 10551298;
    let sumDivisors = 0;
    for (let i = 1; i <= number; i++) {
        if (number % i === 0) {
            sumDivisors += i;
        }
    }
    return sumDivisors;
}

(async () => {
    const lines = await readFile('19-input.txt');

    //const { ipRegister, program } = readInput(lines);
    //analyzeProgram(ipRegister, program);
    //const result = runProgram(ipRegister, program, [1, 0, 0, 0, 0, 0]);

    const result = runOptimizedProgram();
    console.log(`The state of the registers after executing the test program is ${result}`);
})();