diff --git a/tests/y_2022/test_2022_day8.py b/tests/y_2022/test_2022_day8.py new file mode 100644 index 0000000..988ac12 --- /dev/null +++ b/tests/y_2022/test_2022_day8.py @@ -0,0 +1,22 @@ +from __future__ import annotations + +from unittest.mock import mock_open, patch + +from y_2022.common import load_input +from y_2022.day8 import Day + +with patch("builtins.open", mock_open(read_data="01\n23")): + day = Day() + + +def test__preprocess_input(): + day._input_data = [["01", "23"]] + day._preprocess_input() + assert day._Day__grid == {(0, 0): "0", (0, 1): "1", (1, 0): "2", (1, 1): "3"} + + +def test_complete(): + day._input_data = load_input(8, 1) + day._preprocess_input() + assert day._calculate_1() == 21 + assert day._calculate_2() == 8 diff --git a/y_2022/day8.py b/y_2022/day8.py new file mode 100644 index 0000000..e649b08 --- /dev/null +++ b/y_2022/day8.py @@ -0,0 +1,100 @@ +from .common import AoCDay + + +class Day(AoCDay): + def __init__(self, test=0): + super().__init__(__name__.split(".")[1].replace("day", ""), test) + + def _preprocess_input(self): + self.__input_data = self._input_data[0] + self.__grid = {} + x = self.__input_data + for c, i in enumerate(x): + for d, j in enumerate(i): + self.__grid[(c, d)] = j + self.max_w = len(x) + self.max_h = len(x[0]) + + def is_visible(self, i): + if i[0] in [0, self.max_w - 1]: + return True + if i[1] in [0, self.max_h - 1]: + return True + + # visible from Top + visible_Top = True + for j in range(0, i[0]): + if self.__grid[(j, i[1])] >= self.__grid[(i)]: + visible_Top = False + + # visible from Left + visible_Left = True + for j in range(0, i[1]): + if self.__grid[(i[0], j)] >= self.__grid[(i)]: + visible_Left = False + + # visible from Bottom + visible_Bottom = True + for j in range(i[0] + 1, self.max_h): + if self.__grid[(j, i[1])] >= self.__grid[(i)]: + visible_Bottom = False + + # visible from Right + visible_Right = True + for j in range(i[1] + 1, self.max_w): + if self.__grid[(i[0], j)] >= self.__grid[(i)]: + visible_Right = False + + is_visible = visible_Top or visible_Left or visible_Bottom or visible_Right + return is_visible + + def viewing_score(self, i): + if i[0] in [0, self.max_w - 1]: + return 0 + if i[1] in [0, self.max_h - 1]: + return 0 + + # visible top + score_Top = 0 + for j in range(i[0] - 1, -1, -1): + score_Top += 1 + if self.__grid[(j, i[1])] >= self.__grid[i]: + break + + # visible left + score_Left = 0 + for j in range(i[1] - 1, -1, -1): + score_Left += 1 + if self.__grid[(i[0], j)] >= self.__grid[(i)]: + break + + # visible from Bottom + score_Bottom = 0 + for j in range(i[0] + 1, self.max_h): + score_Bottom += 1 + if self.__grid[(j, i[1])] >= self.__grid[i]: + break + + # visible from Right + score_Right = 0 + for j in range(i[1] + 1, self.max_w): + score_Right += 1 + if self.__grid[(i[0], j)] >= self.__grid[(i)]: + break + + return score_Top * score_Left * score_Bottom * score_Right + + def _calculate_1(self): + t = 0 + for i in self.__grid: + if self.is_visible(i): + t += 1 + return t + + def _calculate_2(self): + t = 0 + for i in self.__grid: + x = self.viewing_score(i) + if x > t: + t = x + return t diff --git a/y_2022/input_day8_test.txt b/y_2022/input_day8_test.txt new file mode 100644 index 0000000..16d6fbd --- /dev/null +++ b/y_2022/input_day8_test.txt @@ -0,0 +1,5 @@ +30373 +25512 +65332 +33549 +35390