Jesper Dramsch , , read in 3 minutes

Is this range in that range?

What is Advent of Code?

In this little series, I want to write about the thought processes I have behind solving the puzzles presented in Advent of Code.

During the Advent of Code small coding puzzles are presented with varying levels of difficulty. They're always Christmas-themed text puzzles where you help elves out of some mess to save the holidays. The puzzles are deliberately ambiguous to not bias puzzlers into a certain solution, they always have an example input in the text to explain some details and an input file for each day that comes in the form of a text file you can download. The solution is a simple number or a string you enter, which is checked by the website automatically. After you finish part 1, part 2 unlocks, which is a variation on part 2. This can be a little twist on part 1 or a large twist that changes the problem formulation into a problem that would take brute force solutions to compute longer than the heat death of the universe would take.

Find my solutions here: github.com/JesperDramsch/advent-of-code

These descriptions won't be a perfect narrative, but rather how I think about these problems and where I see different solutions. I apologise for the possibility of rambling!

The example input

This looked like a bunch of ranges, so I already knew, I had to be aware of that one error:

2-4,6-8
2-3,4-5
5-7,7-9
2-8,3-7
6-6,4-6
2-6,4-8

Are the range exclusive or inclusive of the last number?!

The implementation

It was easy to mess up the parsing from the example. Not every number in the actual input data is between 0-9, so I busted out the trusty old regex.

m = re.match(r"(\d+)-(\d+),(\d+)-(\d+)", line).groups()

Extract those numbers and then process them.

So now we just have to figure out if one pair is fully contained within the other or vice versa. I decided to simply do this with a big if statement:

v = b[0] <= a[0] <= b[1]
w = b[0] <= a[1] <= b[1]
x = a[0] <= b[0] <= a[1]
y = a[0] <= b[1] <= a[1]

This would look different if the last number was exclusive, where we'd replace a few of the <= with a <, but this works.

For the fully contained example I now just had to combine those if statements correctly: (v and w) or (x and y).

Part Deux

You may be wondering why I didn't do this in a single swoop.

I did.

But I didn't want to repeat code for part 2, so I tore apart the if statements.

Now part 2 is simply:

v or w or x or y

I love it when I write code that is so easily reusable!

Error Log

Here are the mistake I made along the way:

  • ValueError: invalid literal for int() with base 10: '-' forgot that numbers can be more than 1 digit
  • TypeError: int() argument must be a string, a bytes-like object or a real number, not 'tuple' misremembered the call of regex groups as regex.groups(0), when the .groups() just returns the tuple of matches.
  • Wrong result on example, because I checked for partial containment not full. Changed or to and and it passes. // My hello part 2
  • TypeError: contained() missing 1 required positional argument: 'b' when rewriting the parser and the contained function, I forgot to adjust the function call in main()