lines = [line.strip() for line in open("14.input")]

rocks = set()

for line in lines:
    coords = line.split(" -> ")
    for i in range(0, len(coords) - 1):
        start = list(map(int, coords[i].split(",")))
        end = list(map(int, coords[i+1].split(",")))
        if start[0] == end[0]:
            for y in range(min(start[1], end[1]), max(start[1], end[1]) + 1):
                rocks.add((start[0], y))
        else:
            for x in range(min(start[0], end[0]), max(start[0], end[0]) + 1):
                rocks.add((x, start[1]))

def draw_grid(rocks, sands):
    obst = rocks.union(sands)
    min_x = min(o[0] for o in sands)
    max_x = max(o[0] for o in sands)
    max_y = max(o[1] for o in obst)
    for y in range(0, max_y+1):
        for x in range(min_x, max_x):
            if (x, y) in rocks:
                print("#", end="")
            elif (x, y) in sands:
                print("o", end="")
            else:
                print(".", end="")
        print("")

def step(rocks, sands, bottom):
    obst = rocks.union(sands)

    sand = (500, 0)

    if sand in sands:
        return sands

    while True:
        if sand[1] > bottom:
            return sands
        targets = [
           (sand[0], sand[1] + 1),
           (sand[0] - 1, sand[1] + 1),
           (sand[0] + 1, sand[1] + 1),
           ]
        for t in targets:
            if t not in obst:
                sand = t
                break
        else:
            break

    sands.add(sand)
    return sands

def part1():
    sands = set()
    bottom = max(r[1] for r in rocks)

    while True:
        l = len(sands)
        sands = step(rocks, sands, bottom)
        if l == len(sands):
            break

    print(len(sands))

part1()

def part2():
    sands = set()
    bottom = max(r[1] for r in rocks) + 2

    for x in range(-1000, 1000):
        rocks.add((x, bottom))

    while True:
        l = len(sands)
        sands = step(rocks, sands, bottom)
        if l == len(sands):
            break

    print(len(sands))

part2()