Series: Advent of Code 2016

All posts

Recent posts

Advent of Code 2016

As I did last year, I’m going to solve the Advent of Code problems again this year.

Or that was the plan. It turns out that instead I put down my blog for almost a year and a half and never quite got around to doing these problems. So I’m actually backdating these posts from the early days of 2018 to where they would have been had I solved them on time. They’re still interesting problems, so give them a read.

read more...


AoC 2016 Day 24: Venti

Source: Air Duct Spelunking

Part 1: Given a map of the form:

########### #0.1…..2# #.#######.# #4…….3# ###########


> Find the shortest route to visit each of the points, starting at `0`.





First, we want to take the map that we were given and simplify it. We know that we want to visit all of the points, so lets take the original map and turn it just into a map of distances between any two named points.

```python
walls = set()
name_to_point = {}
point_to_name = {}

# Load the input file into a set of walls and the location of points of interest
for y, line in enumerate(fileinput.input(args.files)):
    for x, c in enumerate(line.strip()):
        if c.isdigit():
            name_to_point[int(c)] = (x, y)
            point_to_name[(x, y)] = int(c)

        elif c == '#':
            walls.add((x, y))

# Dynamically fill a distance map to a given point
def distances_to(name):
    to_scan = queue.Queue()
    to_scan.put((name_to_point[name], 0))

    scanned = set()

    result = {}

    while not to_scan.empty():
        point, distance = to_scan.get()

        if point in point_to_name:
            name = point_to_name[point]
            if name not in result:
                result[name] = distance

        if point in scanned:
            continue
        else:
            scanned.add(point)

        x, y = point
        for xd, yd in [(-1, 0), (1, 0), (0, -1), (0, 1)]:
            neighbor = (x + xd, y + yd)
            if neighbor not in walls:
                to_scan.put((neighbor, distance + 1))

    return result

distances = {
    name: distances_to(name)
    for name in name_to_point
}
names = list(sorted(name_to_point.keys()))

The first part loads the map and the second part will flood fill out from each point. This will find the minimum distance from each named point to the given one, somewhat simplifying the problem.

read more...


AoC 2016 Day 23: Assembunny2

Source: Safe Cracking

Part 1: Take the assembunny interpreter from day 12 and add an instruction (tgl X) that modifies the code at an offset of X instructions.

  • inc becomes dec; any other one argument instruction (including tgl) becomes inc
  • jnz becomes cpy; any other two argument instructions become jnz
  • Toggling an instruction outside of the program does nothing (it does not halt execution)
  • If toggling produces an invalid instruction, ignore it

Run the given program with the initial register of a = 7. What is the final value in register a?

read more...


AoC 2016 Day 21: Scrambler

Source: Scrambled Letters and Hash

Part 1: Another virtual machine, of sorts. Start with the string abcdefgh and apply a sequence of the following commands to it:

  • swap position X with position Y = swap two positions
  • swap letter X with letter Y = swap to letters, no matter where they are
  • rotate (left|right) X steps = rotate forward or backward
  • rotate based on position of letter X = find X, rotate right based on its position; if the original position was >= 4, rotate one more1
  • reverse positions X through Y = reverse a subset of the string
  • move position X to position Y = take a character at a position out of the string and put it somewhere else specific

read more...


AoC 2016 Day 18: Its A Trap

Source: Like a Rogue

Part 1: Starting with a sequence of . and ^, generate additional rows using the rules based on the three characters above the new position.

  • ^^. -> ^
  • .^^ -> ^
  • ^.. -> ^
  • ..^ -> ^
  • Otherwise -> .

How many safe tiles (.) are there after 40 generations?

read more...


AoC 2016 Day 17: Md5 Maze

Source: Two Steps Forward

Part 1: Create a 4x4 grid of rooms with doors Up, Down, Left, and Right from each location. To determine if a door is currently open:

  • Calculate MD5(salt + sequence) where sequence is a string containing any combination of UDLR depending on how you got to this room
  • The first four hex values represent the doors Up, Down, Left, and Right respectively: bcdef means open; anything else is closed

Find the shortest path from (0, 0) to (3, 3).

read more...