Skip to content

Instantly share code, notes, and snippets.

@bluepichu
Created December 19, 2021 06:05
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save bluepichu/37712952379625f78a0a59b868e25671 to your computer and use it in GitHub Desktop.
Save bluepichu/37712952379625f78a0a59b868e25671 to your computer and use it in GitHub Desktop.
import { List, Map, Set } from "immutable";
import { Advent, int } from "advent";
const { compute, computeCheck } = await Advent({ day: 19 });
type Scanner = [number, number, number][];
let deltas: [number, number, number][] = [[0, 0, 0]];
let tfs = Set<List<number>>();
compute(async (input) => {
// const data = input.tokens(/,/).map(int);
// const data = input.ints();
const data: Scanner[] = input.lineTokens(/\n?\n?---.*---\n/g, /\n/g).slice(1).map((line) => line.map((p) => p.split(",").map(int) as [number, number, number]));
const out = mergeAll(List(data));
console.log(JSON.stringify(out));
console.log(JSON.stringify(deltas));
console.log(JSON.stringify(tfs.toJSON()));
// return out.length;
return maxManhattan(deltas);
}, 2);
function mergeAll(scanners: List<Scanner>) {
let current: Scanner = scanners.first()!;
scanners = scanners.rest();
while (scanners.size > 0) {
console.log("remaining scanners:", scanners.size);
console.log(JSON.stringify(tfs.toJSON()));
let updated = false;
for (let scanner of scanners) {
let out = matchCheck(current, scanner);
if (out !== undefined) {
current = out;
scanners = scanners.delete(scanners.indexOf(scanner));
updated = true;
break;
}
}
if (!updated) {
throw new Error("failed");
}
}
return current;
}
function matchCheck(a: Scanner, b: Scanner): Scanner | undefined {
let curB = b;
let tf: [number, number, number] = [1, 2, 3];
for (let xr = 0; xr < 4; xr++) {
// xy rotation
curB = curB.map((p) => [-p[1], p[0], p[2]]);
tf = [-tf[1], tf[0], tf[2]]
for (let yr = 0; yr < 4; yr++) {
// yz rotation
curB = curB.map((p) => [p[0], -p[2], p[1]]);
tf = [tf[0], -tf[2], tf[1]]
for (let zr = 0; zr < 4; zr++) {
// xz rotation
curB = curB.map((p) => [-p[2], p[1], p[0]]);
tf = [-tf[2], tf[1], tf[0]]
tfs = tfs.add(List(tf));
const delta = matchCheckNoRotate(a, curB);
if (delta !== undefined) {
let merged = Set(a.map(List)).union(Set(curB.map((p) => [p[0] + delta[0], p[1] + delta[1], p[2] + delta[2]]).map(List)));
deltas.push(delta);
return merged.toArray().map((p) => p.toArray() as [number, number, number]);
}
}
}
}
return undefined;
}
function matchCheckNoRotate(a: Scanner, b: Scanner): [number, number, number] | undefined {
let aSet = Set(a.map(List));
for (let i = 0; i < a.length; i++) {
for (let j = 0; j < b.length; j++) {
let common = 0;
let delta = [a[i][0] - b[j][0], a[i][1] - b[j][1], a[i][2] - b[j][2]] as [number, number, number];
for (let k = 0; k < b.length; k++) {
if (aSet.has(List(b[k].map((p, i) => p + delta[i])))) {
common++;
}
}
if (common >= 12) {
return delta;
}
}
}
return undefined;
}
function maxManhattan(pos: [number, number, number][]) {
let max = 0;
for (let p of pos) {
for (let q of pos) {
max = Math.max(max, Math.abs(p[0] - q[0]) + Math.abs(p[1] - q[1]) + Math.abs(p[2] - q[2]));
}
}
return max;
}
// computeCheck(async function* (input) {
// yield 0;
// });
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment