Skip to content

Instantly share code, notes, and snippets.

@bluepichu
Created December 22, 2021 05:43
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/19c0e925113b4aa4a623183a490fa79c to your computer and use it in GitHub Desktop.
Save bluepichu/19c0e925113b4aa4a623183a490fa79c to your computer and use it in GitHub Desktop.
import { List, Map, Set } from "immutable";
import { Advent, int, arr } from "advent";
const { compute, computeCheck } = await Advent({ day: 22 });
interface Cube {
x1: number;
y1: number;
z1: number;
x2: number;
y2: number;
z2: number;
}
compute(async (input) => {
// const data = input.tokens(/,/).map(int);
const data = input.lines();
let cubes: Cube[] = [];
for (let line of data) {
let [op, pos] = line.split(" ");
let [xr, yr, zr] = pos.split(",");
let [x1, x2] = xr.split("=")[1].split("..").map(int);
let [y1, y2] = yr.split("=")[1].split("..").map(int);
let [z1, z2] = zr.split("=")[1].split("..").map(int);
let cur = { x1, y1, z1, x2: x2+1, y2: y2+1, z2: z2+1 };
cubes = cubes.flatMap((c) => sub(c, cur));
if (op === "on") {
cubes.push(cur);
}
}
return cubes.map((c) => vol(c)).reduce((a, b) => a + b, 0n).toString();
}, 2);
function vol(c: Cube) {
return BigInt(c.x2 - c.x1) * BigInt(c.y2 - c.y1) * BigInt(c.z2 - c.z1);
}
function sub(a: Cube, b: Cube): Cube[] {
if (contains(b, a)) {
return [];
}
if (!intersects(a, b)) {
return [a];
}
let xSplits = [b.x1, b.x2].filter((x) => a.x1 < x && x < a.x2);
let ySplits = [b.y1, b.y2].filter((y) => a.y1 < y && y < a.y2);
let zSplits = [b.z1, b.z2].filter((z) => a.z1 < z && z < a.z2);
let xv = [a.x1, ...xSplits, a.x2];
let yv = [a.y1, ...ySplits, a.y2];
let zv = [a.z1, ...zSplits, a.z2];
let res: Cube[] = [];
for (let i = 0; i < xv.length - 1; i++) {
for (let j = 0; j < yv.length - 1; j++) {
for (let k = 0; k < zv.length - 1; k++) {
res.push({
x1: xv[i],
y1: yv[j],
z1: zv[k],
x2: xv[i+1],
y2: yv[j+1],
z2: zv[k+1],
});
}
}
}
return res.filter((c) => !contains(b, c));
}
function contains(a: Cube, b: Cube): boolean {
return a.x1 <= b.x1 && a.x2 >= b.x2 && a.y1 <= b.y1 && a.y2 >= b.y2 && a.z1 <= b.z1 && a.z2 >= b.z2;
}
function intersects(a: Cube, b: Cube): boolean {
return a.x1 <= b.x2 && a.x2 >= b.x1 && a.y1 <= b.y2 && a.y2 >= b.y1 && a.z1 <= b.z2 && a.z2 >= b.z1;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment