|
@@ -0,0 +1,68 @@
|
|
|
|
+const Moon = require("./Moon");
|
|
|
|
+const Vector3 = require("./Vector3");
|
|
|
|
+
|
|
|
|
+/**
|
|
|
|
+ * @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;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+/**
|
|
|
|
+ * 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;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+module.exports = {
|
|
|
|
+ parseInput,
|
|
|
|
+ step,
|
|
|
|
+};
|