Python Tips & Tricks for the Advent of Code 2019

Day 1: The Tyranny of the Rocket Equation

problem / solution

import fileinputif __name__ == '__main__':
lines = [*fileinput.input()]
process(lines)
echo 'input' | ./day1.py
cat input.txt | ./day1.py
./day1.py input.txt

Day 2: 1202 Program Alarm

problem / solution

Day 3: Crossed Wires

problem / solution

grid = {
(0, 0): '.',
(0, 1): '#',
(1, 0): '#',
(1, 1): '.',
}
  • You don’t have to worry about row-major vs. column-major order.
  • You don’t thave to worry about bounds checking: grid.get((-1, 0)) is valid and returns None, whereas negative indexing in a list will do something different.
  • You don’t need to know the size of the grid in advance. This is especially helpful if you’re starting in the middle and exploring a space, as on Day 15. Negative indices are OK.
grid = {
(x, y): v
for y, row in enumerate(fileinput.input())
for x, v in enumerate(row.strip())
}
def minmax(it):
vals = list(it)
return min(vals), max(vals)
minx, maxx = minmax(x for x, y in grid.keys())
miny, maxy = minmax(y for x, y in grid.keys())
explored_nodes = {...}
moves = [
(-1, 0),
(+1, 0),
(0, -1),
(0, +1),
]
new_nodes = {
x + dx, y + dy
for x, y in current_nodes
for dx, dy in moves
if grid.get((x + dx, y + dy)) == '.'
and (x + dx, y + dy) not in explored_nodes
}
new_nodes = {
node
for x, y in current_nodes
for dx, dy in moves
if grid.get(node := (x + dx, y + dy)) == '.'
and node not in explored_nodes
}

Day 7: Amplification Circuit

problem / solution

Day 10: Monitoring Station (Asteroid lines of sight)

problem / solution

  • itertools.combinations(xs, 2) returns an iterator over all pairs.
  • math.atan2 is a version of arctangent that takes x and y as two separate arguments (unlike regular math.atan, which takes y/x). This ensures you get an angle back that's in the correct quadrant: key for part 2!
  • defaultdict(list) is a convenient way to index a list by something. For example, to index the asteroids by their angle (as in part 2):
Using math.atan2 and defaultdict(list) to index the list of asteroids by angle

Day 12: The N-Body Problem

problem / solution

Day 13: Care Package (Breakout game)

problem / solution

  • Adding a save/restore feature.
  • Adding an indicator for where the ball would land on the bottom.
def address_for_block(x, y):
return 1664 + ((((((25 * x + y) * 521) + 1011) % (64 * 1025)) % (8 * 1025)) % 1025)

Day 14: Space Stoichiometry

problem / solution

Day 15: Oxygen System

problem / solution

Day 16: Flawed Frequency Transmission

problem / solution

I decided to hang out on these hammocks while my slow solution to Day 16 ran.

Day 18: Many-Worlds Interpretation (Maze & Keys)

problem / solution

Day 20: Donut Maze

problem / solution

Day 21: Springdroid Adventure

problem / solution

  • You can split the problem into three cases: there’s a blank immediately in front of you (in which case you must jump), a blank two in front of you and a blank three in front of you. You always want to decide to jump, rather than not to jump.
  • For each case, you can take all the examples in which you want to jump, OR them and simplify the resulting boolean expression.
  • To implement a boolean expression in SpringScript, you need to get it in a form that starts with a NOT (since another case might have set the T register) and does not branch. I’m curious if there’s a name for this form.

Day 22: Slam Shuffle

problem / solution

> pow(2, 3, 7)
1 # 2 ** 3 % 7 == 1
> pow(2, -1, 7)
4
> 2 * 4 % 7
1

Day 25: Cryostasis (Christmas!)

After the challenges of the previous few days, Days 23 and 24 were comparably easy—a welcome relief! I was prepared for part two of Day 25 to be a real monster of a problem, but much to my surprise it was just a congratulations!

--

--

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store
Dan Vanderkam

Dan Vanderkam

507 Followers

Software Developer @sidewalklabs, author of Effective TypeScript