Skip to content

Commit e62a1bb

Browse files
committed
feat: 2019 Day 12
1 parent 499bcd1 commit e62a1bb

5 files changed

Lines changed: 116 additions & 0 deletions

File tree

2019/day/12/part/1/solve.test.ts

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
import solve from "./solve.ts";
2+
3+
import { assertEquals } from "@std/assert";
4+
5+
Deno.test("first example", () => {
6+
const input = `\
7+
<x=-1, y=0, z=2>
8+
<x=2, y=-10, z=-7>
9+
<x=4, y=-8, z=8>
10+
<x=3, y=5, z=-1>`;
11+
12+
assertEquals(solve(input, { steps: 10 }), 179);
13+
});
14+
15+
Deno.test("second example", () => {
16+
const input = `\
17+
<x=-8, y=-10, z=0>
18+
<x=5, y=5, z=10>
19+
<x=2, y=-7, z=3>
20+
<x=9, y=-8, z=-3>`;
21+
22+
assertEquals(solve(input, { steps: 100 }), 1940);
23+
});

2019/day/12/part/1/solve.ts

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
import { parsePositions } from "../../positions.ts";
2+
3+
export default function solve(input: string, { steps = 1_000 } = {}): number {
4+
const moons = parsePositions(input).map((position) => {
5+
const velocity = [0, 0, 0];
6+
return { position, velocity };
7+
});
8+
for (let step = 0; step < steps; step++) {
9+
for (let i = 0; i < moons.length; i++) {
10+
for (let j = i + 1; j < moons.length; j++) {
11+
for (let k = 0; k < 3; k++) {
12+
const change = Math.sign(moons[j].position[k] - moons[i].position[k]);
13+
moons[i].velocity[k] += change;
14+
moons[j].velocity[k] -= change;
15+
}
16+
}
17+
}
18+
for (let i = 0; i < moons.length; i++) {
19+
for (let k = 0; k < 3; k++) {
20+
moons[i].position[k] += moons[i].velocity[k];
21+
}
22+
}
23+
}
24+
return moons.reduce((total, { position, velocity }) => {
25+
const potential = position.reduce((sum, p) => sum + Math.abs(p), 0);
26+
const kinetic = velocity.reduce((sum, v) => sum + Math.abs(v), 0);
27+
return total + potential * kinetic;
28+
}, 0);
29+
}

2019/day/12/part/2/solve.test.ts

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
import solve from "./solve.ts";
2+
3+
import { assertEquals } from "@std/assert";
4+
5+
Deno.test("first example", () => {
6+
const input = `\
7+
<x=-1, y=0, z=2>
8+
<x=2, y=-10, z=-7>
9+
<x=4, y=-8, z=8>
10+
<x=3, y=5, z=-1>`;
11+
12+
assertEquals(solve(input), 2772);
13+
});
14+
15+
Deno.test("second example", () => {
16+
const input = `\
17+
<x=-8, y=-10, z=0>
18+
<x=5, y=5, z=10>
19+
<x=2, y=-7, z=3>
20+
<x=9, y=-8, z=-3>`;
21+
22+
assertEquals(solve(input), 4686774924);
23+
});

2019/day/12/part/2/solve.ts

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
import lcm from "@lib/lcm.ts";
2+
import { parsePositions } from "../../positions.ts";
3+
4+
export default function solve(input: string) {
5+
const moons = parsePositions(input).map((initialPosition) => {
6+
const initialVelocity = [0, 0, 0];
7+
const position = [...initialPosition], velocity = [...initialVelocity];
8+
return ({ initialPosition, initialVelocity, position, velocity });
9+
});
10+
const repeats = [0, 0, 0];
11+
for (let step = 0; repeats.some((r) => !r); step++) {
12+
for (let i = 0; i < moons.length; i++) {
13+
for (let j = i + 1; j < moons.length; j++) {
14+
for (let k = 0; k < 3; k++) {
15+
const change = Math.sign(moons[j].position[k] - moons[i].position[k]);
16+
moons[i].velocity[k] += change;
17+
moons[j].velocity[k] -= change;
18+
}
19+
}
20+
}
21+
for (let i = 0; i < moons.length; i++) {
22+
for (let k = 0; k < 3; k++) {
23+
moons[i].position[k] += moons[i].velocity[k];
24+
}
25+
}
26+
for (let k = 0; k < repeats.length; k++) {
27+
if (repeats[k]) continue;
28+
const aligns = moons.every((moon) =>
29+
moon.position[k] === moon.initialPosition[k] &&
30+
moon.velocity[k] === moon.initialVelocity[k]
31+
);
32+
if (aligns) repeats[k] = step + 1;
33+
}
34+
}
35+
return repeats.reduce(lcm);
36+
}

2019/day/12/positions.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
export function parsePositions(input: string) {
2+
return input.matchAll(/<x=(-?\d+), y=(-?\d+), z=(-?\d+)>/g)
3+
.map(([, ...values]) => values.map(Number))
4+
.toArray();
5+
}

0 commit comments

Comments
 (0)