advent-of-code

Entries to advent of code, multiple years
git clone git://git.finwo.net/misc/advent-of-code
Log | Files | Refs

commit 95b832f24de507987174f78e95e8e7f59658c912
parent e86f9394074a8cd4e5695c72714703c6a01981b5
Author: finwo <finwo@pm.me>
Date:   Sun, 18 Dec 2022 13:43:46 +0100

2022/18 solution

Diffstat:
A2022/day-18/index.js | 138+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
A2022/day-18/sample | 13+++++++++++++
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