Day 4: Printing Department

Megathread guidelines

  • Keep top level comments as only solutions, if you want to say something other than a solution put it in a new post. (replies to comments can be whatever)
  • You can send code in code blocks by using three backticks, the code, and then three backticks or use something such as https://topaz.github.io/paste/ if you prefer sending it through a URL

FAQ

you are viewing a single comment's thread
view the rest of the comments
[โ€“] 2 points 10 months ago

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}`);

  • source