common.js 2.1 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768
  1. const Moon = require("./Moon");
  2. const Vector3 = require("./Vector3");
  3. /**
  4. * @param {string[]} inputs The day's input
  5. * @returns {Moon[]} An array of Moon objects
  6. */
  7. function parseInput(inputs) {
  8. const moons = [];
  9. const parseRegex = new RegExp(/x=(-?\d+), y=(-?\d+), z=(-?\d+)/);
  10. for (const position of inputs) {
  11. // eslint-disable-next-line no-shadow-restricted-names
  12. const [undefined, x, y, z] = position.match(parseRegex);
  13. moons.push(new Moon(new Vector3(parseInt(x, 10), parseInt(y, 10), parseInt(z, 10))));
  14. }
  15. return moons;
  16. }
  17. /**
  18. * Calculate one step of time
  19. *
  20. * @param {Moon[]} moons A list of moons
  21. * @returns {void}
  22. */
  23. function step(moons) {
  24. for (let i = 0; i < moons.length - 1; i++) {
  25. for (let j = i + 1; j < moons.length; j++) {
  26. // Calculate Moon B's gravity influence on Moon A
  27. const firstGravity = calculateGravity(moons[i], moons[j]);
  28. // Invert the signage to represent Moon A's influence on Moon B
  29. const secondGravity = firstGravity.negate();
  30. moons[i].velocity.add(firstGravity);
  31. moons[j].velocity.add(secondGravity);
  32. }
  33. }
  34. moons.forEach((moon) => { moon.position.add(moon.velocity); });
  35. }
  36. /**
  37. * Find the gravitational influence two moons have on each other
  38. *
  39. * @param {Moon} moonA The first moon to consider
  40. * @param {Moon} moonB The second moon to consider
  41. *
  42. * @returns {Vector3} The gravitational influence of Moon B on Moon A
  43. */
  44. function calculateGravity(moonA, moonB) {
  45. // The gravitational pull on Moon A caused by Moon B
  46. const gravityDifference = new Vector3(
  47. // eslint-disable-next-line no-nested-ternary
  48. moonB.position.x > moonA.position.x ? 1 : (moonB.position.x < moonA.position.x ? -1 : 0),
  49. // eslint-disable-next-line no-nested-ternary
  50. moonB.position.y > moonA.position.y ? 1 : (moonB.position.y < moonA.position.y ? -1 : 0),
  51. // eslint-disable-next-line no-nested-ternary
  52. moonB.position.z > moonA.position.z ? 1 : (moonB.position.z < moonA.position.z ? -1 : 0),
  53. );
  54. return gravityDifference;
  55. }
  56. module.exports = {
  57. parseInput,
  58. step,
  59. };