← Back View problem

Day 4 — Camp Cleanup

Part 1

Welcome to Day 4! As usual, we’ll start by splitting our input by line.

const pairs = input.split("\n").filter(Boolean);

Now that we have our pairs, we can start to reduce them down to count the instances where they fully overlap. Since our “pairs” are still a single string at the moment, we’ll use some split and map goodness to get them in a format we can work with.

return pairs.reduce((total, pair) => {
  const ranges = pair.split(",").map((range) => {
    return range.split("-").map(Number);
  });

  // ...

  return total;
}, 0);

This will essentially take a pair string like 40-51,4-39, and convert it to a nested array that is shaped like so:

[
  [40, 51],
  [4, 39],
];

Now that we have our ranges, we can start to compare them. There are probably a few ways to do this, but my first instinct was to create a function to generate a range with a start and end value. This will allow us to compare the ranges and see if they overlap.

function createRange(start: number, end: number) {
  return Array.from({ length: end + 1 - start }, (_, k) => k + start);
}

createRange(2, 5); // [2, 3, 4, 5]

Now we’ll generate a range for each of our pairs, and compare them using Array.every to see if they overlap. If they do, we’ll add 1 to our total.

return pairs.reduce((total, pair) => {
  const ranges = pair.split(",").map((range) => {
    return range.split("-").map(Number);
  });

  const firstRange = createRange(ranges[0][0], ranges[0][1]);
  const secondRange = createRange(ranges[1][0], ranges[1][1]);

  if (
    firstRange.every((i) => secondRange.includes(i)) ||
    secondRange.every((i) => firstRange.includes(i))
  ) {
    total++;
  }

  return total;
}, 0);

And that’s it! We can run our code and get our answer: 560

Part 2

Probably the easiest part 2 yet! Our solution looks the exact same, but instead of using Array.every we simply use Array.some instead.

Boom! Our answer is 839 😄

← Back View problem