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?

This is an elementary cellular automaton. Specifically, Rule 90. I wrote a solution to these five years ago 1 with a pretty cool web based simulator. Here’s a way to do it in Python with zip though:

# If the previous row left, center, right looks like this, the next element is a trap
trap_map = {
    ('^', '^', '.'), # Its left and center tiles are traps, but its right tile is not.
    ('.', '^', '^'), # Its center and right tiles are traps, but its left tile is not.
    ('^', '.', '.'), # Only its left tile is a trap.
    ('.', '.', '^'), # Only its right tile is a trap.
}

def next(row):
    return ''.join(
        '^' if previous in trap_map else '.'
        for previous in zip('.' + row, row, row[1:] + '.')
    )

def rows(row, height):
    yield row
    for i in range(height - 1):
        row = next(row)
        yield row

safe_count = 0
trap_count = 0

for row in rows(args.initial, args.height):
    safe_count += row.count('.')
    trap_count += row.count('^')
    logging.info(row)

print('{} safe, {} trap'.format(safe_count, trap_count))

Part 2: How many safe tiles are there after 400,000 rows?

The solution doesn’t change. It’s already as memory efficient as it can be, only keeping one row at a time.


  1. I feel old now. ↩︎