#!/usr/bin/env python # -*- encoding: utf-8; py-indent-offset: 4 -*- # Author: Sebastian Mark # CC-BY-SA (https://creativecommons.org/licenses/by-sa/4.0/deed.de) # pylint: disable=missing-module-docstring,missing-function-docstring,consider-using-f-string def readinput(): with open("input", "r", encoding="utf-8") as file: lines = [list(line.strip()) for line in file] return lines def is_visible(trees: list, tree_y: int, tree_x: int) -> bool: height = len(trees) width = len(trees[0]) # edges are always visible if not 0 < tree_y < height - 1 or not 0 < tree_x < width - 1: return True # check up, right, down, right directions = [(-1, 0), (0, 1), (1, 0), (0, -1)] for dy, dx in directions: nxty = tree_y + dy nxtx = tree_x + dx # continue to check in the direction til border is_biggest = True while 0 <= nxty < height and 0 <= nxtx < width: # check size, stop searching if bigger tree found if trees[tree_y][tree_x] <= trees[nxty][nxtx]: is_biggest = False break nxtx += dx nxty += dy if is_biggest: return True return False def scenic_score(trees: list, tree_y: int, tree_x: int) -> int: height = len(trees) width = len(trees[0]) score = 1 # check up, right, down, right directions = [(-1, 0), (0, 1), (1, 0), (0, -1)] for dy, dx in directions: nxty = tree_y + dy nxtx = tree_x + dx visual_range = 1 # continue to check in the direction til border while 0 < nxty < height - 1 and 0 < nxtx < width - 1: # check size, stop if bigger tree found if trees[tree_y][tree_x] <= trees[nxty][nxtx]: break visual_range += 1 nxtx += dx nxty += dy score *= visual_range return score def main(): trees = readinput() # part 1 visible = 0 for y in range(len(trees)): for x in range(len(trees[0])): if is_visible(trees, y, x): visible += 1 print("Visible trees: %d" % visible) # part 1 scenic_scores = [] for y in range(len(trees)): for x in range(len(trees[0])): scenic_scores.append(scenic_score(trees, y, x)) print("Highest scenic score: %d" % max(scenic_scores)) if __name__ == "__main__": main()