Coding Journal

Jordan Vidrine

Daily Coding Journal

A Self-taught coder from the Cajun Prairie in rural Louisiana, currently working as a designer for Discourse.

I am always trying to better myself, and do so through learning new skills, trying out new routines, traveling, and pouring energy into hobbies. Since 2014, I have been recording, editing, and producing my own music under the name Skies Speak.

December 13th - Advent of Code Day 8

I found out about Advent of Code a couple days late, but still decided to participate. I’ve been able to complete at LEAST part one of each puzzle that I have attempted so that has been pretty encouraging. It’s crazy to think that at this time last year, I did not know javascript well enough to complete these puzzles. Today I was able to finish solving part 2 of Day 8. You can view my Advent Repo here, or continue to read through this post. My code is below.

Part One

I wrote multiple functions to break down the complexity of the problem at hand. The problem involved parsing through an array that was X in width and X in height. Given these dimensions, we were given an input, and instructed to create a large array of arrays split up from the input we were given. The original prompt can be found here.

My first step was to get the input, and create it into an array of parse-able layers.

const fs = require('fs')

const getInput = () => {
  let input = fs.readFileSync('./input.txt')
  return input.toString().split('').map(number => Number(number))
}

function createLayers(width, height) {
    let input = getInput()

    let image = [];

    while (input.length > 0) {

        let layer = [];

        for (let i = 0; i < height; i++) {
            layer.push(input.splice(0,width))
        }

        image.push(layer)

    }

    return image

}

My next step was to find the layer with the least amount of 0s, then multiply the amount of 1s by the amount of 2s. I did this with the following code.

function getTargetLayer() {
    let image = createLayers(25,6)

    let zeroDigits = {};

    // count zeroes

    for (let i = 0; i < image.length - 1 ; i++) {

        for (let j = 0; j < image[i].length; j++) {

            let zeroes = image[i][j].filter(number => number == 0)

            if (`${i}` in zeroDigits) {
                zeroDigits[`${i}`] += zeroes.length;
            } else {
                zeroDigits[`${i}`] = zeroes.length;
            }
        }
    }

    // find layer with least amount of zeroes

    let layerWithLeastZeroes = undefined;
    let numOfZeroes = Infinity

    for (key in zeroDigits) {
        if (zeroDigits[key] < numOfZeroes) {
            numOfZeroes = zeroDigits[key]
            layerWithLeastZeroes = key
        }
    }

    let targetLayer = image[Number(layerWithLeastZeroes)]

    return targetLayer

}

function multDigits(layer) {
    debugger;
    let ones = 0;
    let twos = 0;

    for (let i = 0; i < layer.length; i++) {
        for (let j = 0; j < layer[i].length; j++) {
            if (layer[i][j] == 1) {
                ones++
            }

            if (layer[i][j] == 2) {
                twos++
            }
        }
    }

    return ones * twos
}

console.log(multDigits(getTargetLayer()))

Part Two

Now this was an interesting part! The next step involved ‘rendering’ all of the layers together into one layer. At each x,y coordinate in the layers, we had to figure out whethere this ‘pixel’ would be black, white, or transparent. We had to start with the pixel coordinate furthest back, and decide the color based on the rules provided. My first step was to create a ‘Blank’ image to be able to re-assign the values computed out of my parsed layers.

function blankImage(layers) {
    let width = layers[0][0].length
    let height = layers[0].length

    let blankImage = [];

    for (let i = 0; i < height; i++) {
        let layer = [];
        for (let j = 0; j < width; j++) {
            layer.push('0')
        }
        blankImage.push(layer)
    }

    return blankImage
}

My next step, was for me to create an image map, where I stored EVERY possible value at each coordinate using the stacked layers of arrays. This function returned an object, with they keys being equal to XY coordinates, and the values of each key being an array of possible ‘colors’ to parse through.

function imageMap(layers) {

    let imageMap = {};

    for (let y = 0; y < layers[0].length; y++) {

        for (let x = 0; x < layers[0][0].length; x++) {

            let xy = []

            for (let inner = 0; inner < layers.length ; inner++) {
                xy.push(layers[inner][y][x])
            }

            imageMap[`${x},${y}`] = xy

        }

    }

    return imageMap
}

My next step was to build the image based on the object provided above. I did this by re-assigning the values in the ‘blank’ image based on a reduced value from each coordinates array.

function buildImage(layers) {
    let map = imageMap(layers)
    let blank = blankImage(layers)

    for (let coords in map) {

        let x = coords.split(',')[0]
        let y = coords.split(',')[1]

        let reducedValue = reduceLayers(map[coords].reverse())

        blank[y][x] = reducedValue;
    }

    return blank;
}

function reduceLayers(layer) {
    let value = layer.reduce((acc,current) => {
        if (current === 2) {
            return acc;
        } else if (current === 1) {
            acc = '#';
            return acc;
        } else {
            acc = ' ';
            return acc;
        }
    }, 2)

    return value;
}

console.log(buildImage(createLayers(25,6)))

["#", "#", "#", " ", " ", " ", "#", "#", " ", " ", "#", " ", " ", " ", "#", "#", "#", "#", "#", " ", "#", "#", "#", "#", " "]
["#", " ", " ", "#", " ", "#", " ", " ", "#", " ", "#", " ", " ", " ", "#", "#", " ", " ", " ", " ", "#", " ", " ", " ", " "]
["#", "#", "#", " ", " ", "#", " ", " ", " ", " ", " ", "#", " ", "#", " ", "#", "#", "#", " ", " ", "#", "#", "#", " ", " "]
["#", " ", " ", "#", " ", "#", " ", " ", " ", " ", " ", " ", "#", " ", " ", "#", " ", " ", " ", " ", "#", " ", " ", " ", " "]
["#", " ", " ", "#", " ", "#", " ", " ", "#", " ", " ", " ", "#", " ", " ", "#", " ", " ", " ", " ", "#", " ", " ", " ", " "]
["#", "#", "#", " ", " ", " ", "#", "#", " ", " ", " ", " ", "#", " ", " ", "#", "#", "#", "#", " ", "#", " ", " ", " ", " "]

I used a console log to ‘render’ the image in the chrome debugger. Doing this allowed me to see the code that I was trying to be ‘sent’ from the ‘elves’. The message being sent contained the password of BCYEF. This was a super fun problem to solve!

Back to blog...