day08 sligtly improved

This commit is contained in:
Ruediger Ludwig 2022-12-08 20:43:40 +01:00
parent 64e3eb063c
commit bb83caec1d
2 changed files with 21 additions and 24 deletions

View file

@ -7,63 +7,60 @@ day_num = 8
def part1(lines: Iterator[str]) -> int: def part1(lines: Iterator[str]) -> int:
return Trees.parse(lines).count_visible() return Forest.parse(lines).count_visible_trees()
def part2(lines: Iterator[str]) -> int: def part2(lines: Iterator[str]) -> int:
return Trees.parse(lines).max_scenic_score() return Forest.parse(lines).max_scenic_score()
@dataclass(slots=True) @dataclass(slots=True)
class Trees: class Forest:
trees: list[list[int]] trees: list[list[int]]
width: int width: int
height: int height: int
@staticmethod @staticmethod
def parse(lines: Iterator[str]) -> Trees: def parse(lines: Iterator[str]) -> Forest:
trees = [[int(tree) for tree in line] for line in lines] trees = [[int(tree) for tree in line] for line in lines]
return Trees(trees, len(trees[0]), len(trees)) return Forest(trees, len(trees[0]), len(trees))
def count_visible(self) -> int: def count_visible_trees(self) -> int:
visible = [[True] * self.width] visible: set[tuple[int, int]] = set()
for _ in range(self.height - 2):
visible += [[True] + [False] * (self.width - 2) + [True]]
visible += [[True] * self.width]
# From Up # From Above
mx = self.trees[0].copy() mx = self.trees[0].copy()
for y in range(1, self.height - 1): for y in range(1, self.height - 1):
for x in range(1, self.width - 1): for x in range(1, self.width - 1):
if self.trees[y][x] > mx[x]: if self.trees[y][x] > mx[x]:
mx[x] = self.trees[y][x] mx[x] = self.trees[y][x]
visible[y][x] = True visible.add((x, y))
# From Down # From Below
mx = self.trees[-1].copy() mx = self.trees[-1].copy()
for y in range(self.height - 2, 0, -1): for y in range(self.height - 2, 0, -1):
for x in range(1, self.width - 1): for x in range(1, self.width - 1):
if self.trees[y][x] > mx[x]: if self.trees[y][x] > mx[x]:
mx[x] = self.trees[y][x] mx[x] = self.trees[y][x]
visible[y][x] = True visible.add((x, y))
# From Left # From Left
mx = [self.trees[y][0] for y in range(self.height)] mx = [row[0] for row in self.trees]
for x in range(1, self.width - 1): for x in range(1, self.width - 1):
for y in range(1, self.height - 1): for y in range(1, self.height - 1):
if self.trees[y][x] > mx[y]: if self.trees[y][x] > mx[y]:
mx[y] = self.trees[y][x] mx[y] = self.trees[y][x]
visible[y][x] = True visible.add((x, y))
# From Right # From Right
mx = [self.trees[y][-1] for y in range(self.height)] mx = [row[-1] for row in self.trees]
for x in range(self.width - 2, 0, -1): for x in range(self.width - 2, 0, -1):
for y in range(1, self.height - 1): for y in range(1, self.height - 1):
if self.trees[y][x] > mx[y]: if self.trees[y][x] > mx[y]:
mx[y] = self.trees[y][x] mx[y] = self.trees[y][x]
visible[y][x] = True visible.add((x, y))
return sum(1 for y in range(self.height) for x in range(self.width) if visible[y][x]) return len(visible) + 2 * (self.width + self.height - 2)
def max_scenic_score(self) -> int: def max_scenic_score(self) -> int:
max_score = 0 max_score = 0

View file

@ -1,6 +1,6 @@
from advent.common import utils from advent.common import utils
from .solution import Trees, day_num, part1, part2 from .solution import Forest, day_num, part1, part2
def test_part1(): def test_part1():
@ -20,26 +20,26 @@ def test_part2():
def test_visible(): def test_visible():
data = utils.read_data(day_num, 'test01.txt') data = utils.read_data(day_num, 'test01.txt')
expected = 21 expected = 21
result = Trees.parse(data).count_visible() result = Forest.parse(data).count_visible_trees()
assert result == expected assert result == expected
def test_distance(): def test_distance():
data = utils.read_data(day_num, 'test01.txt') data = utils.read_data(day_num, 'test01.txt')
expected = 4 expected = 4
result = Trees.parse(data).single_scenic_score(2, 1) result = Forest.parse(data).single_scenic_score(2, 1)
assert result == expected assert result == expected
def test_distance2(): def test_distance2():
data = utils.read_data(day_num, 'test01.txt') data = utils.read_data(day_num, 'test01.txt')
expected = 8 expected = 8
result = Trees.parse(data).single_scenic_score(2, 3) result = Forest.parse(data).single_scenic_score(2, 3)
assert result == expected assert result == expected
def test_max_distance(): def test_max_distance():
data = utils.read_data(day_num, 'test01.txt') data = utils.read_data(day_num, 'test01.txt')
expected = 8 expected = 8
result = Trees.parse(data).max_scenic_score() result = Forest.parse(data).max_scenic_score()
assert result == expected assert result == expected