mirror of
https://github.com/RussellChamp/advent-of-code-2022.git
synced 2026-10-27 21:52:30 +00:00
91 lines
2.9 KiB
Python
91 lines
2.9 KiB
Python
# Day 08: Treetop Tree House
|
|||
|
|
|
||
|
|
import os
|
||
|
|
|
||
|
|
def get_path():
|
||
|
|
return os.path.join(os.path.dirname(__file__), 'data.txt')
|
||
|
|
|
||
|
|
def build_grid():
|
||
|
|
grid = []
|
||
|
|
with open(get_path()) as fp:
|
||
|
|
for line in fp:
|
||
|
|
grid.append(map(int, line.strip()))
|
||
|
|
return grid
|
||
|
|
|
||
|
|
def get_column(grid, col_idx):
|
||
|
|
return map(lambda row: row[col_idx], grid)
|
||
|
|
|
||
|
|
def is_visible(grid, row_idx, col_idx):
|
||
|
|
# all edge trees are visible
|
||
|
|
if row_idx == 0 or row_idx == len(grid) -1 \
|
||
|
|
or col_idx == 0 or col_idx == len(grid[0]) - 1:
|
||
|
|
return True
|
||
|
|
cell = grid[row_idx][col_idx]
|
||
|
|
# check the left side
|
||
|
|
if all([item < cell for item in grid[row_idx][:col_idx]]):
|
||
|
|
return True
|
||
|
|
# check the right side
|
||
|
|
if all([item < cell for item in grid[row_idx][col_idx+1:]]):
|
||
|
|
return True
|
||
|
|
# check the top
|
||
|
|
if all([item < cell for item in get_column(grid, col_idx)[:row_idx]]):
|
||
|
|
return True
|
||
|
|
# check the bottom
|
||
|
|
if all([item < cell for item in get_column(grid, col_idx)[row_idx+1:]]):
|
||
|
|
return True
|
||
|
|
return False
|
||
|
|
|
||
|
|
def score_row(height, row):
|
||
|
|
score = 0
|
||
|
|
for item in row:
|
||
|
|
score += 1
|
||
|
|
if item >= height:
|
||
|
|
break
|
||
|
|
return score
|
||
|
|
|
||
|
|
def get_score(grid, row_idx, col_idx):
|
||
|
|
# all edge trees will have at least one size with a 0 score
|
||
|
|
if row_idx == 0 or row_idx == len(grid) -1 \
|
||
|
|
or col_idx == 0 or col_idx == len(grid[0]) - 1:
|
||
|
|
return 0
|
||
|
|
|
||
|
|
height = grid[row_idx][col_idx]
|
||
|
|
left_score = score_row(height, grid[row_idx][:col_idx][::-1]) # [::-1] reverses a slice. who knew?
|
||
|
|
right_score = score_row(height, grid[row_idx][col_idx+1:])
|
||
|
|
top_score = score_row(height, get_column(grid, col_idx)[:row_idx][::-1]) # reverse it because we are looking "backwards"
|
||
|
|
bottom_score = score_row(height, get_column(grid, col_idx)[row_idx+1:])
|
||
|
|
total_score = left_score * right_score * top_score * bottom_score
|
||
|
|
# print ('grid[%d][%d] = %d, (%d, %d, %d, %d) = %d' % (row_idx, col_idx, height, left_score, right_score, top_score, bottom_score, total_score))
|
||
|
|
return total_score
|
||
|
|
|
||
|
|
def solve_part1():
|
||
|
|
total = 0
|
||
|
|
|
||
|
|
grid = build_grid()
|
||
|
|
# print('height %d, width %d' % (len(grid), len(grid[0])))
|
||
|
|
for row_idx in range(0, len(grid)):
|
||
|
|
for col_idx in range(0, len(grid[row_idx])):
|
||
|
|
if is_visible(grid, row_idx, col_idx):
|
||
|
|
total += 1
|
||
|
|
|
||
|
|
print('Day 08: Part 1')
|
||
|
|
print('GOAL: Count the number of trees that are visible from outside the grid when looking directly along a row or column.')
|
||
|
|
print('ANSWER: How many trees are visible from outside the grid?')
|
||
|
|
print('Total: %d' % (total))
|
||
|
|
|
||
|
|
def solve_part2():
|
||
|
|
best_score = 0
|
||
|
|
grid = build_grid()
|
||
|
|
for row_idx in range(0, len(grid)):
|
||
|
|
for col_idx in range(0, len(grid[row_idx])):
|
||
|
|
score = get_score(grid, row_idx, col_idx)
|
||
|
|
best_score = score if score > best_score else best_score
|
||
|
|
|
||
|
|
print('Day 08: Part 2')
|
||
|
|
print('GOAL: Consider each tree on your map.')
|
||
|
|
print('ANSWER: What is the highest scenic score possible for any tree?')
|
||
|
|
print('Best Score: %d' % (best_score))
|
||
|
|
|
||
|
|
if __name__ == '__main__':
|
||
|
|
solve_part1()
|
||
|
|
solve_part2()
|