Day 8 - Advent of Code 2022

Working solutions for the day 8 puzzles.

Part One

""" day_08_01.py """

# usage: python3 day_08_01.py < input

import sys


def chop(height, base):
    """ calculate height above base less one - floor is 0 """
    return max(0, height - (base - 1))


def top(row_arg, col_arg, patch_arg):
    """ calculate top edge to tree at row, col """
    tree = patch_arg[row_arg][col_arg]
    line = [chop(patch_arg[y][col_arg], tree) for y in range(0, row_arg)]
    return sum(line) == 0


def bottom(row_arg, col_arg, patch_arg):
    """ calculate tree at row, col to bottom edge """
    tree = patch_arg[row_arg][col_arg]
    line = [chop(patch_arg[y][col_arg], tree)
            for y in range(row_arg + 1, len(patch_arg))]
    return sum(line) == 0


def left(row_arg, col_arg, patch_arg):
    """ calculate left edge to tree at row, col """
    tree = patch_arg[row_arg][col_arg]
    line = [chop(patch_arg[row_arg][x], tree) for x in range(0, col_arg)]
    return sum(line) == 0


def right(row_arg, col_arg, patch_arg):
    """ calculate tree at row, col to right edge """
    tree = patch_arg[row_arg][col_arg]
    line = [chop(patch_arg[row_arg][x], tree)
            for x in range(col_arg + 1, len(patch_arg[0]))]
    return sum(line) == 0


def visible(row_arg, col_arg, patch_arg):
    """ calculate if tree at row, col is visible in square patch """
    size = len(patch_arg) - 1
    if 0 in (row_arg, col_arg) or size in (row_arg, col_arg):
        return True
    if top(row_arg, col_arg, patch_arg):
        return True
    if bottom(row_arg, col_arg, patch_arg):
        return True
    if left(row_arg, col_arg, patch_arg):
        return True
    if right(row_arg, col_arg, patch_arg):
        return True
    return False


patch = []
for row in sys.stdin:
    patch.append(list(map(int, row.rstrip())))

count = 0
for j, row in enumerate(patch):
    for i, col in enumerate(row):
        if visible(j, i, patch):
            count += 1
print(count)

Part Two

""" day_08_02.py """

# usage: python3 day_08_02.py < input

import sys
import math


def top(row_arg, col_arg, patch_arg):
    """ calculate from tree at row, col towards top edge """
    tree = patch_arg[row_arg][col_arg]
    count = 0
    for y in range(row_arg - 1, -1, -1):
        count += 1
        if patch_arg[y][col_arg] >= tree:
            break
    return count


def bottom(row_arg, col_arg, patch_arg):
    """ calculate from tree at row, col towards bottom edge """
    tree = patch_arg[row_arg][col_arg]
    count = 0
    for y in range(row_arg + 1, len(patch_arg)):
        count += 1
        if patch_arg[y][col_arg] >= tree:
            break
    return count


def left(row_arg, col_arg, patch_arg):
    """ calculate from tree at row, col towards left edge """
    tree = patch_arg[row_arg][col_arg]
    count = 0
    for x in range(col_arg - 1, -1, -1):
        count += 1
        if patch_arg[row_arg][x] >= tree:
            break
    return count


def right(row_arg, col_arg, patch_arg):
    """ calculate from tree at row, col towards right edge """
    tree = patch_arg[row_arg][col_arg]
    count = 0
    for x in range(col_arg + 1, len(patch_arg[row_arg])):
        count += 1
        if patch_arg[row_arg][x] >= tree:
            break
    return count


def scenic(row_arg, col_arg, patch_arg):
    """ calculate scenic score for tree at row, col in square patch """
    output = (top(row_arg, col_arg, patch_arg),
              bottom(row_arg, col_arg, patch_arg),
              left(row_arg, col_arg, patch_arg),
              right(row_arg, col_arg, patch_arg))
    return math.prod(output)


patch = []
for row in sys.stdin:
    patch.append(list(map(int, row.rstrip())))

score = 0
for j, row in enumerate(patch):
    for i, col in enumerate(row):
        score = max(score, scenic(j, i, patch))
print(score)