Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- const parse = (input) => {
- const lines = utils.getInputLines(input);
- const blocks = [];
- const max = { x: 0, y: 0, z: 0 };
- let id = 1;
- for (let line of lines) {
- const matches = line.match(/^(\d+),(\d+),(\d+)~(\d+),(\d+),(\d+)/).map((e) => parseInt(e));
- const p1 = { x: matches[1], y: matches[2], z: matches[3] };
- const p2 = { x: matches[4], y: matches[5], z: matches[6] };
- const block = {
- p1: p1.z <= p2.z ? p1 : p2,
- p2: p1.z <= p2.z ? p2 : p1,
- id: id++,
- };
- blocks.push(block);
- max.x = Math.max(max.x, block.p1.x, block.p2.x);
- max.y = Math.max(max.y, block.p1.y, block.p2.y);
- max.z = Math.max(max.z, block.p1.z, block.p2.z);
- }
- blocks.sort((b1, b2) => b1.p1.z - b2.p1.z);
- return {
- blocks: blocks,
- max: max,
- };
- };
- class Level {
- constructor(level, width, depth) {
- this.level = level;
- this.grid = Array.from({ length: width + 1 }, () => Array.from({ length: depth + 1 }, () => 0));
- this.blocks = {};
- }
- getBlocks() {
- return Object.values(this.blocks);
- }
- canSupport(block, exclude = 0) {
- for (let x = block.p1.x; x <= block.p2.x; x++) {
- for (let y = block.p1.y; y <= block.p2.y; y++) {
- if (this.grid[x][y] > 0 && this.grid[x][y] != exclude) {
- return true;
- }
- }
- }
- return false;
- }
- add(block) {
- for (let x = block.p1.x; x <= block.p2.x; x++) {
- for (let y = block.p1.y; y <= block.p2.y; y++) {
- this.grid[x][y] = block.id;
- }
- }
- this.blocks[block.id] = block;
- }
- toString() {
- return "Level: " + this.level + "\n" + this.grid.map((e) => e.join("")).join("\n");
- }
- }
- const drop = (levels, block) => {
- const start = block.p1.z;
- for (let z = start - 1; z > 0; z--) {
- const level = levels[z];
- if (level.canSupport(block)) {
- break;
- }
- block.p1.z--;
- block.p2.z--;
- }
- for (let z = block.p1.z; z <= block.p2.z; z++) {
- const level = levels[z];
- level.add(block);
- }
- return block.p1.z != start;
- };
- const solvePart1 = (input) => {
- const data = parse(input);
- const levels = Array.from({ length: data.max.z }, (_, i) => new Level(i, data.max.x, data.max.y));
- for (let block of data.blocks) {
- drop(levels, block);
- }
- let sum = 0;
- for (let block of data.blocks) {
- const top = levels[block.p2.z];
- const above = levels[block.p2.z + 1];
- if (!above) {
- continue;
- }
- const blocks = above.getBlocks();
- let canRemove = true;
- for (let b of blocks) {
- if (!top.canSupport(b, block.id)) {
- canRemove = false;
- }
- }
- if (canRemove) {
- sum++;
- }
- }
- return sum;
- };
- const solvePart2 = (input) => {
- const data = parse(input);
- const levels = Array.from({ length: data.max.z }, (_, i) => new Level(i, data.max.x, data.max.y));
- // initial drop
- for (let block of data.blocks) {
- drop(levels, block);
- }
- let counter = 0;
- for (let i = 0; i < data.blocks.length; i++){
- const bs = JSON.parse(JSON.stringify(data.blocks)).filter(e => e.id != i + 1)
- const ls = Array.from({ length: data.max.z }, (_, i) => new Level(i, data.max.x, data.max.y));
- for (let block of bs){
- const dropped = drop(ls, block);
- if (dropped){ counter++; }
- }
- }
- return counter;
- };
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement