Advertisement
Guest User

Untitled

a guest
Dec 8th, 2022
459
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 3.91 KB | None | 0 0
  1.     from math import prod
  2.    
  3.     DIRECTION_LEFT = (-1, 0)
  4.     DIRECTION_RIGHT = (1, 0)
  5.     DIRECTION_UP = (0, -1)
  6.     DIRECTION_DOWN = (0, 1)
  7.    
  8.    
  9.     def measures(forest: list) -> tuple:
  10.         return len(forest[0]), len(forest)
  11.    
  12.    
  13.     def get_cell(forest: list, x: int, y: int) -> int:
  14.         width, height = measures(forest)
  15.    
  16.         if x < 0 or y < 0 or x >= width or y >= height:
  17.             return None
  18.    
  19.         return forest[y][x]
  20.    
  21.    
  22.     def get_line_of_sight(forest: list, x: int, y: int, direction: tuple) -> tuple:
  23.         # IMPORTANT: this function adds a -1 at the end, representing
  24.         # the outside of the grid so all cell can be treated equally
  25.         # regardless of if they're corners or not
  26.    
  27.         output = []
  28.         vx, vy = direction
  29.         while True:
  30.             x += vx
  31.             y += vy
  32.    
  33.             if (current := get_cell(forest, x, y)) is None:
  34.                 return tuple(output + [-1])
  35.    
  36.             output.append(current)
  37.    
  38.    
  39.     def scenic_value(cell: int, line_of_sight: tuple) -> int:
  40.         for i, tree_height in enumerate(line_of_sight):
  41.             if tree_height >= cell:
  42.                 return i + 1
  43.    
  44.         return len(line_of_sight) - 1
  45.    
  46.    
  47.     def test(forest: list):
  48.         test_forest = [
  49.             [1, 2, 3],
  50.             [4, 0, 6],
  51.             [7, 8, 9],
  52.         ]
  53.    
  54.         assert (value := get_line_of_sight(test_forest, 0, 1, DIRECTION_LEFT)) == (-1,), value
  55.         assert (value := get_line_of_sight(test_forest, 0, 1, DIRECTION_UP)) == (1, -1), value
  56.         assert (value := get_line_of_sight(test_forest, 0, 1, DIRECTION_DOWN)) == (7, -1), value
  57.         assert (value := get_line_of_sight(test_forest, 0, 1, DIRECTION_RIGHT)) == (0, 6, -1), value
  58.    
  59.         assert (value := scenic_value(1, (1, 2, 3, -1))) == 1, value
  60.         assert (value := scenic_value(2, (1, 2, 3, -1))) == 2, value
  61.         assert (value := scenic_value(3, (1, 2, 3, -1))) == 3, value
  62.         assert (value := scenic_value(4, (1, 2, 3, -1))) == 3, value
  63.    
  64.    
  65.     def get_forest() -> list:
  66.         forest = []
  67.         for x in open('assets/day8.txt', 'r').read().strip().split('\n'):
  68.             forest.append([int(y) for y in list(x)])
  69.    
  70.         return forest
  71.    
  72.    
  73.     def main2(forest: list) -> int:
  74.         scores = []
  75.    
  76.         for x, y, cell in iterate_forest(forest):
  77.             points = (
  78.                 scenic_value(cell, get_line_of_sight(forest, x, y, DIRECTION_UP)),
  79.                 scenic_value(cell, get_line_of_sight(forest, x, y, DIRECTION_DOWN)),
  80.                 scenic_value(cell, get_line_of_sight(forest, x, y, DIRECTION_LEFT)),
  81.                 scenic_value(cell, get_line_of_sight(forest, x, y, DIRECTION_RIGHT)),
  82.             )
  83.    
  84.             scores.append(prod(points))
  85.    
  86.         return max(scores)
  87.    
  88.    
  89.     def iterate_forest(forest: list):
  90.         width, height = measures(forest)
  91.         for x in range(width):
  92.             for y in range(height):
  93.                 yield x, y, get_cell(forest, x, y)
  94.    
  95.    
  96.     def main1(forest: list) -> int:
  97.         amount_of_trees = 0
  98.         for x, y, cell in iterate_forest(forest):
  99.    
  100.             conditions = (
  101.                 max(get_line_of_sight(forest, x, y, DIRECTION_UP)) < cell,
  102.                 max(get_line_of_sight(forest, x, y, DIRECTION_DOWN)) < cell,
  103.                 max(get_line_of_sight(forest, x, y, DIRECTION_LEFT)) < cell,
  104.                 max(get_line_of_sight(forest, x, y, DIRECTION_RIGHT)) < cell,
  105.             )
  106.    
  107.             if any(conditions):
  108.                 amount_of_trees += 1
  109.    
  110.         return amount_of_trees
  111.    
  112.    
  113.     if __name__ == '__main__':
  114.         forest = get_forest()
  115.         test(forest)
  116.    
  117.         assert (part1 := main1(forest)) == 1662, part1
  118.         assert (part2 := main2(forest)) == 537600, part2
  119.    
  120.         print(part1, part2)
  121.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement