DEV Community

Discussion on: Advent of Code 2019 Solution Megathread - Day 7: Amplification Circuit

Collapse
 
mellen profile image
Matt Ellen • Edited

Part 1: oh gods, so many for loops

(using basically the same intcode processor from day 5, except output is put into a variable instead of output to the console)

function day7part1()
{
    let highest = 0;
    for(let a = 0; a < 5; a++)
    {
        let ainp = process([a, 0]);
        for(let b = 0; b < 5; b++)
        {
            if(b == a)
            {
                continue;
            }
            let binp = process([b, ainp]);
            for(let c = 0; c < 5; c++)
            {
                if(c == b || c == a)
                {
                    continue;
                }
                let cinp = process([c, binp]);
                for(let d = 0; d < 5; d++)
                {
                    if(d == a || d == b || d == c)
                    {
                        continue;
                    }
                    let dinp = process([d, cinp]);
                    for(let e = 0; e < 5; e++)
                    {
                        if(e == a || e == b || e == c || e == d)
                        {
                            continue;
                        }
                        let outp = parseInt(process([e, dinp]), 10);
                        if(outp > highest)
                        {
                            highest = outp;
                        }
                    }
                }
            }
        }
    }

    return highest;
}
Collapse
 
mellen profile image
Matt Ellen • Edited

FINALLY got part 2 done. Had to mess around so much:

function getPermutations(phases)
{
    if(phases.length === 2)
    {
        return [[phases[0], phases[1]], [phases[1], phases[0]]];
    }

    let perms = [];

    for(let pi = 0; pi < phases.length; pi++)
    {
        let others = phases.slice(0, pi).concat(phases.slice(pi+1, phases.length));
        let next = [];
        let otherPerms = getPermutations(others);
        for(let op of otherPerms)
        {
            op.unshift(phases[pi]);
            next.push(op);
        }
        perms = perms.concat(next);
    }

    return perms;
}

function day7part2()
{
    const pretext = document.getElementsByTagName('pre')[0].innerHTML.trim();
    let instructions = pretext.split(',');

    let highest = 0;

    let possiblephases = [5,6,7,8,9];
    let setofphases = getPermutations(possiblephases);

    for(let phases of setofphases)
    {
        let amps = phases.map((phase, index) => new Amp(new Processor(instructions), phase, String.fromCodePoint('A'.charCodeAt(0) + index)));
        for(let ai = 0; ai < amps.length - 1; ai++)
        {
            amps[ai].next = amps[ai+1];
        }

        amps[amps.length - 1].next = amps[0];

        let curAmp = amps[0];
        curAmp.takeSignal(0);
        while(!amps[amps.length - 1].done)
        {
            curAmp.run();
            curAmp = curAmp.next;
        }

        if(parseInt(amps[amps.length - 1].output) > highest)
        {
            highest = parseInt(amps[amps.length - 1].output);
        }
    }

    return highest;
}

function Processor(instructions)
{
    this.instructions = instructions.map(i => i);
    this.instructionPointer = 0;
    this.input = [];
    this.inputPointer = 0;
    this.output = null;
    this.running = false;
    this.sendOutput = null;
    this.opToLength =
        {
            '01': 4,
            '02': 4,
            '03': 2,
            '04': 2,
            '05': 3,
            '06': 3,
            '07': 4,
            '08': 4,
            '99': 1
        };
    this.opToFunc =
        {
            '01': (modes, a, b, p) =>
                {
                    a = this.modeSwitch(a, modes[0]);
                    b = this.modeSwitch(b, modes[1]);

                    this.instructions[p] = (a+b).toString();
                },
            '02': (modes, a, b, p) =>
                {
                    a = this.modeSwitch(a, modes[0]);
                    b = this.modeSwitch(b, modes[1]);

                    this.instructions[p] = (a*b).toString();
                },
            '03': (modes, p, _, __) =>
                {
                    this.instructions[p] = this.input[this.inputPointer].toString();
                    this.inputPointer++;
                },
            '04': (modes, p, _, __) =>
                {
                    this.output = this.instructions[p];
                },
            '05': (modes, a, p, _) =>
                {
                    a = this.modeSwitch(a, modes[0]);
                    p = this.modeSwitch(p, modes[1]);
                    if(a !== 0)
                    {
                        this.instructionPointer = p;
                        this.opToLength['05'] = 0; 
                    }
                    else
                    {
                        this.opToLength['05'] = 3;
                    }
                },
            '06': (modes, a, p, _) =>
                {
                    a = this.modeSwitch(a, modes[0]);
                    p = this.modeSwitch(p, modes[1]);
                    if(a === 0)
                    {
                        this.instructionPointer = p;
                        this.opToLength['06'] = 0;
                    }
                    else
                    {
                        this.opToLength['06'] = 3;
                    }
                },
            '07': (modes, a, b, p) =>
                {
                    a = this.modeSwitch(a, modes[0]);
                    b = this.modeSwitch(b, modes[1]);

                    this.instructions[p] = a < b ? '1' : '0';
                },
            '08': (modes, a, b, p) =>
                {
                    a = this.modeSwitch(a, modes[0]);
                    b = this.modeSwitch(b, modes[1]);

                    this.instructions[p] = a === b ? '1' : '0';
                },
            '99': (_,__,___,____) =>
                {
                    this.running = false;
                }
        };
}

Processor.prototype.modeSwitch = function(value, mode)
{
    if(mode == 0)
    {
        return parseInt(this.instructions[value]);
    }

    return value;
};

Processor.prototype.step = function()
{
    let inst = this.instructions[this.instructionPointer].padStart(5, '0');
    let opcode = inst.slice(-2);
    let parameterModes = inst.substr(0,3).split('').reverse();
    let a = parseInt(this.instructions[this.instructionPointer+1]);
    let b = parseInt(this.instructions[this.instructionPointer+2]);
    let p = parseInt(this.instructions[this.instructionPointer+3]);
    if(typeof(this.opToFunc[opcode]) === 'undefined')
    {
        console.log('error: inst', inst, 'op:',opcode, 'a', a, 'b', b, 'p', p, 'index', this.instructionPointer);
    }   
    this.opToFunc[opcode](parameterModes, a, b, p);
    let instructionInc = this.opToLength[opcode];
    this.instructionPointer += instructionInc;
};

Processor.prototype.start = function()
{
    this.running = true;
};

Processor.prototype.takeOutput = function()
{
    let result = this.output;
    this.output = null;
    return result;
};

Processor.prototype.addInput = function(value)
{
    this.input.push(value);
};

function Amp(processor, phase, name)
{
    this.processor = processor;
    this.phase = phase
    this.next = null;
    this.done = false;
    this.output = null;
    this.name = name;

    this.processor.addInput(this.phase);
}

Amp.prototype.toString = function()
{
    return `Amp ${this.name}, phase ${this.phase}, done ${this.done}, output ${this.output}`;
};

Amp.prototype.run = function()
{
    if(!this.processor.running)
    {
        this.processor.start();
    }

    let output = null;
    while(this.processor.running && output == null)
    {
        this.processor.step();
        output = this.processor.takeOutput();
    }

    if(output != null)
    {
        this.next.takeSignal(output);
        this.output = parseInt(output);
    }

    this.done = !this.processor.running;
};

Amp.prototype.takeSignal = function(signal)
{
    this.processor.addInput(signal);
};

For some reason I can't get this to work with part 1, but I'm done worrying about it. 😠