commit 95b832f24de507987174f78e95e8e7f59658c912
parent e86f9394074a8cd4e5695c72714703c6a01981b5
Author: finwo <finwo@pm.me>
Date: Sun, 18 Dec 2022 13:43:46 +0100
2022/18 solution
Diffstat:
2 files changed, 151 insertions(+), 0 deletions(-)
diff --git a/2022/day-18/index.js b/2022/day-18/index.js
@@ -0,0 +1,138 @@
+const fs = require('fs');
+const through = require('through2');
+const line_by_line = require('../common/line-for-line');
+
+String.prototype.startsWith = function(subject) {
+ return this.substr(0, subject.length) === subject;
+};
+
+const area = [];
+let sides = 0;
+
+let minx = Infinity;
+let miny = Infinity;
+let minz = Infinity;
+let maxx = -Infinity;
+let maxy = -Infinity;
+let maxz = -Infinity;
+
+
+function instantiate(area, x, y, z) {
+ if (!area[x-1]) area[x-1] = [];
+ if (!area[x-1][y-1]) area[x-1][y-1] = [];
+ if (!area[x-1][y ]) area[x-1][y ] = [];
+ if (!area[x-1][y+1]) area[x-1][y+1] = [];
+ if (!area[x ]) area[x ] = [];
+ if (!area[x ][y-1]) area[x ][y-1] = [];
+ if (!area[x ][y ]) area[x ][y ] = [];
+ if (!area[x ][y+1]) area[x ][y+1] = [];
+ if (!area[x+1]) area[x+1] = [];
+ if (!area[x+1][y-1]) area[x+1][y-1] = [];
+ if (!area[x+1][y ]) area[x+1][y ] = [];
+ if (!area[x+1][y+1]) area[x+1][y+1] = [];
+}
+
+// fs.createReadStream('sample')
+fs.createReadStream('input')
+ .pipe(line_by_line())
+
+ // Minor parsing
+ .pipe(through.obj(function(line, enc, cb) {
+ line = line.toString();
+ const [x,y,z] = line.split(',').map(n => parseInt(n));
+
+ // Ensure the location exists
+ instantiate(area, x, y, z);
+
+ // Check all sides if covered
+ // +1 or -1, as either showing a new side or hiding another's
+ if (area[x-1][y ][z ]) { sides--; } else { sides++ };
+ if (area[x+1][y ][z ]) { sides--; } else { sides++ };
+ if (area[x ][y-1][z ]) { sides--; } else { sides++ };
+ if (area[x ][y+1][z ]) { sides--; } else { sides++ };
+ if (area[x ][y ][z-1]) { sides--; } else { sides++ };
+ if (area[x ][y ][z+1]) { sides--; } else { sides++ };
+
+ // Track area size
+ if (x < minx) minx = x;
+ if (y < miny) miny = y;
+ if (z < minz) minz = z;
+ if (x > maxx) maxx = x;
+ if (y > maxy) maxy = y;
+ if (z > maxz) maxz = z;
+
+ // Mark our spot as taken by rock
+ area[x][y][z] = 1;
+
+ console.log({ line, x, y, z, sides });
+ cb();
+ }))
+
+ .on('finish', () => {
+ console.log('loaded');
+
+ // Expand area by 1 in all directions, so we steam can travel to all edges
+ minx -= 1;
+ miny -= 1;
+ minz -= 1;
+ maxx += 1;
+ maxy += 1;
+ maxz += 1;
+
+ // Mark our starting position as steam-filled
+ instantiate(area, minx, miny, minz);
+ area[minx][miny][minz] = 2;
+
+ let edges = 0;
+ let checked = 0;
+
+ // Fill the area with steam
+ let openset = [[minx,miny,minz]];
+ while(openset.length) {
+ console.log(openset.length);
+ const test = openset.pop();
+
+ // Directions for testing
+ // No diagonals
+ const [x,y,z] = test;
+ let directions = [
+ [x-1,y ,z ],
+ [x+1,y ,z ],
+ [x ,y-1,z ],
+ [x ,y+1,z ],
+ [x ,y ,z-1],
+ [x ,y ,z+1],
+ ];
+
+ for(const direction of directions) {
+ const [x,y,z] = direction;
+
+ // out-of-bounds = skip
+ if (x<minx) continue;
+ if (y<miny) continue;
+ if (z<minz) continue;
+ if (x>maxx) continue;
+ if (y>maxy) continue;
+ if (z>maxz) continue;
+
+ // Ensure our test location and surroundings exist
+ instantiate(area, x, y, z);
+
+ // If filled by steam already, skip test location
+ if (area[x][y][z] == 2) continue;
+
+ // If filled by rock, mark the direction as an edge & don't expand there
+ if (area[x][y][z] == 1) {
+ edges++;
+ continue;
+ }
+
+ // Here = space is open
+ // Mark as steam and add to testing locations
+ area[x][y][z] = 2;
+ openset.push([x,y,z]);
+ }
+ }
+
+ console.log({ sides, edges });
+ });
diff --git a/2022/day-18/sample b/2022/day-18/sample
@@ -0,0 +1,13 @@
+2,2,2
+1,2,2
+3,2,2
+2,1,2
+2,3,2
+2,2,1
+2,2,3
+2,2,4
+2,2,6
+1,2,5
+3,2,5
+2,1,5
+2,3,5