diff --git a/tests/y_2022/test_2022_day0.py b/tests/y_1900/test_1900_day0.py similarity index 93% rename from tests/y_2022/test_2022_day0.py rename to tests/y_1900/test_1900_day0.py index e0b4a2e..854ca02 100644 --- a/tests/y_2022/test_2022_day0.py +++ b/tests/y_1900/test_1900_day0.py @@ -2,7 +2,7 @@ from unittest.mock import mock_open, patch -from y_2022.day0 import Day +from y_1900.day0 import Day with patch("builtins.open", mock_open(read_data="0")): day = Day() diff --git a/tests/y_2015/test_2015_day6.py b/tests/y_2015/test_2015_day6.py new file mode 100644 index 0000000..ed76058 --- /dev/null +++ b/tests/y_2015/test_2015_day6.py @@ -0,0 +1,36 @@ +from __future__ import annotations + +from unittest.mock import mock_open, patch + +from y_2015.day6 import Day + +with patch("builtins.open", mock_open(read_data="command 0,0 through 999,999")): + day = Day() + + +def test_calculate_1(): + day._input_data = [["turn on 0,0 through 9,0", "turn off 8,0 through 9,0"]] + day._preprocess_input() + assert day._calculate_1() == 8 + + day._input_data = [["turn off 0,0 through 9,0"]] + day._preprocess_input() + assert day._calculate_1() == 0 + + day._input_data = [["toggle 0,0 through 9,0"]] + day._preprocess_input() + assert day._calculate_1() == 10 + + +def test_calculate_2(): + day._input_data = [["turn on 0,0 through 0,0"]] + day._preprocess_input() + assert day._calculate_2() == 1 + + day._input_data = [["turn off 0,0 through 0,0"]] + day._preprocess_input() + assert day._calculate_2() == 0 + + day._input_data = [["toggle 0,0 through 0,0"]] + day._preprocess_input() + assert day._calculate_2() == 2 diff --git a/y_2022/day0.py b/y_1900/day0.py similarity index 100% rename from y_2022/day0.py rename to y_1900/day0.py diff --git a/y_2015/day3.py b/y_2015/day3.py index 763613f..f6c869a 100644 --- a/y_2015/day3.py +++ b/y_2015/day3.py @@ -5,7 +5,7 @@ from common.aoc import AoCDay -@dataclass() +@dataclass class Position: x: int y: int diff --git a/y_2015/day6.py b/y_2015/day6.py new file mode 100644 index 0000000..02573d0 --- /dev/null +++ b/y_2015/day6.py @@ -0,0 +1,84 @@ +import re +from typing import Dict + +from pydantic.dataclasses import dataclass + +from common.aoc import AoCDay + + +@dataclass +class Instruction: + command: str + start_x: int + start_y: int + end_x: int + end_y: int + + def process(self, grid, actions=None) -> None: + min_x = min(self.start_x, self.end_x) + min_y = min(self.start_y, self.end_y) + max_x = max(self.start_x, self.end_x) + max_y = max(self.start_y, self.end_y) + + for i in range(min_x, max_x + 1): + for j in range(min_y, max_y + 1): + hash = Light.hash_fun(i, j) + if hash not in grid: + grid[hash] = Light(i, j) + light = grid[hash] + light.brightness = actions[self.command](light.brightness) + + +@dataclass +class Light: + x: int + y: int + brightness: int = 0 + + @staticmethod + def hash_fun(x: int, y: int): + return f"x={x};y={y}" + + @property + def hash(self) -> str: + return Light.hash_fun(self.x, self.y) + + +class Day(AoCDay): + def __init__(self, test=0): + super().__init__(__name__, test) + + def _preprocess_input(self): + self.__input_data = [ + Instruction( + *list(re.search(r"(\D*) (\d*),(\d*) through (\d*),(\d*)", i).groups()), + ) + for i in self._input_data[0] + ] + + def _calculate_1(self) -> int: + grid: Dict[str, Light] = {} + + actions = { + "turn on": lambda x: True, + "turn off": lambda x: False, + "toggle": lambda x: not x, + } + for i in self.__input_data: + i.process(grid, actions) + + return sum(i.brightness for i in grid.values()) + + def _calculate_2(self) -> int: + grid: Dict[str, Light] = {} + + actions = { + "turn on": lambda x: x + 1, + "turn off": lambda x: max(x - 1, 0), + "toggle": lambda x: x + 2, + } + + for i in self.__input_data: + i.process(grid, actions) + + return sum(i.brightness for i in grid.values())