Advertisement
Guest User

Advent of Code 2023 - Day 22

a guest
Dec 22nd, 2023
342
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
JavaScript 3.31 KB | Source Code | 0 0
  1. const parse = (input) => {
  2.   const lines = utils.getInputLines(input);
  3.   const blocks = [];
  4.   const max = { x: 0, y: 0, z: 0 };
  5.   let id = 1;
  6.   for (let line of lines) {
  7.     const matches = line.match(/^(\d+),(\d+),(\d+)~(\d+),(\d+),(\d+)/).map((e) => parseInt(e));
  8.     const p1 = { x: matches[1], y: matches[2], z: matches[3] };
  9.     const p2 = { x: matches[4], y: matches[5], z: matches[6] };
  10.     const block = {
  11.       p1: p1.z <= p2.z ? p1 : p2,
  12.       p2: p1.z <= p2.z ? p2 : p1,
  13.       id: id++,
  14.     };
  15.     blocks.push(block);
  16.     max.x = Math.max(max.x, block.p1.x, block.p2.x);
  17.     max.y = Math.max(max.y, block.p1.y, block.p2.y);
  18.     max.z = Math.max(max.z, block.p1.z, block.p2.z);
  19.   }
  20.   blocks.sort((b1, b2) => b1.p1.z - b2.p1.z);
  21.   return {
  22.     blocks: blocks,
  23.     max: max,
  24.   };
  25. };
  26. class Level {
  27.   constructor(level, width, depth) {
  28.     this.level = level;
  29.     this.grid = Array.from({ length: width + 1 }, () => Array.from({ length: depth + 1 }, () => 0));
  30.     this.blocks = {};
  31.   }
  32.   getBlocks() {
  33.     return Object.values(this.blocks);
  34.   }
  35.   canSupport(block, exclude = 0) {
  36.     for (let x = block.p1.x; x <= block.p2.x; x++) {
  37.       for (let y = block.p1.y; y <= block.p2.y; y++) {
  38.         if (this.grid[x][y] > 0 && this.grid[x][y] != exclude) {
  39.           return true;
  40.         }
  41.       }
  42.     }
  43.     return false;
  44.   }
  45.   add(block) {
  46.     for (let x = block.p1.x; x <= block.p2.x; x++) {
  47.       for (let y = block.p1.y; y <= block.p2.y; y++) {
  48.         this.grid[x][y] = block.id;
  49.       }
  50.     }
  51.     this.blocks[block.id] = block;
  52.   }
  53.   toString() {
  54.     return "Level: " + this.level + "\n" + this.grid.map((e) => e.join("")).join("\n");
  55.   }
  56. }
  57.  
  58. const drop = (levels, block) => {
  59.   const start = block.p1.z;
  60.   for (let z = start - 1; z > 0; z--) {
  61.     const level = levels[z];
  62.     if (level.canSupport(block)) {
  63.       break;
  64.     }
  65.     block.p1.z--;
  66.     block.p2.z--;
  67.   }
  68.   for (let z = block.p1.z; z <= block.p2.z; z++) {
  69.     const level = levels[z];
  70.     level.add(block);
  71.   }
  72.   return block.p1.z != start;
  73. };
  74. const solvePart1 = (input) => {
  75.   const data = parse(input);
  76.   const levels = Array.from({ length: data.max.z }, (_, i) => new Level(i, data.max.x, data.max.y));
  77.   for (let block of data.blocks) {
  78.     drop(levels, block);
  79.   }
  80.   let sum = 0;
  81.   for (let block of data.blocks) {
  82.     const top = levels[block.p2.z];
  83.     const above = levels[block.p2.z + 1];
  84.     if (!above) {
  85.       continue;
  86.     }
  87.     const blocks = above.getBlocks();
  88.  
  89.     let canRemove = true;
  90.     for (let b of blocks) {
  91.       if (!top.canSupport(b, block.id)) {
  92.         canRemove = false;
  93.       }
  94.     }
  95.     if (canRemove) {
  96.       sum++;
  97.     }
  98.   }
  99.   return sum;
  100. };
  101. const solvePart2 = (input) => {
  102.   const data = parse(input);
  103.   const levels = Array.from({ length: data.max.z }, (_, i) => new Level(i, data.max.x, data.max.y));
  104.   // initial drop
  105.   for (let block of data.blocks) {
  106.     drop(levels, block);
  107.   }
  108.   let counter = 0;
  109.   for (let i = 0; i < data.blocks.length; i++){
  110.     const bs = JSON.parse(JSON.stringify(data.blocks)).filter(e => e.id != i + 1)
  111.     const ls = Array.from({ length: data.max.z }, (_, i) => new Level(i, data.max.x, data.max.y));
  112.     for (let block of bs){
  113.       const dropped = drop(ls, block);
  114.       if (dropped){ counter++; }
  115.     }
  116.   }
  117.   return counter;
  118. };
  119.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement