DEV Community

Cover image for The N-Body Problem
Robert Mion
Robert Mion

Posted on

The N-Body Problem

Advent of Code 2019 Day 12

Try the simulator of Part 1 with your puzzle input!

Animation of moons orbiting Jupiter

Task: Solve for X where...

Part 1

X = the total energy in the system after simulating 1000 steps of the four moons' motion given in my scan
Enter fullscreen mode Exit fullscreen mode

Part 2

X = the step where all four moons repeat their initial state for the first time
Enter fullscreen mode Exit fullscreen mode

Example input

<x=-1, y=0, z=2>
<x=2, y=-10, z=-7>
<x=4, y=-8, z=8>
<x=3, y=5, z=-1>
Enter fullscreen mode Exit fullscreen mode

It represents:

  • The x,y,z positions of four moons of Jupiter

Part 1

  1. The easy part (I hope?): extracting the positions
  2. Understanding how the velocity is calculated and positions are updated
  3. Another easy part: calculating the total energy of the system
  4. A written outline of my working algorithm

The easy part (I hope?): extracting the positions

Without a regular expression:

<x=2, y=-10, z=-7>

Trim off both ends
'x=2, y=-10, z=-7'

Split at ', '
['x=2','y=-10','z=-7']

Trim off the first two characters in each
['2','-10','-7']

Coerce to numbers
[2,-10,-7]
Enter fullscreen mode Exit fullscreen mode

With a regular expression:

/\w=(-?\d+),?\s?/g
Enter fullscreen mode Exit fullscreen mode

Matches <x=2, y=-10, z=-7>:

  • \w= matches x=,y=,z=
  • (-?\d+) matches 2,-10,-7
  • ,?\s? matches ,,,

For each moon's position, I then get the same list of three matches associated with the x,y,z positions.

Understanding how the velocity is calculated and positions are updated

Facts:

  • Each moon has a 3-dimensional position (x, y, and z) - that's given in my input
  • Each moon has a 3-dimensional velocity (x, y, and z) - all starting at 0

Motion is simulated in time steps.

During each one:

  1. Update the velocity of every moon by applying gravity
  2. Update the position of every moon by applying velocity

Update the velocity of every moon by applying gravity

To apply gravity, consider every pair of moons.

There are four moons, so:

1,2
1,3
1,4
2,3
2,4
3,4
Enter fullscreen mode Exit fullscreen mode
For i from 1 to (1 less than the number of moons):
  For j from i + 1 to (the number of moons):
    Compare moon i's x,y,z to j's x,y,z

Walkthrough:
i=1, j=2
i=1, j=3
i=1, j=4
i=2, j=3
i=2, j=4
i=3, j=4
Enter fullscreen mode Exit fullscreen mode

On each axis (x, y, and z), the velocity of each moon changes by exactly +1 or -1 to pull the moons together

Given two numbers - the velocities of a pair of moon's shared axis:
  If both are equal
    Do nothing
  Else, each differ
    Decrement the greater number by 1
    Increment the lesser number by 1

Walkthrough:
 5 <>  3
-1    +1

 2 <>  2
 -     -

 1 <>  4
+1    -1
Enter fullscreen mode Exit fullscreen mode

Update the position of every moon by applying velocity

Simply add the velocity of each moon to its own position

Example given:

Where positions are:
x= 1, y=2, z=3

And velocities are:
x=-2, y=0, z=3


New positions are:
   1    2    3
  -2   +0   +3
-----------------
x=-1, y=2, z=6

Velocities remain unchanged:
x=-2, y=0, z=3
Enter fullscreen mode Exit fullscreen mode

Another easy part: calculating the total energy of the system

For each moon:
Calculate the product of two sums:
  1. Sum of the absolute values of the x,y,z positions
  2. Sum of the absolute values of the x,y,z velocities
Return the sum of all products
Enter fullscreen mode Exit fullscreen mode

A written outline of my working algorithm

Split the input at each newline character to create an array of strings

Modify each string according to the following operations:
  Use the regular expression on each string to create a 3-element array of strings
  Coerce each string to a number
  Based on the order of the match (0,1,2), set each as value of the respective x,y,z keys inside an object that stores positions and velocities
  Return the object with stored x,y,z key-value pairs for position and velocity

For each step from 0 to i - as defined by the input parameter
  Compare each pair of moons
    Update each moon's velocity x,y,z based on whether the position x,y,z is <,>,== the other moon's position
  Update each moon's position x,y,z by adding the current velocity x,y,z

Calculate the total energy by following these operations:
Accumulate a sum - starting at 0
  For each moon
    Calculate the product of two sums:
      1. Sum of the absolute values of the x,y,z positions
      2. Sum of the absolute values of the x,y,z velocities
  Add the product to the accumulating sum

Return the sum
Enter fullscreen mode Exit fullscreen mode

The instructions in this puzzle offer a great visual for most of what is described above.

It seems redundant to create an animation.

Part 2

  1. Another challenge of algorithm performance and optimization, I presume?
  2. LCM & GCD
  3. I tried, but failed

Another challenge of algorithm performance and optimization, I presume?

  • That's what I thought
  • But soon after 'giving up' and skimming the Solution Megathread for today, it seems I was wrong

LCM & GCD

  • Lowest Common Multiple
  • Greatest Common Denominator
  • You need the latter to calculate the former, as I discovered
  • And the former is how several solvers generated the correct answer in record time

I tried, but failed

  • I wrote an algorithm that identifies the step when each positional coordinate for each moon cycles back upon itself
  • I re-created both utility functions for LCM & GCD after finding articles online that illustrate the code
  • I wrote a few reducers that calculate the LCMs among different values (e.g. each moon's similar axes, each axis among one moon)
  • The LCMs were always exponentially larger than the correct answers provided in the instructions

I feel like I'm really close.

But I sense that any further work would just make me frustrated in an unfruitful way.

Celebrating my accomplishments

Bummer:

  • I didn't solve Part 2
  • No GIFs this time since the instructions did a great job illustrating how my algorithms work

Time to move on!

Top comments (0)