Refactor python solutions for 2022 Day 8

This commit is contained in:
hedy 2022-12-08 15:12:56 +08:00
parent 3699ff3c6a
commit ef796df0e0
Signed by: hedy
GPG Key ID: B51B5A8D1B176372
2 changed files with 98 additions and 64 deletions

72
2022/08/python-long.py Normal file
View File

@ -0,0 +1,72 @@
from aocd import submit
with open(0) as f:
# tuple of tree heights, for each line, in a list
# [(1, 2, 3), (4, 5, 6), ...]
lines = [tuple(map(int, line)) for line in f.read().strip().splitlines()]
def viewdist(current: int, view: list[int], reverse=False) -> int:
"""Calculate the viewing distance of a tree
Parameters:
current (int) Height of current tree in question
view (list(int)) List of heights of trees from current view
reverse (bool) Whether to reverse the `view` list when checking
(used for viewing left and top)
Returns:
The number of trees visible from this view.
"""
n = 0
iterator = view
if reverse: iterator = reversed(iterator)
for i in iterator:
n += 1
if current <= i:
break
return n
# Part 1
# Number of trees visible from at least 1 side
# Edges = left/right-most trees + top/bottom-most trees
# Basically = perimeter - 4 (corners repeated)
n_visible = len(lines)*2 + (len(lines[0])-2)*2 # Edges
# Part 2
# Edge trees excluded in part 2 score summation, as at least 1 of the
# view dists =0, hence their scores would be 0
max_score = 0
# For every row excluding first and last
for i in range(1, len(lines)-1):
row = lines[i]
# For every column excluding first and last
for j in range(1, len(row)-1):
current = row[j]
# List of tree heights in 4 directions excluding current one
# top, left, bottom, right: like in CSS :D
top = [ l[j] for l in lines[:i] ]
left = row[:j]
bottom = [ l[j] for l in lines[i+1:] ]
right = row[j+1:]
# Part 1
if (current > max(left) or current > max(right) or
current > max(top) or current > max(bottom)):
n_visible += 1
# Part 2
score = 1
for view in left, top:
vd = viewdist(current, view, reverse=True)
score *= vd
for view in right, bottom:
vd = viewdist(current, view, reverse=False)
score *= vd
# Find the highest score (max_score initialized to 0)
if score > max_score:
max_score = score
print(n_visible)
submit(n_visible, "a", 8, 2022)
print(max_score)
submit(max_score, "b", 8, 2022)

View File

@ -1,72 +1,34 @@
from aocd import submit
with open(0) as f:
# tuple of tree heights, for each line, in a list
# [(1, 2, 3), (4, 5, 6), ...]
lines = [tuple(map(int, line)) for line in f.read().strip().splitlines()]
L = [tuple(map(int, l)) for l in f.read().strip().splitlines()]
def viewdist(current: int, view: list[int], reverse=False) -> int:
"""Calculate the viewing distance of a tree
Parameters:
current (int) Height of current tree in question
view (list(int)) List of heights of trees from current view
reverse (bool) Whether to reverse the `view` list when checking
(used for viewing left and top)
Returns:
The number of trees visible from this view.
"""
n = 0
iterator = view
if reverse: iterator = reversed(iterator)
for i in iterator:
def vd(cur, v, rev=False):
n = 0; it = v
for i in (reversed(it) if rev else it):
n += 1
if current <= i:
break
if cur <= i: break
return n
n = len(L)*2 + (len(L[0])-2)*2
m = 0
# Part 1
# Number of trees visible from at least 1 side
# Edges = left/right-most trees + top/bottom-most trees
# Basically = perimeter - 4 (corners repeated)
n_visible = len(lines)*2 + (len(lines[0])-2)*2 # Edges
# Part 2
# Edge trees excluded in part 2 score summation, as at least 1 of the
# view dists =0, hence their scores would be 0
max_score = 0
# For every row excluding first and last
for i in range(1, len(lines)-1):
row = lines[i]
# For every column excluding first and last
for i in range(1, len(L)-1):
row = L[i]
for j in range(1, len(row)-1):
current = row[j]
# List of tree heights in 4 directions excluding current one
# top, left, bottom, right: like in CSS :D
top = [ l[j] for l in lines[:i] ]
left = row[:j]
bottom = [ l[j] for l in lines[i+1:] ]
right = row[j+1:]
# Part 1
if (current > max(left) or current > max(right) or
current > max(top) or current > max(bottom)):
n_visible += 1
# Part 2
score = 1
for view in left, top:
vd = viewdist(current, view, reverse=True)
score *= vd
for view in right, bottom:
vd = viewdist(current, view, reverse=False)
score *= vd
# Find the highest score (max_score initialized to 0)
if score > max_score:
max_score = score
cur = row[j]
top = [ l[j] for l in L[:i] ]
lef = row[:j]
bot = [ l[j] for l in L[i+1:] ]
rgt = row[j+1:]
if (cur > max(lef) or cur > max(rgt) or
cur > max(top) or cur > max(bot)):
n += 1
s = 1
for v in lef, top:
s *= vd(cur, v, True)
for v in rgt, bot:
s *= vd(cur, v, False)
if s > m:
m = s
print(n_visible)
submit(n_visible, "a", 8, 2022)
print(max_score)
submit(max_score, "b", 8, 2022)
print(n)
print(m)