Advent of Code: Day 21

For Day 21, the challenge is to follow a set of rules to convert some strings.

import numpy as np

rules = {}

def flipandrotate(base):
    np_base = np.array(list(list(x) for x in base.split("/")))
    flipped = np.fliplr(np_base)

    res = []

    for i in range(4):
        for n in [np_base, flipped]:
            res.append("/".join(["".join(x) for x in np.rot90(n, i).tolist()]))

    return res

with open("input.txt", "r") as o:
    for line in o.readlines():
        f, t = line.strip().split(" => ")
        for option in flipandrotate(f):
            if option not in rules:
                rules[option] = t


size = 3
pattern = ".#./..#/###"

def pattern_coord(size, x, y):
    return y * (size + 1) + x

def get_from_pattern(pattern, size, x, y):
    return pattern[pattern_coord(size, x, y)]

def extract(pattern, original_size, size, x, y):
    new_pattern = list("/".join(["." * size for i in range(size)]))
    for xx in range(size):
        for yy in range(size):
            new_pattern[pattern_coord(size, xx, yy)] = get_from_pattern(pattern, original_size, x * size + xx, y * size + yy)
    return "".join(new_pattern)

def replace_pattern(pattern):
    return rules.get(pattern, pattern)

for i in range(18):
    block_size = 2 if size % 2 == 0 else 3
    num_blocks = size / block_size

    new_pattern = []

    for x in range(num_blocks):
        for y in range(num_blocks):
            new_sub_pattern = extract(pattern, size, block_size, x, y)
            new_sub_pattern = replace_pattern(new_sub_pattern).split("/")
            for row in range(len(new_sub_pattern[0])):
                new_row_n = y * (block_size + 1) + row
                if len(new_pattern) <= new_row_n:
                    new_pattern.append("")
                new_pattern[new_row_n] += new_sub_pattern[row]

    size = len(new_pattern[0])
    pattern = "/".join(new_pattern)
    if i == 4:
        print "Part 1", len([i for i in pattern if i == "#"])
print "Part 2", len([i for i in pattern if i == "#"])

Advent of Code runs every day up to Christmas, you should join in!.

Show Comments

Get the latest posts delivered right to your inbox.