Today’s puzzle involved a forest of trees, and evaluating the heights of trees in that forest. For the sake of coding simplicity, the trees are a nice grid, which makes it an easy 2 dimensional matrix. This was my biggest hang up in designing a solution, Because Python handles 2 dimensional matrices as a “list of lists”. Which means often, the x and y coordinates need “flipped” when referenced, which often screws me up. This is because and loops will run down the rows, then the columns, that is, it will run down down the y axis then the x axis.

Technically, I don’t think it actually matters from a programmatic perspective, but it makes it tricky to logic out.

Otherwise the process is just running up and down in either direction to see if any tree is taller than the target tree. If it is not, then the tree is “Visible”. A tree only needs to be “Visible” from one of the 4 cardinal directions, to be counted.

The only other tricky part for part 1, is that all of the sides are considered “visible. The first instinct is to just take the length of the sides times 4, and add it to the total, except this means counting the corners twice. So you either need to subtract 4 or take the length-1 times 4.

Part 2 game me a fair amount of trouble, and after a lot of troubleshooting, it ended up being kind of a stupid issue. You need to check each tree, to see how many trees they can see, before hitting a taller tree (that they can’t see beyond). I left them in, but my troubleshooting is all those commented out print statements

# print(tree_grid[y][i] + " " + tree_grid[y][x])

Because I took the sample data, and checked to make sure it was stepping through each set properly. One by one, for each cardinal direction. And I was close and then not close, and I tried adding +1 to ranges and maybe I need this to start here instead of there an finally I found I was doing <= instead of just <, which was giving me bad results. I could have sworn the puzzle said they can see trees past those of equal height, but nope. Removing those equals signs fixed it.

Also, I am sure this code could be refactored down to be less repetitious, but it works fine now, no need to break it. I actually started working through it in a more compact method that used one function for each direction but I started to get loss so I just expanded it out.

with open("Day08Input.txt") as file:
    data = file.read()

tree_grid = data.split('\n')

leny = len(tree_grid)-1

tall_total = 0

def check_west(x,y):
    for each in range(0, x):
        if tree_grid[y][x] <= tree_grid[y][each]:
            return False
    return True

def check_east(x,y):
    for each in range(x+1,len(tree_grid)):
        if tree_grid[y][x] <= tree_grid[y][each]:
            return False
    return True

def check_north(x,y):
    for each in range(0, y):
        if tree_grid[y][x] <= tree_grid[each][x]:
            return False
    return True

def check_south(x,y):
    for each in range(y + 1, len(tree_grid)):
        if tree_grid[y][x] <= tree_grid[each][x]:
            return False
    return True

def scenic_score(x,y):
    east_score = 0
    west_score = 0
    north_score = 0
    south_score = 0

    for i in range(x+1,len(tree_grid)):
        if tree_grid[y][i] < tree_grid[y][x]:
            east_score += 1
        else:
            east_score += 1
            break
    for i in range(y+1, len(tree_grid)):
        if tree_grid[i][x] < tree_grid[y][x]:
            # print(tree_grid[i][x] + " " + tree_grid[y][x])
            south_score += 1
        else:
            # print(tree_grid[i][x] + " " + tree_grid[y][x])
            south_score += 1
            break
    for i in reversed(range(0, x)):
        if tree_grid[y][i] < tree_grid[y][x]:
            # print(tree_grid[y][i] + " " + tree_grid[y][x])
            west_score += 1
        else:
            # print(tree_grid[y][i] + " " + tree_grid[y][x])
            west_score += 1
            break
    for i in reversed(range(0, y)):
        if tree_grid[i][x] < tree_grid[y][x]:
            # print(tree_grid[i][x] + " " + tree_grid[y][x])
            north_score += 1
        else:
            # print(tree_grid[i][x] + " " + tree_grid[y][x])
            north_score += 1
            break
    # print(f"{north_score} * {west_score} * {east_score} * {south_score}")
    return east_score * south_score * west_score * north_score

high_score = 0
for y in range(1, len(tree_grid[0])-1):
    for x in range(1, len(tree_grid)-1):
        if check_west(x,y) or check_east(x,y) or check_north(x,y) or check_south(x,y):
            tall_total += 1
        score = scenic_score(x,y)
        if score > high_score:
            high_score = score


print(tall_total+((len(tree_grid))*4)-4)
# 2007 High
# 1991 High
# 1859 Correct
print(high_score)
# 332640