Advent of Code 2021 - Day 13

Advent of Code 2021 - Day 13
Day 13 - Advent of Code 2021

The problem

Given a list of coordinates and folding instructions, how many points are visible after the first fold.

Since i was not fully awake this morning, i spent 20 minutes wondering why my result was not correct because i tried to get visible points in the last fold.

Sleepy

Intial thoughs

At first i tried to create a matrix with given coordinates, then try to do the folding and let them iterate through the matrix to get the visible points, easy peasy lemon squeezy, right ?!

So i spent the next 10 minutes to properly handle the matrix, first detect the max size of the paper, then fill all the empty items with 0. Finally comes the folding logic. However, this seems too tedious for me with all the array manipulation, i would have finished this problem in another 1 hour ?.

let maxX = 0;
let maxY = 0;
const paper = [[]];
coordinates.forEach(coord => {
    const [x,y] = coord;
    if (maxX < x) maxX = x;
    if (maxY < y) maxY = y;
})

for (let i=0; i< maxX;i++)
{
 	if (!paper[i]) {
    	paper[i] = [];
    }   
    
    for (let j=0;j < maxY; j++)
    {
        if (!paper[i][j]) {
            paper[i][j] = 0;
        }    	 
    }
}
Initialize paper from the input

Another approach

Do i really have to use matrix to solve this problem ? the matrix approach makes every calculation seems too long because we have to iterate through rows and columns. And i only need to know if a given coordinate has a dot or not, so maybe a map is enough ?

Eureka !
let maxX = 0;
let maxY = 0;

const getCoordLabel = (x, y) => {
  return `${x}-${y}`;
};

coords.forEach((coord) => {
    if (maxX < coord[0]) maxX = coord[0];
    if (maxY < coord[1]) maxY = coord[1];

    currentCoords[getCoordLabel(coord[0], coord[1])] = 1;
});
Map ftw ?

So what next is how are we gonna handle the fold logic ?

Folding

For the folding part, i figured out a pattern, so everything with x < new x (the new x is the folding line) stays the same. Beyond the folding point it would "reflect". The reflected x can be calculated using the formula maxX - ( x - maxX) which deductes to 2 * maxX - x.  Same thing applies to the vertical fold.

With these results, we can determinate the new coordinate of given point after folding. The rest now is update our Map with the correct values ✨

const fold = (input, foldCoords, maxX, maxY) => {
  const newInput = {};

  const newX = foldCoords[0] === -1 ? maxX : Number.parseInt(foldCoords[0]);
  const newY = foldCoords[1] === -1 ? maxY : Number.parseInt(foldCoords[1]);

  for (const coordLabel of Object.keys(input)) {
    const [x, y] = coordLabel.split("-");
    const [foldedX, foldedY] = [
      x > newX ? Math.abs(2 * newX - x) : x,
      y > newY ? Math.abs(2 * newY - y) : y,
    ];
    newInput[getCoordLabel(foldedX, foldedY)] = 1;
  }

  return {
    coords: newInput,
    x: newX,
    y: newY,
  };
};
Fold all the things

In my code, a vertical fold would have a coordinate [x, -1] and a horizontal fold is [-1, y]

As a requirement of part 2, we need to know after folding X times the paper, what characters we can see in the final results. Now we are going to need some logics to print out all the coordinates in our map.

const printCoords = (maxX, maxY, currentCoords) => {
  for (let j = 0; j < maxY; j++) {
    let row = "";
    for (let i = 0; i < maxX; i++) {
      if (currentCoords[getCoordLabel(i, j)]) {
        row += "#";
      } else {
        row += ".";
      }
    }
    console.log(row);
  }
};

Final result

With all the parts combines together, now we can see the result. Those Elves cannot stop me now !

ZKAUCFUC 😶

That's it for today, thank you for reading 😄. I hope you had fun doing this puzzle like i did today

Duy NGUYEN

Duy NGUYEN

Paris