Published
Edited
Dec 13, 2019
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
planets = function(puzzle) {
return puzzle.replace(/[<=xyz\n]/g,'').split('>').map(p => {
const pos = p.split(',').map(Number);
const pE = pos.map(Math.abs).reduce((a,v) => a+v);
return {position: pos,
velocity: [0, 0, 0],
pE: pE,
kE: 0,
tE: 0
}
}).slice(0,-1);
}
Insert cell
updatePlanets = function (planets) {
let dv, p1_d, p2_d;
let velUpdate = planets.map((p1, i1) => { // go through planets
dv = planets.reduce((acc, p2, i2) => //go through planets for pairs
acc.map((v_d, d) => { //for each dimension
p1_d = p1.position[d];
p2_d = p2.position[d];
if (p1_d < p2_d) { return v_d + 1 }
if (p1_d > p2_d) { return v_d - 1 }
return v_d // at same place or same planet
})
, [0, 0, 0]);
return p1.velocity.map((v_d, d) => v_d + dv[d])
});
let pos, vel, pE, kE;
return planets.map( (p, i) => { // update positions
vel = velUpdate[i];
pos = p.position.map( (p_d, d) => p_d + vel[d] ); // just add vel.
pE = pos.map(Math.abs).reduce((a,v) => a+v); // compute energies
kE = vel.map(Math.abs).reduce((a,v) => a+v);
return {position: pos, velocity: vel, pE: pE, kE: kE, tE: pE*kE};
})
}
Insert cell
run = function(steps, input = puzzle) {
let totalE;
let updatedPlanets = planets(input);
return Array(steps + 1).fill({planets: updatedPlanets}).reduce((result, p) => { // just iterate
updatedPlanets = updatePlanets(updatedPlanets);
totalE = updatedPlanets.reduce( (a,p) => a + p.tE, 0 );
return {planets: updatedPlanets, totalE: totalE}
})
}
Insert cell
run(0)
Insert cell
Insert cell
run(10, test1)
Insert cell
Insert cell
Insert cell
answerPerDim = function(input, iterMax = 10000) {
let hash, iter, current, universes;
let repeats = [0, 1, 2].map(d => { // key is get repeats per dimension, then find smallest combo
current = planets(input);
universes = new Set(); //sets seem faster than arrays
iter = iterMax;
while (iter--) {
//hash = current.reduce((a,p) => a+[p.pE, p.kE].join(), ""); //was useless, tE also
hash = current.reduce((a, p) => a + //just all positions and velocities
p.position[d].toString(34) +
p.velocity[d].toString(34), "");
// found_i = universes.indexOf(hash); //slower
// for (found_i = 0; found_i < universes.length; found_i++) {
// if ( hash === universes[found_i] ) { break; }
// }
if ( universes.has(hash) ) { break; }
universes.add(hash);
current = updatePlanets(current);
}
return universes.size
})
return repeats
}
Insert cell
Type JavaScript, then Shift-Enter. Ctrl-space for more options. Arrow ↑/↓ to switch modes.

Insert cell
factorize = function (n) {
let fact = function (n) { // recursive has to be inside one cell
for (let i=2; i < n/2; i++) {
if (n % i == 0) { return [i].concat( fact( n/i )); } //if divisible save and fact. rest
}
return [n]; //tried all, has no factor
}
return fact(n);
}
Insert cell
answer = function(input) {
return answerPerDim(input, 240000)
.map(factorize)
.reduce((a, v) => { // find necessary factors
let r = Array.from(a);
return a.concat(v.map(c => {
let i = r.indexOf(c);
if (i == -1) { return c } // need the factor
r[i] = 1; // remove factor
return 1;
}))}, [])
.reduce((a,v) => a * v, 1)
}
Insert cell
puzzleAnswer = answer(puzzle)
Insert cell
Math.pow(4686774924,1/3)
Insert cell

Purpose-built for displays of data

Observable is your go-to platform for exploring data and creating expressive data visualizations. Use reactive JavaScript notebooks for prototyping and a collaborative canvas for visual data exploration and dashboard creation.
Learn more