Javascript
After smashing out a functional version in 20 minutes, I converted it into a OOP approach for a more appealing solution.
Solution
const input = require('fs').readFileSync('input-day4.txt', 'utf-8');
class PrintingDepartmentMap {
/** @param {string} input */
constructor(input) {
/** @type {number[][]} */
this.map = input.split("\n").map(r => r.split('').map(v => v === '@' ? 1 : 0));
}
/**
* @param {number} x
* @param {number} y
* @returns {number} the value of that tile, or -1 if invalid
*/
getCoord(x, y) {
if (x < 0 || y < 0 || x >= this.map[0].length || y >= this.map.length) {
return -1;
}
return this.map[y][x];
}
/**
* @param {number} x
* @param {number} y
* @returns {number} the number of adjacent tiles that are >= 1
*/
countAdjacent(x, y) {
return [
// top-left
this.getCoord(x - 1, y - 1) >= 1,
// top
this.getCoord(x, y - 1) >= 1,
// top-right
this.getCoord(x + 1, y - 1) >= 1,
// right
this.getCoord(x + 1, y) >= 1,
// bottom-right
this.getCoord(x + 1, y + 1) >= 1,
// bottom
this.getCoord(x, y + 1) >= 1,
// bottom-left
this.getCoord(x - 1, y + 1) >= 1,
// left
this.getCoord(x - 1, y) >= 1
].reduce((acc, v) => !!v ? acc + 1 : acc, 0);
}
/**
* transform in place the map replacing any rolls (1) with (2) if they are accessible
* @returns {PrintingDepartmentMap}
*/
markAccessable() {
for (let y = 0; y < this.map.length; y += 1) {
for (let x = 0; x < this.map[0].length; x += 1) {
if (this.map[y][x] < 1) continue;
if (this.countAdjacent(x, y) < 4) {
this.map[y][x] = 2;
}
}
}
return this;
}
/** @returns {number} the number of removed rolls */
removeAccessable() {
let removed = 0;
for (let y = 0; y < this.map.length; y += 1) {
for (let x = 0; x < this.map[0].length; x += 1) {
if (this.map[y][x] === 2) {
removed += 1;
this.map[y][x] = 0;
}
}
}
return removed;
}
}
const map = new PrintingDepartmentMap(input);
let removed = 0;
while (true) {
const justRemoved = map.markAccessable().removeAccessable();
if (removed === 0) {
console.log(`Part 1 Answer: ${justRemoved}`);
}
if (justRemoved === 0) break;
removed += justRemoved;
}
console.log(`Part 2 Answer: ${removed}`);