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)