ApisNecros 1 anno fa
parent
commit
581e84a46d
6 ha cambiato i file con 506 aggiunte e 0 eliminazioni
  1. 110 0
      1/1_1.js
  2. 123 0
      1/1_2.js
  3. 16 0
      2/2_1.js
  4. 47 0
      2/2_2.js
  5. 107 0
      IntComp/Computer.js
  6. 103 0
      IntComp/Stack.js

+ 110 - 0
1/1_1.js

@@ -0,0 +1,110 @@
+const input = [
+    94164
+    , 100562
+    , 114499
+    , 134308
+    , 138764
+    , 114494
+    , 70457
+    , 113793
+    , 117753
+    , 77795
+    , 110371
+    , 113357
+    , 118839
+    , 99757
+    , 119918
+    , 145232
+    , 147113
+    , 142411
+    , 93053
+    , 81783
+    , 124022
+    , 98470
+    , 77368
+    , 75163
+    , 79175
+    , 131174
+    , 93196
+    , 121875
+    , 86016
+    , 148758
+    , 126577
+    , 109812
+    , 105696
+    , 66318
+    , 146939
+    , 113236
+    , 130014
+    , 135719
+    , 127114
+    , 69700
+    , 109416
+    , 64168
+    , 89215
+    , 69015
+    , 128511
+    , 59682
+    , 79067
+    , 58795
+    , 145447
+    , 129419
+    , 93058
+    , 63860
+    , 146148
+    , 58364
+    , 74149
+    , 81871
+    , 116469
+    , 131739
+    , 132852
+    , 148040
+    , 98865
+    , 56588
+    , 79326
+    , 114713
+    , 52397
+    , 134887
+    , 114809
+    , 113356
+    , 60505
+    , 142323
+    , 84792
+    , 117079
+    , 147796
+    , 50196
+    , 148897
+    , 100794
+    , 50508
+    , 71023
+    , 149350
+    , 66679
+    , 93680
+    , 116069
+    , 133042
+    , 117291
+    , 127439
+    , 81598
+    , 93163
+    , 83964
+    , 64226
+    , 63026
+    , 82625
+    , 59589
+    , 94831
+    , 66807
+    , 120375
+    , 112108
+    , 83484
+    , 109892
+    , 66136
+    , 126794
+];
+
+function CalculateShipMass(moduleMasses) {
+    const calcultedMasses = moduleMasses.map((mass) => Math.floor(mass / 3) - 2);
+    const totalMass = calcultedMasses.reduce((totalMass, currValue) => totalMass + currValue);
+    return totalMass;
+}
+
+console.log(CalculateShipMass(input));

+ 123 - 0
1/1_2.js

@@ -0,0 +1,123 @@
+const input = [
+    94164
+    , 100562
+    , 114499
+    , 134308
+    , 138764
+    , 114494
+    , 70457
+    , 113793
+    , 117753
+    , 77795
+    , 110371
+    , 113357
+    , 118839
+    , 99757
+    , 119918
+    , 145232
+    , 147113
+    , 142411
+    , 93053
+    , 81783
+    , 124022
+    , 98470
+    , 77368
+    , 75163
+    , 79175
+    , 131174
+    , 93196
+    , 121875
+    , 86016
+    , 148758
+    , 126577
+    , 109812
+    , 105696
+    , 66318
+    , 146939
+    , 113236
+    , 130014
+    , 135719
+    , 127114
+    , 69700
+    , 109416
+    , 64168
+    , 89215
+    , 69015
+    , 128511
+    , 59682
+    , 79067
+    , 58795
+    , 145447
+    , 129419
+    , 93058
+    , 63860
+    , 146148
+    , 58364
+    , 74149
+    , 81871
+    , 116469
+    , 131739
+    , 132852
+    , 148040
+    , 98865
+    , 56588
+    , 79326
+    , 114713
+    , 52397
+    , 134887
+    , 114809
+    , 113356
+    , 60505
+    , 142323
+    , 84792
+    , 117079
+    , 147796
+    , 50196
+    , 148897
+    , 100794
+    , 50508
+    , 71023
+    , 149350
+    , 66679
+    , 93680
+    , 116069
+    , 133042
+    , 117291
+    , 127439
+    , 81598
+    , 93163
+    , 83964
+    , 64226
+    , 63026
+    , 82625
+    , 59589
+    , 94831
+    , 66807
+    , 120375
+    , 112108
+    , 83484
+    , 109892
+    , 66136
+    , 126794
+];
+
+const demo = [14];
+
+function CalculateFuelMass(fuelWeight) {
+    const fuelForFuel = Math.floor(fuelWeight / 3) - 2;
+    return fuelForFuel <= 0 ? 0 : fuelForFuel + CalculateFuelMass(fuelForFuel);
+}
+
+function CalculateShipMass(moduleMasses) {
+    const calcultedMasses = moduleMasses.map((mass) => {
+        const fuelForMass = Math.floor(mass / 3) - 2;
+        // console.log(`DEBUG: fuelForMass: ${fuelForMass}`);
+        // console.log(`DEBUG: CalculateFuelMass: ${CalculateFuelMass(fuelForMass)}`);
+        return fuelForMass + CalculateFuelMass(fuelForMass);
+    });
+    const totalMass = calcultedMasses.reduce((totalMass, currValue) => totalMass + currValue);
+    // console.log(`DEBUG: totalMass: ${totalMass}`);
+    return totalMass;
+}
+
+console.log(CalculateShipMass(input));

+ 16 - 0
2/2_1.js

@@ -0,0 +1,16 @@
+const Computer = require("../IntComp/Computer");
+
+const input = [1, 12, 0, 3, 1, 1, 2, 3, 1, 3, 4, 3, 1, 5, 0, 3, 2, 1, 13, 19, 1, 9, 19, 23, 1, 6, 23, 27, 2, 27, 9, 31, 2, 6, 31, 35, 1, 5, 35, 39, 1, 10, 39, 43, 1, 43, 13, 47, 1, 47, 9, 51, 1, 51, 9, 55, 1, 55, 9, 59, 2, 9, 59, 63, 2, 9, 63, 67, 1, 5, 67, 71, 2, 13, 71, 75, 1, 6, 75, 79, 1, 10, 79, 83, 2, 6, 83, 87, 1, 87, 5, 91, 1, 91, 9, 95, 1, 95, 10, 99, 2, 9, 99, 103, 1, 5, 103, 107, 1, 5, 107, 111, 2, 111, 10, 115, 1, 6, 115, 119, 2, 10, 119, 123, 1, 6, 123, 127, 1, 127, 5, 131, 2, 9, 131, 135, 1, 5, 135, 139, 1, 139, 10, 143, 1, 143, 2, 147, 1, 147, 5, 0, 99, 2, 0, 14, 0];
+
+const demos = [
+    [1, 9, 10, 3, 2, 3, 11, 0, 99, 30, 40, 50],
+    [1, 0, 0, 0, 99],
+    [2, 3, 0, 3, 99],
+    [2, 4, 4, 5, 99, 0],
+    [1, 1, 1, 4, 99, 5, 6, 0, 99],
+];
+
+const computer = new Computer(demos[0]);
+computer.Run();
+console.log(computer.stack.Get(0));
+// computer.DumpMemory();

+ 47 - 0
2/2_2.js

@@ -0,0 +1,47 @@
+const Computer = require("../IntComp/Computer");
+
+const input = [1, 12, 0, 3, 1, 1, 2, 3, 1, 3, 4, 3, 1, 5, 0, 3, 2, 1, 13, 19, 1, 9, 19, 23, 1, 6, 23, 27, 2, 27, 9, 31, 2, 6, 31, 35, 1, 5, 35, 39, 1, 10, 39, 43, 1, 43, 13, 47, 1, 47, 9, 51, 1, 51, 9, 55, 1, 55, 9, 59, 2, 9, 59, 63, 2, 9, 63, 67, 1, 5, 67, 71, 2, 13, 71, 75, 1, 6, 75, 79, 1, 10, 79, 83, 2, 6, 83, 87, 1, 87, 5, 91, 1, 91, 9, 95, 1, 95, 10, 99, 2, 9, 99, 103, 1, 5, 103, 107, 1, 5, 107, 111, 2, 111, 10, 115, 1, 6, 115, 119, 2, 10, 119, 123, 1, 6, 123, 127, 1, 127, 5, 131, 2, 9, 131, 135, 1, 5, 135, 139, 1, 139, 10, 143, 1, 143, 2, 147, 1, 147, 5, 0, 99, 2, 0, 14, 0];
+
+const demos = [
+    [1, 9, 10, 3, 2, 3, 11, 0, 99, 30, 40, 50],
+    [1, 0, 0, 0, 99],
+    [2, 3, 0, 3, 99],
+    [2, 4, 4, 5, 99, 0],
+    [1, 1, 1, 4, 99, 5, 6, 0, 99],
+];
+
+function CalculateNounPlusVerb(noun, verb, expected) {
+    const freshMemory = JSON.parse(JSON.stringify(input));
+
+    freshMemory[1] = noun;
+    freshMemory[2] = verb;
+
+    const comp = new Computer(freshMemory);
+    comp.Run();
+    return comp.stack.Get(0) == expected;
+}
+
+function LoopNounsAndVerbs() {
+    const EXPECTED = 19690720;
+    let noun = 0;
+    let verb = 0;
+    for (noun = 0; noun < 100; noun++) {
+        for (verb = 0; verb < 100; verb++) {
+            if (CalculateNounPlusVerb(noun, verb, EXPECTED)) {
+                return 100 * noun + verb;
+            }
+        }
+    }
+
+    return false;
+}
+
+const output = LoopNounsAndVerbs();
+
+if (output !== false) {
+    console.log(`Answer: ${output}`);
+}
+else {
+    console.log("Couldn't find answer");
+}
+// computer.DumpMemory();

+ 107 - 0
IntComp/Computer.js

@@ -0,0 +1,107 @@
+const Stack = require("./Stack");
+
+/**
+ * An Intcode Computer for the Advent of Code 2019 challenge
+ *
+ * @author Apis Necros
+ */
+module.exports = class Computer {
+    constructor(stack) {
+        this.stack = new Stack(stack);
+        this.OPCODES = {
+            ADD: 1,
+            MULTIPLY: 2,
+            HALT: 99,
+        };
+    }
+
+    /**
+     * Run the computer
+     *
+     * Runs opcodes on the stack until either the a HALT command is
+     * encountered, or an error is thrown.
+     * @returns {void}
+     */
+    Run() {
+        // eslint-disable-next-line no-empty
+        while (this.Execute(this.stack.Get()) === true) { }
+    }
+
+    /**
+     * Execute a call using the provided opcode
+     *
+     * @param {number} opcode A opcode to execute
+     * @returns {boolean} False if the opcode was HALT, otherwise true
+     */
+    Execute(opcode) {
+        // console.log(`DEBUG: opcode: ${opcode}`)
+        let status = true;
+        switch (opcode) {
+            case this.OPCODES.ADD: {
+                const operandLeft = this.stack.Next().GetUsingStackValue();
+                const operandRight = this.stack.Next().GetUsingStackValue();
+                const position = this.stack.Next().Get();
+
+                this.Operation_Add(operandLeft, operandRight, position);
+                break;
+            }
+            case this.OPCODES.MULTIPLY: {
+                const operandLeft = this.stack.Next().GetUsingStackValue();
+                const operandRight = this.stack.Next().GetUsingStackValue();
+                const position = this.stack.Next().Get();
+
+                this.Operation_Multiply(operandLeft, operandRight, position);
+                break;
+            }
+            case this.OPCODES.HALT:
+                status = false;
+                break;
+            default:
+                throw Error(`Opcode ${opcode} not found`);
+        }
+
+        this.stack.Next();
+
+        return status;
+    }
+
+    /**
+     * Execute the Add opcode
+     *
+     * Adds two numbers and stores the result at the provided position
+     * on the stack.
+     *
+     * @param {number} operandLeft The first operand
+     * @param {number} operandRight The second operand
+     * @param {number} outputPosition The position on the stack to place the result
+     * @returns {void}
+     */
+    Operation_Add(operandLeft, operandRight, outputPosition) {
+        const newValue = operandLeft + operandRight;
+        this.stack.Put(outputPosition, newValue);
+    }
+
+    /**
+     * Execute the Multiply opcode
+     *
+     * Multiplies two numbers and stores the result at the provided
+     * position on the stack.
+     *
+     * @param {number} operandLeft The first operand
+     * @param {number} operandRight The second operand
+     * @param {number} outputPosition The position on the stack to place the result
+     * @returns {void}
+     */
+    Operation_Multiply(operandLeft, operandRight, outputPosition) {
+        const newValue = operandLeft * operandRight;
+        this.stack.Put(outputPosition, newValue);
+    }
+
+    /**
+     * Outputs the computer's stack to the console
+     * @returns {void}
+     */
+    DumpMemory() {
+        console.log(this.stack.Dump());
+    }
+};

+ 103 - 0
IntComp/Stack.js

@@ -0,0 +1,103 @@
+/**
+ * The stack, or memory, for the Intcode Computer
+ *
+ * @author Apis Necros
+ */
+module.exports = class Stack {
+    constructor(stack) {
+        this.pointer = 0;
+        this._stack = stack;
+    }
+
+    /**
+     * Move the stack's pointer to the right by 1
+     * @returns {void}
+     */
+    Next() {
+        this.pointer++;
+        return this;
+    }
+
+    /**
+     * Move the stack's pointer to the left by 1
+     * @returns {void}
+     */
+    Prev() {
+        this.pointer--;
+    }
+
+    /**
+     * Get a value from the stack
+     *
+     * If an index isn't given, retrieves the value at the current
+     * location of the pointer
+     *
+     * @param {?number} index The index of the value to retrieve
+     * @returns {number} The value at the given index, or 0
+     */
+    Get(index = null) {
+        if (index !== null && (Number.isNaN(index) || !Number.isInteger(index))) {
+            throw new TypeError("index must be an integer");
+        }
+
+        try {
+            return index !== null ? this._stack[index] : this._stack[this.pointer];
+        }
+        catch (e) {
+            return 0;
+        }
+    }
+
+    /**
+     * Use the value at the current pointer to get a value at another position
+     *
+     * This is essentially shorthand for `stack.Get(stack.Get())`
+     *
+     * @returns {number} The value at the index given by the pointer's current position
+     */
+    GetUsingStackValue() {
+        return this.Get(this._stack[this.pointer]);
+    }
+
+    /**
+     * Push a new value onto the end of the stack
+     *
+     * @param {number} value The value to add
+     * @returns {void}
+     */
+    Push(value) {
+        this._stack[++this.pointer] = value;
+    }
+
+    /**
+     * Pop a value off the end of the stack
+     *
+     * @returns {number}
+     * @returns {void}
+     */
+    Pop() {
+        return this._stack.pop();
+    }
+
+    /**
+     * Overwrite the value at a given index with a new value
+     *
+     * The index need not be defined
+     *
+     * @param {number} index The index on the stack to write a value to
+     * @param {number} value The value to write to that position
+     * @returns {void}
+     */
+    Put(index, value) {
+        this._stack[index] = value;
+    }
+
+    /**
+     * Return the whole stack
+     *
+     * @returns {number[]} The current stack
+     */
+    Dump() {
+        return this._stack;
+    }
+};