Advent Of Code 2023 - Day Two Solution

Murtuzaali Surti
Murtuzaali Surti

• 3 min read

Just wrapped up solving advent of code's day two challenge. This was a tricky one in terms of the language used to describe the puzzle. I had to take some online help to understand what was the second part of the puzzle trying to say.

You can visit the advent of code day two challenge to check what was the puzzle. In short, in the first part of the puzzle, we had to figure out the sum of the number of valid games from a given input. And, in the second part, we had to find the sum of the powers of fewest number of cubes (of each color) present to make the game possible.

Part One

To re-structure the data we are getting in the input in a singe line, I created this function to map the game number to the number of cubes revealed of each type in each play.

{
  number: '1',
  cubes: {
    green: [ '6', '5', '5', '1' ],     
    red: [ '3', '3', '1', '3' ],       
    blue: [ '7', '1', '8', '5' ]       
  }
}

The readFileByLine function is the same as used in day-1's solution.

const getCubeCountMappedToTheGameAndType = async () => {
    const games = await readFileByLine('day-2/input.txt')
    const cubeCountMappedToTheGameAndType = Array.from({ length: games.length })

    for (const [index, game] of games.entries()) {
        const splitGameNumberAndPlays = game.split(':').map(i => i.trim())

        const cubesFromAPlay = {
            green: [],
            red: [],
            blue: []
        }

        const plays = splitGameNumberAndPlays[1].split(';').map(i => i.trim())

        for (const play of plays) {
            play.split(',').map(i => i.trim()).forEach((cubeType) => {
                const cubeColor = cubeType.split(" ")[1];
                const cubeCount = cubeType.split(" ")[0];
                cubesFromAPlay[`${cubeColor}`].push(cubeCount)
            })
        }

        cubeCountMappedToTheGameAndType[index] = {
            number: splitGameNumberAndPlays[0].split(" ")[1],
            cubes: cubesFromAPlay
        }
    }
    return cubeCountMappedToTheGameAndType
}

The maximum number of cubes that should be present (for each cube type) for a game play to make this a valid game are:

const totalCubesAtOnce = {
    red: 12,
    green: 13,
    blue: 14
};

If we get any count greater than the count above for each cube type, the game is marked as invalid. For example, game Game 2: 1 blue, 2 green; 3 green, 4 blue, 1 red; 1 green, 1 blue is a valid game because for each play (separated by semi-colon), the cube count for each type is under the maximum count.

const partOne = async () => {
    const validGames = []
    const cubeCountMappedToTheGameAndType = await getCubeCountMappedToTheGameAndType()

    for (const game of cubeCountMappedToTheGameAndType) {
        let isValid = true
        loop2: for (const [type, value] of Object.entries(game.cubes)) {
            for (const count of value) {
                if (parseInt(count) > totalCubesAtOnce[`${type}`]) {
                    isValid = false
                    break loop2;
                }
            }
        };

        isValid && validGames.push(game);
    }
    return validGames.reduce((acc, curr) => acc + parseInt(curr.number), 0);
}

And then finally, I am summing up all of the valid game numbers.

From this challenge, I came across an interesting revelation about breaking nested loops in javascript. I am still processing this.

Part Two

Here, we had to figure out the sum of the power (cube count of each color multiplied together) of the fewest set of cubes required to make the game possible. "Fewest" here means the biggest number of cubes of each color present in a game. Once we get the number of cubes required for each color, we can multiply them together and that will give us the power for each game. Adding them up gives us the result.

const partTwo = async () => {
    const cubeCountMappedToTheGameAndType = await getCubeCountMappedToTheGameAndType()
    const powersOfCubes = Array.from({ length: cubeCountMappedToTheGameAndType.length })

    for (const [i, game] of cubeCountMappedToTheGameAndType.entries()) {
        const powersOfCubeInAGame = [];
        for (const [_, value] of Object.entries(game.cubes)) {
            powersOfCubeInAGame.push(value.sort((a, b) => parseInt(a) - parseInt(b))[value.length - 1])
        };
        powersOfCubes[i] = powersOfCubeInAGame.reduce((acc, curr) => acc * curr, 1)
    }

    return powersOfCubes.reduce((acc, curr) => acc + curr, 0)
}

The execution time turns out to be:

exec: 19.009 ms

Repository


Completed Advent Of Code: Day One

Previous

Web Components & Custom Elements

Next