Day 17 - Advent of Code 2022

Working solutions for the day 17 puzzles.

Part One

""" day_17_01.py """

# usage: python3 day_17_01.py < input


import sys


def rock_generator():
    """ generate rocks """
    rocks = [{(0, 0), (1, 0), (2, 0), (3, 0)},
             {(1, 0), (0, 1), (1, 1), (2, 1), (1, 2)},
             {(0, 0), (1, 0), (2, 0), (2, 1), (2, 2)},
             {(0, 0), (0, 1), (0, 2), (0, 3)},
             {(0, 0), (1, 0), (0, 1), (1, 1)}]
    while True:
        for unit in rocks:
            yield unit


def jet_generator():
    """ generate jet blasts """
    data = sys.stdin.read().rstrip()
    while True:
        for item in data:
            yield item


def peak(data):
    """ calculate highest point """
    return max({y for _, y in data})


def move(delta, shape, data):
    """ move shape delta units """
    dx, dy = delta
    shift = {(x + dx, y + dy) for x, y in shape}
    if [x for x, _ in shift if x < 0 or x > 6]:
        return shape, False
    if data.isdisjoint(shift):
        return shift, True
    return shape, False


def left(shape, data):
    """ move shape left """
    return move((-1, 0), shape, data)[0]


def right(shape, data):
    """ move shape right """
    return move((1, 0), shape, data)[0]


def down(shape, data):
    """ move shape down """
    return move((0, -1), shape, data)


def place(shape, data):
    """ place shape """
    return move((2, peak(data) + 4), shape, data)[0]


def action(blast, shape, data):
    """ action jet blast on shape """
    if blast == '<':
        return left(shape, data)
    return right(shape, data)


rock = rock_generator()
jet = jet_generator()

field = {(0, 0), (1, 0), (2, 0), (3, 0), (4, 0), (5, 0), (6, 0)}

rock_count = 2022
while rock_count > 0:
    sprite = place(next(rock), field)
    in_motion = True
    while in_motion:
        sprite = action(next(jet), sprite, field)
        sprite, in_motion = down(sprite, field)
    field = field.union(sprite)
    rock_count -= 1
print(peak(field))

Part Two

# standby ...