Solved 2024/14
This commit is contained in:
+125
@@ -0,0 +1,125 @@
|
||||
## \-\-- Day 8: Treetop Tree House \-\--
|
||||
|
||||
The expedition comes across a peculiar patch of tall trees all planted
|
||||
carefully in a grid. The Elves explain that a previous expedition
|
||||
planted these trees as a reforestation effort. Now, they\'re curious if
|
||||
this would be a good location for a [tree
|
||||
house](https://en.wikipedia.org/wiki/Tree_house).
|
||||
|
||||
First, determine whether there is enough tree cover here to keep a tree
|
||||
house *hidden*. To do this, you need to count the number of trees that
|
||||
are *visible from outside the grid* when looking directly along a row or
|
||||
column.
|
||||
|
||||
The Elves have already launched a
|
||||
[quadcopter](https://en.wikipedia.org/wiki/Quadcopter)
|
||||
to generate a map with the height of each tree ([your puzzle
|
||||
input]{title="The Elves have already launched a quadcopter (your puzzle input)."}).
|
||||
For example:
|
||||
|
||||
30373
|
||||
25512
|
||||
65332
|
||||
33549
|
||||
35390
|
||||
|
||||
Each tree is represented as a single digit whose value is its height,
|
||||
where `0` is the shortest and `9` is the tallest.
|
||||
|
||||
A tree is *visible* if all of the other trees between it and an edge of
|
||||
the grid are *shorter* than it. Only consider trees in the same row or
|
||||
column; that is, only look up, down, left, or right from any given tree.
|
||||
|
||||
All of the trees around the edge of the grid are *visible* - since they
|
||||
are already on the edge, there are no trees to block the view. In this
|
||||
example, that only leaves the *interior nine trees* to consider:
|
||||
|
||||
- The top-left `5` is *visible* from the left and top. (It isn\'t
|
||||
visible from the right or bottom since other trees of height `5` are
|
||||
in the way.)
|
||||
- The top-middle `5` is *visible* from the top and right.
|
||||
- The top-right `1` is not visible from any direction; for it to be
|
||||
visible, there would need to only be trees of height *0* between it
|
||||
and an edge.
|
||||
- The left-middle `5` is *visible*, but only from the right.
|
||||
- The center `3` is not visible from any direction; for it to be
|
||||
visible, there would need to be only trees of at most height `2`
|
||||
between it and an edge.
|
||||
- The right-middle `3` is *visible* from the right.
|
||||
- In the bottom row, the middle `5` is *visible*, but the `3` and `4`
|
||||
are not.
|
||||
|
||||
With 16 trees visible on the edge and another 5 visible in the interior,
|
||||
a total of `21` trees are visible in this arrangement.
|
||||
|
||||
Consider your map; *how many trees are visible from outside the grid?*
|
||||
|
||||
Your puzzle answer was `1690`.
|
||||
|
||||
The first half of this puzzle is complete! It provides one gold star: \*
|
||||
|
||||
## \-\-- Part Two \-\-- {#part2}
|
||||
|
||||
Content with the amount of tree cover available, the Elves just need to
|
||||
know the best spot to build their tree house: they would like to be able
|
||||
to see a lot of *trees*.
|
||||
|
||||
To measure the viewing distance from a given tree, look up, down, left,
|
||||
and right from that tree; stop if you reach an edge or at the first tree
|
||||
that is the same height or taller than the tree under consideration. (If
|
||||
a tree is right on the edge, at least one of its viewing distances will
|
||||
be zero.)
|
||||
|
||||
The Elves don\'t care about distant trees taller than those found by the
|
||||
rules above; the proposed tree house has large
|
||||
[eaves](https://en.wikipedia.org/wiki/Eaves) to keep it
|
||||
dry, so they wouldn\'t be able to see higher than the tree house anyway.
|
||||
|
||||
In the example above, consider the middle `5` in the second row:
|
||||
|
||||
30373
|
||||
25512
|
||||
65332
|
||||
33549
|
||||
35390
|
||||
|
||||
- Looking up, its view is not blocked; it can see `1` tree (of height
|
||||
`3`).
|
||||
- Looking left, its view is blocked immediately; it can see only `1`
|
||||
tree (of height `5`, right next to it).
|
||||
- Looking right, its view is not blocked; it can see `2` trees.
|
||||
- Looking down, its view is blocked eventually; it can see `2` trees
|
||||
(one of height `3`, then the tree of height `5` that blocks its
|
||||
view).
|
||||
|
||||
A tree\'s *scenic score* is found by *multiplying together* its viewing
|
||||
distance in each of the four directions. For this tree, this is `4`
|
||||
(found by multiplying `1 * 1 * 2 * 2`).
|
||||
|
||||
However, you can do even better: consider the tree of height `5` in the
|
||||
middle of the fourth row:
|
||||
|
||||
30373
|
||||
25512
|
||||
65332
|
||||
33549
|
||||
35390
|
||||
|
||||
- Looking up, its view is blocked at `2` trees (by another tree with a
|
||||
height of `5`).
|
||||
- Looking left, its view is not blocked; it can see `2` trees.
|
||||
- Looking down, its view is also not blocked; it can see `1` tree.
|
||||
- Looking right, its view is blocked at `2` trees (by a massive tree
|
||||
of height `9`).
|
||||
|
||||
This tree\'s scenic score is `8` (`2 * 2 * 1 * 2`); this is the ideal
|
||||
spot for the tree house.
|
||||
|
||||
Consider each tree on your map. *What is the highest scenic score
|
||||
possible for any tree?*
|
||||
|
||||
Answer:
|
||||
|
||||
Although it hasn\'t changed, you can still [get your puzzle
|
||||
input](8/input).
|
||||
|
||||
@@ -0,0 +1,155 @@
|
||||
#!/bin/python3
|
||||
import sys,time,re
|
||||
from pprint import pprint
|
||||
sys.path.insert(0, '../../')
|
||||
from fred import list2int,get_re,nprint,lprint,loadFile,nprint,get_value_in_direction,grid_valid,toGrid,addTuples
|
||||
start_time = time.time()
|
||||
|
||||
input_f = 'test'
|
||||
|
||||
#########################################
|
||||
# #
|
||||
# Part 1 #
|
||||
# #
|
||||
#########################################
|
||||
def part1():
|
||||
grid = toGrid(input_f)
|
||||
nprint(grid)
|
||||
|
||||
directions = {
|
||||
'up': (-1, 0),
|
||||
'down': (1, 0),
|
||||
'left': (0, -1),
|
||||
'right': (0, 1),
|
||||
}
|
||||
|
||||
visible = []
|
||||
for r,row in enumerate(grid):
|
||||
for c,col in enumerate(row):
|
||||
if r == 0 or r == len(grid)-1 or c == 0 or c == len(row)-1:
|
||||
visible.append((r,c))
|
||||
else:
|
||||
#print(r,c)
|
||||
cur = get_value_in_direction(grid,(r,c))
|
||||
|
||||
x = []
|
||||
test = {}
|
||||
length = 0
|
||||
notVisible = False
|
||||
(nr,nc) = (r,c)
|
||||
#print((r,c),cur)
|
||||
for d in directions.keys():
|
||||
#print(d)
|
||||
if d == 'up':
|
||||
length = r
|
||||
if d == 'down':
|
||||
length = len(grid)-r-1
|
||||
if d == 'left':
|
||||
length = c
|
||||
if d == 'right':
|
||||
length = len(row)-c-1
|
||||
new = get_value_in_direction(grid,(nr,nc),d,length,'list')
|
||||
|
||||
if int(max(new)) >= int(cur):
|
||||
test[d] = 'hidden'
|
||||
else:
|
||||
test[d] = 'visible'
|
||||
# while notVisible:
|
||||
# print((r,c),d,(nr,nc))
|
||||
# new = get_value_in_direction(grid,(nr,nc),d)
|
||||
# #print(new,(nr,nc))
|
||||
# if new is not None:
|
||||
# if cur > int(new) :
|
||||
# print(cur,'>',new)
|
||||
# notVisible = False
|
||||
# (nr,nc) = addTuples((nr,nc),directions[d])
|
||||
# if not grid_valid(nr,nc,grid):
|
||||
# break
|
||||
# nprint(grid,(r,c),str(cur),positions=visible)
|
||||
# input()
|
||||
#if not notVisible:
|
||||
# visible.append((r,c))
|
||||
|
||||
#print((r,c),test)
|
||||
#nprint(grid,(r,c),cur)
|
||||
if 'visible' in test.values():
|
||||
visible.append((r,c))
|
||||
#print(x)
|
||||
#input()
|
||||
nprint(grid,positions=visible)
|
||||
return len(visible)
|
||||
|
||||
start_time = time.time()
|
||||
#print('Part 1:',part1(), '\t\t', round((time.time() - start_time)*1000), 'ms')
|
||||
|
||||
|
||||
#########################################
|
||||
# #
|
||||
# Part 2 #
|
||||
# #
|
||||
#########################################
|
||||
def part2():
|
||||
grid = toGrid(input_f)
|
||||
nprint(grid)
|
||||
|
||||
directions = {
|
||||
'up': (-1, 0),
|
||||
'down': (1, 0),
|
||||
'left': (0, -1),
|
||||
'right': (0, 1),
|
||||
}
|
||||
|
||||
visible = []
|
||||
for r,row in enumerate(grid):
|
||||
for c,col in enumerate(row):
|
||||
if r == 0 or r == len(grid)-1 or c == 0 or c == len(row)-1:
|
||||
visible.append((r,c))
|
||||
else:
|
||||
#print(r,c)
|
||||
cur = get_value_in_direction(grid,(r,c))
|
||||
|
||||
x = []
|
||||
test = {}
|
||||
length = 0
|
||||
score = 0
|
||||
view_distance = 0
|
||||
notVisible = False
|
||||
(nr,nc) = (r,c)
|
||||
print((r,c),cur)
|
||||
for d in directions.keys():
|
||||
#print(d)
|
||||
if d == 'up':
|
||||
length = r
|
||||
if d == 'down':
|
||||
length = len(grid)-r-1
|
||||
if d == 'left':
|
||||
length = c
|
||||
if d == 'right':
|
||||
length = len(row)-c-1
|
||||
new = get_value_in_direction(grid,(nr,nc),d,length,'list')
|
||||
print('->>>',new)
|
||||
if isinstance(new,list):
|
||||
for idx,i in enumerate(new):
|
||||
if int(i) >= int(cur):
|
||||
print(i,cur,idx)
|
||||
view_distance = (idx+1)
|
||||
|
||||
else:
|
||||
if int(new) <= int(cur):
|
||||
print(new,cur,1)
|
||||
view_distance = +1
|
||||
print('View distance',view_distance,d,'<---')
|
||||
#if int(max(new)) >= int(cur):
|
||||
# test[d] = 'hidden'
|
||||
#else:
|
||||
# test[d] = 'visible'
|
||||
nprint(grid,(r,c),cur)
|
||||
input()
|
||||
if 'visible' in test.values():
|
||||
visible.append((r,c))
|
||||
|
||||
nprint(grid,positions=visible)
|
||||
return len(visible)
|
||||
|
||||
start_time = time.time()
|
||||
print('Part 2:',part2(), '\t\t', round((time.time() - start_time)*1000), 'ms')
|
||||
Reference in New Issue
Block a user