The puzzles in AoC are meant to be light-hearted, and that includes the titles. However, they can sometimes give you a clue to what's coming. Here's Part 1 of today's puzzle:
A nice string function that is handy here is
split(), which divides a string into a list, based on a delimiter. For example, splitting
'x' results in a list of three items:
['2', '3', '4'].
Unfortunately, these are all strings, which will be a bit of a pain when we try to multiply them. Thankfully, Python also has a
map() function, which can apply functions to iterators, including lists. So we end up with something like this:
l, w, h = map(int, data.split('x'))
This highlights another neat feature of Python, of being able to initialise or update several variables at once.
The next part of solving the puzzle involves finding the two smallest sides, to work out the size of the extra piece of wrapping paper. Python has
min(), but this doesn't help with finding the second smallest side. In the end, I decided to sort the list so the first two items would always be the shortest. I did later see
min() used in other solutions to find the smallest 'extra' piece:
extra_piece = min(l*w, w*h, 1*h).
My code, though, essentially looked like this:
total_area = 0 for box in data: l, w, h = sorted(map(int, box.split('x'))) area = (2 * l * w) + (2 * l * h) + (2 * w * h) extra = l * w #Always the shortest sides, thanks to the sort total_area += (area + extra)
This solved nicely for Part 1, and made Part 2 surprisingly easy:
The calculation for part of the ribbon also depends on knowing the shortest two sides, which meant that my Part 1 code could simply be extended to solve Part 2:
total_ribbon = 0 total_area = 0 for box in data: l, w, h = sorted(map(int, box.split('x'))) area = (2 * l * w) + (2 * l * h) + (2 * w * h) extra = l * w total_area += (area + extra) bow = l * w * h ribbon = (2 * l) + (2 * w) total_ribbon += (bow + ribbon)
Didn't see any golfing solutions in Python, although there were several for other languages, like PHP and Bash.
I have lost count of the number of times I've had to completely rethink my approach to Advent code when Part 2 is revealed! This can often be avoided by not simply throwing yourself into solving Part 1 without spending a minute or two wondering how the puzzle might develop. (Don't do this if you're trying to get on the leader board, of course!)
For example, if Part 1 of a puzzle has you finding your way through a field of data using the cardinal directions, you can almost guarantee that Part 2 will have you moving in diagonals. You won't save time on Part 1, but you could save a ton of time on Part 2 if you plan ahead. It won't always work, but the more puzzles you do, the better feel you'll get for what might be coming up!
On to Day 3, then...