re: AoC Day 3: No Matter How You Slice It VIEW POST

FULL DISCUSSION
 

Node.js

Reused my work for part 1 in part 2.

I make the 1000 x 1000 array and fill it every slot with a *.
First time a claim is added, it gets a #
If a claim overlaps with another, those cells get marked with an X.

Part 1: Filter matrix for all X values.

Part 2: Check every coordinate for each claim. If every coordinate is a #, then that claim is the answer.

const generateFabricMatrix = () => {
  const fabric = [];

  for (const i of Array(1000).keys()) {
    fabric_columns = [];
    for (const j of Array(1000).keys()) {
      fabric_columns.push("*");
    }
    fabric.push(fabric_columns);
  }
  return fabric;
};

const claimData = input => {
  claimChars = [...input];

  const at = claimChars.indexOf("@");
  const colon = claimChars.indexOf(":");

  const id = Number(input.substr(1, at - 2));
  const xPosition = Number(input.substr(at + 1, colon - at - 1).split(",")[0]);
  const yPosition = Number(input.substr(at + 1, colon - at - 1).split(",")[1]);
  const xLength = Number(input.substr(colon + 1).split("x")[0]);
  const yLength = Number(input.substr(colon + 1).split("x")[1]);

  return {id, xPosition, yPosition, xLength, yLength};
};

const addToFabric = (claimData, fabric) => {
  for (const i of Array(claimData.xLength).keys()) {
    for (const j of Array(claimData.yLength).keys()) {
      if (fabric[claimData.xPosition + i][claimData.yPosition + j] === "*") {
        fabric[claimData.xPosition + i][claimData.yPosition + j] = "#";
      } else if (
        fabric[claimData.xPosition + i][claimData.yPosition + j] === "#"
      ) {
        fabric[claimData.xPosition + i][claimData.yPosition + j] = "X";
      }
    }
  }

  return fabric;
};

const blocked = fabric => {
  let numberBlocked = 0;
  for (let i = 0; i < fabric.length; i++) {
    const arr = fabric[i].filter(val => val === "X");
    numberBlocked += arr.length;
  }
  return numberBlocked;
};

const overlap = async stream => {
  let fabric = generateFabricMatrix();

  for await (const claim of streamToClaim(stream)) {
    fabric = addToFabric(claimData(claim), fabric);
  }

  return blocked(fabric);
};

const unique = async stream => {
  let fabric = generateFabricMatrix();
  const cloned = stream.pipe(new PassThrough({encoding: "utf-8"}));

  for await (const claim of streamToClaim(stream)) {
    fabric = addToFabric(claimData(claim), fabric);
  }

  for await (const claim of streamToClaim(cloned)) {
    const data = claimData(claim);

    const totalLength = data.xLength * data.yLength;
    let checkUnique = 0;

    for (const i of Array(data.xLength).keys()) {
      for (const j of Array(data.yLength).keys()) {
        if (fabric[data.xPosition + i][data.yPosition + j] === "#") {
          checkUnique++;
        }
      }
    }
    if (checkUnique === totalLength) {
      return data.id;
    }
  }
};

Main.js:

const claimStream = () => {
  return fs.createReadStream(__dirname + "/input.txt", {
    encoding: "utf-8",
    highWaterMark: 256
  });
};

const main = async () => {
  try {
    const part1 = await overlap(claimStream());
    console.log({part1});
    const part2 = await unique(claimStream());
    console.log({part2});
  } catch (e) {
    console.log(e.message);
    process.exit(-1);
  }
 

I did my part 1 similarly: I wrote the ID to each cell in it’s rectangle, unless the cell wasn’t zero, in which case I wrote -1. At the end, I counted the -1 values.

The second step was a little different. First of all, I added the ID to a set of IDs that were OK. Then I went through each cell of its rectangle. If the cell is zero, then update it to the current row’s ID. If it had a number in it, then that’s the ID of the most recent rectangle to overlap that cell; so remove the found ID and the current ID from the set of good IDs. Then set all the cells in the entire rectangle to its ID. At the end, the set of good IDs has a single element.

It sounds tricky, but it’s literally just a couple of lines of code

code of conduct - report abuse