AOC 2021 - Start
It’s a truth universally acknowledged that I hate a finished product, as long as I’m the one doing the finishing. Last year, I stopped writing these blog posts when I got bored. This year, I promise to either finish the month or get bored much more quickly, 50-50. I did eventually finish 2020’s problems with much tearing my clothes, rubbing ashes in my hair, and putting on of sackcloth. As a total aside; I think the fragmentation of literary culture away from the bible has robbed the US population of a useful schelling point, or common reference, for a rich source of metaphor (see moby dick). As always, the jewish community has a good strategy by making every smart person study the same set of books for thousands of years.
Onward and downward!
You're minding your own business on a ship at sea when the overboard alarm goes off! You rush to see if you can help. Apparently, one of the Elves tripped and accidentally sent the sleigh keys flying into the ocean!
Before you know it, you're inside a submarine the Elves keep ready for situations like this. It's covered in Christmas lights (because of course it is), and it even has an experimental antenna that should be able to track the keys if you can boost its signal strength high enough; there's a little meter that indicates the antenna's signal strength by displaying 0-50 stars.
Your instincts tell you that in order to save Christmas, you'll need to get all fifty stars by December 25th.
I’m firmly convinced the elves are hunting me for sport in increasingly convoluted ways.
Overall Approach
In preparation for this year’s puzzles, I’ve been thinking and trying to systematize my approach. There’s a few common things that I do every time, and formalizing this might help with speed, clarity of thinking, and “reflexes”.
- Read the problem
- Get the test cases
- Get the input data
- Map or subdivide the problem to known entities + examples: graph theory, regular expressions, factorization, etc
- Then develop potential solution, test it, iterate as needed
For each day, I want to try and categorize the problem and the way I solved it, to try and pick out weak points in my own thinking. I don’t intend to measure times and try to speed up this year, but I do want to do screen recordings and see where I spend my time, and where struggle. My intuition is that I struggle the most on the problem mapping stage, but we’ll see how it works out.
In terms of tools, I’m sticking with python (poetry,pyenv as package+version management) this year. I’ve also devised a template file to cut down on mental overhead, and want to try and make a library out of the functions I develop along the way. We’ll see how long that lasts.
Day 1
For lack of a better category, I’m calling this signal processing. It also follows the “map + reduce lines” pattern, or whatever. This problem was easy (~3 minutes), and I didn’t bother to make it reusable; I can’t see it coming up again.
INPUT = open('input1.txt').read()
if __name__ == '__main__':
values = [int(i) for i in INPUT.splitlines() if i]
print('part 1: ', sum(values[i+1] > values[i] f
or i in range(len(values)-1)))
print('part 2: ', sum(sum(values[i+1:i+4]) > sum(values[i:i+3])
for i in range(len(values)-3)))
Day 2
Now, you need to figure out how to pilot this thing.
...Based on your calculations, the planned course doesn't seem to make any sense. You find the submarine manual and discover that the process is actually slightly more complicated.
Based on my calculations, I’ve been trapped in some sort of puzzle world hell, ruled by a sort of red madman with lots of child labor.
Also pretty easy (5:54 but I was sick). I’m categorizing this one as “instruction per line” and “manhattan distance” or “grid movement”. I kind of want to make some visualizations of the movement here. When I’m pressed for time, I tend to name things generically, even when there’s consistent terminology in the question. Something to fix in the future. This type of problem struck me as a way to experiment with the structural pattern matching that’s new in python 3.10; something to try.
INPUT = """
forward 5
down 5
forward 8
up 3
down 8
forward 2"""
INPUT = open('input.txt').read()
def plot_pos(input):
x = 0
y = 0
for line in input.splitlines():
if not line:
continue
if line.startswith('forward'):
x += int(line.replace('forward ', ''))
elif line.startswith('down'):
y -= int(line.replace('down ', ''))
elif line.startswith('up'):
y += int(line.replace('up ', ''))
return x, y
def plot_posv2(input):
x = 0
y = 0
aim = 0
for line in input.splitlines():
if not line:
continue
if line.startswith('forward'):
w = int(line.replace('forward ', ''))
x += w
y += aim * w
elif line.startswith('down'):
aim += int(line.replace('down ', ''))
elif line.startswith('up'):
aim -= int(line.replace('up ', ''))
return x, y
if __name__ == '__main__':
print('part 1: ', plot_pos(INPUT))
print('part 2: ', plot_posv2(INPUT))