const util = require("util"); const Vector3 = require("./Vector3"); const Moon = require("./Moon"); const input = parseInput([ "", "", "", "", ]); const tests = parseInput([ "", "", "", "", ]); const STEPS = 1000; for (let i = 0; i < STEPS; i++) { step(input); } console.log(`Total energy in system is: ${calculateTotalEnergy(input)}`); /** * Calculate one step of time * * @param {Moon[]} moons A list of moons * @returns {void} */ function step(moons) { for (let i = 0; i < moons.length - 1; i++) { for (let j = i + 1; j < moons.length; j++) { // Calculate Moon B's gravity influence on Moon A const firstGravity = calculateGravity(moons[i], moons[j]); // Invert the signage to represent Moon A's influence on Moon B const secondGravity = firstGravity.negate(); moons[i].velocity.add(firstGravity); moons[j].velocity.add(secondGravity); } } moons.forEach((moon) => { moon.position.add(moon.velocity); }); } /** * Find the gravitational influence two moons have on each other * * @param {Moon} moonA The first moon to consider * @param {Moon} moonB The second moon to consider * * @returns {Vector3} The gravitational influence of Moon B on Moon A */ function calculateGravity(moonA, moonB) { // The gravitational pull on Moon A caused by Moon B const gravityDifference = new Vector3( // eslint-disable-next-line no-nested-ternary moonB.position.x > moonA.position.x ? 1 : (moonB.position.x < moonA.position.x ? -1 : 0), // eslint-disable-next-line no-nested-ternary moonB.position.y > moonA.position.y ? 1 : (moonB.position.y < moonA.position.y ? -1 : 0), // eslint-disable-next-line no-nested-ternary moonB.position.z > moonA.position.z ? 1 : (moonB.position.z < moonA.position.z ? -1 : 0), ); return gravityDifference; } /** * Calculate the total energy in the system * * The total energy in the system is the sum of the sum of the positional * values multiplied by the sum of the velocity values. * * @param {Moon[]} moons The moons in the system * @returns {number} The total energy in the system */ function calculateTotalEnergy(moons) { let energy = 0; for (const moon of moons) { const potentialEnergy = Math.abs(moon.position.x) + Math.abs(moon.position.y) + Math.abs(moon.position.z); const kineticEnergy = Math.abs(moon.velocity.x) + Math.abs(moon.velocity.y) + Math.abs(moon.velocity.z); energy += potentialEnergy * kineticEnergy; } return energy; } /** * @param {string[]} inputs The day's input * @returns {Moon[]} An array of Moon objects */ function parseInput(inputs) { const moons = []; const parseRegex = new RegExp(/x=(-?\d+), y=(-?\d+), z=(-?\d+)/); for (const position of inputs) { // eslint-disable-next-line no-shadow-restricted-names const [undefined, x, y, z] = position.match(parseRegex); moons.push(new Moon(new Vector3(parseInt(x, 10), parseInt(y, 10), parseInt(z, 10)))); } return moons; } // console.log(util.inspect(parseInput(input)));