DEV Community

Cover image for Camp Cleanup
Robert Mion
Robert Mion

Posted on

Camp Cleanup

Advent of Code 2022 Day 4

Part 1

  1. Extracting the numbers with regex
  2. Comparing A to B and B to A
  3. My algorithm in JavaScript

Extracting the numbers with regex

From this string:

2-4,6-8
Enter fullscreen mode Exit fullscreen mode

...I want the numbers.

Thankfully, that's a simple regular expression:

/\d+/g
Enter fullscreen mode Exit fullscreen mode

That will match each contiguous set of digits.

Comparing A to B and B to A

Sticking with the first example:

2-4,6-8
Enter fullscreen mode Exit fullscreen mode

I want to check both of these:

Is 6-8 fully contained in 2-4?
Or
Is 2-4 fully contained in 6-8?
Enter fullscreen mode Exit fullscreen mode

As long as one is true, I found a valid pair!

Replacing digits with locations:

a b c d
Enter fullscreen mode Exit fullscreen mode

I want to check both of these:

Is a <= c and b >= d?
Or
Is c <= a and d >= b?
Enter fullscreen mode Exit fullscreen mode

Again, as long as one is true, I found a valid pair!

My algorithm in JavaScript

return input
  .split('\n')
  .reduce((valids, pair) => {
    let [a,b,c,d] = [...pair.matchAll(/\d+/g)]
                       .map(el => +el[0])
    let flag = (a <= c && b >= d) || (c <= a && d >= b)
    return valids += flag ? 1 : 0
  }, 0)
Enter fullscreen mode Exit fullscreen mode

Part 2

  1. Twist: Venn diagram
  2. Using Sets instead of messy conditions

Twist: Venn diagram

Instead of a fully-enclosed pair, I now need to identify any pair that share at least one digit among their ranges.

Using Sets instead of messy conditions

For this example pair and diagram:

.2345678.  2-8
..34567..  3-7
Enter fullscreen mode Exit fullscreen mode

I could use this logic:

let pair1 = [2,3,4,5,6,7,8]
pair1.length // 7

let pair2 = [3,4,5,6,7]
pair2.length // 5

let mergedUniques = [2,3,4,5,6,7,8]
mergedUniques.size = // 7

if (mergedUniques.size < pair1.length + pair2.length) {
  // Valid pair!
} else {
  // No overlap!
}
Enter fullscreen mode Exit fullscreen mode

My algorithm in JavaScript

return input
  .split('\n')
  .reduce((valids, pair) => {
    let [a,b,c,d] = [...pair.matchAll(/\d+/g)]
                       .map(el => +el[0])
    let pair1 = new Array(b - a + 1)
      .fill(null)
      .map((_,i) => i + a)
    let pair2 = new Array(d - c + 1)
      .fill(null)
      .map((_,i) => i + c)
    let merged = new Set(pair1.concat(pair2))
    let flag = merged.size < pair1.length + pair2.length
    return valids += flag ? 1 : 0
  }, 0)
Enter fullscreen mode Exit fullscreen mode

I did it!!

  • I solved both parts!
  • I used conditions, Sets, regex and reduce()!
  • I reused my algorithm for generating an array of numbers from a min and max!

For a Sunday puzzle, this one felt relatively easy.

I anticipate one of a variety of puzzle themes coming up, like: changing grid, shortest path, circular games?

Just. Please. No. Assembly. Code.

Top comments (0)