Sean McLemon | Advent of Code

Home | Czech | Blog | GitHub | Advent Of Code | Notes


2021-12-13 - Transparent Origami

(original .ipynb)

Day 13 puzzle input consists of some co-ordinates of dots on a piece of transparent paper, and some instructions describing a sequence of folds to perform (mine is here). Part 1 involves determining the number of dots which are visible after performing the first fold. Part 2 involves following all the folds and determining a code from the resulting dot pattern.

puzzle_input_str = open("puzzle_input/day13.txt").read()

test_input_str = """6,10
0,14
9,10
0,3
10,4
4,11
6,0
6,12
4,1
0,13
10,12
3,4
3,0
8,4
1,10
2,14
8,10
9,0

fold along y=7
fold along x=5"""


def parse_dots(dots_str):
    for line in dots_str.split("\n"):
        x,y = line.split(",")
        yield (int(y),int(x))


def fold_x(dots, fold_pos):
    for r, c in dots:
        if c < fold_pos:
            yield (r, c)
        else:
            yield (r, (2*fold_pos) - c)


def fold_y(dots, fold_pos):
    for r, c in dots:
        if r < fold_pos:
            yield (r, c)
        else:
            yield ((2 * fold_pos) - r, c)


def parse_folds(folds_str):
    fold_action = {"x": fold_x, "y": fold_y}
    for line in folds_str.split("\n"):
        axis, fold_pos = line.removeprefix("fold along ").split("=")
        yield (fold_action[axis], int(fold_pos))


def parse_input(input_str):
    dots_str, folds_str = input_str.split("\n\n")
    return parse_dots(dots_str), parse_folds(folds_str)


def apply_folds(dots, folds):
    for fold_action, fold_pos in folds:
        dots = fold_action(dots, fold_pos)
    return dots

    
def part_one(input_str):
    dots, folds = parse_input(input_str)
    dots = apply_folds(dots, [next(folds)])   
    return len(set((dots)))


assert 17 == part_one(test_input_str)
print("part one:", part_one(puzzle_input_str))
part one: 701
def print_dots(dots):
    paper = []
    rs, cs = zip(*dots)
    max_row = max(rs)
    max_col = max(cs)
    
    for r in range(max_row + 2):
        paper.append([" "] * (max_col + 1))
    
    for r,c in dots:
        paper[r][c] = "#"
        
    for line in paper:
        print("".join(line))


def part_two(input_str):
    dots, folds = parse_input(input_str)
    dots = apply_folds(dots, folds)
    print_dots(list(dots))


print("part two:\n")
print("(test)")
part_two(test_input_str)

print("(puzzle)")
part_two(puzzle_input_str)
part two:

(test)
#####
#   #
#   #
#   #
#####
     
(puzzle)
#### ###  #### #  # ###  ####   ## #   
#    #  # #    # #  #  # #       # #   
###  #  # ###  ##   ###  ###     # #   
#    ###  #    # #  #  # #       # #   
#    #    #    # #  #  # #    #  # #   
#    #    #### #  # ###  ####  ##  ####