From 95c244102fdc06268e0ca1a4227148d94081de8a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Anders=20Ytterstr=C3=B6m?= Date: Thu, 9 Dec 2021 11:00:28 +0100 Subject: [PATCH] Solve 2021:9 "Smoke Basin" part 2 Yet again I got stuck in the common AOC trap: The example input worked, but not the actual input. 2 things got me stuck. > The size of a basin is the number of locations within the basin, including the low point. The example above has four basins. 1. I missed the obvious part to only check the low points. 2. Based on the example, I asumed that the adjacent locations would increase by one to count. This is wrong: What matters is that their height is a larger value. Way too long time for a simple problem. Never read puzzles sloppy. --- 2021-python/solutions/day_09.py | 46 ++++++++++++++++++++++++++++---- 2021-python/tests/test_day_09.py | 4 +-- 2 files changed, 43 insertions(+), 7 deletions(-) diff --git a/2021-python/solutions/day_09.py b/2021-python/solutions/day_09.py index 451805c..a09480c 100644 --- a/2021-python/solutions/day_09.py +++ b/2021-python/solutions/day_09.py @@ -1,4 +1,5 @@ from solutions import BaseSolution +from typing import List, Tuple class Solution(BaseSolution): @@ -11,7 +12,37 @@ class Solution(BaseSolution): return [[int(c) for c in r] for r in data.split()] def solve(self, puzzle_input): - lp = 0 + lp = self._lowpoints(puzzle_input) + return sum(lpv[1] + 1 for lpv in lp) + + def solve_again(self, puzzle_input): + offsets = (-1, 0), (0, 1), (1, 0), (0, -1) + my = len(puzzle_input) + mx = len(puzzle_input[0]) + + basins = [] + + def basin(y, x, value, seen=set()): + if value < 9: + seen.add((value, (y, x))) + for oy, ox in offsets: + sy = y + oy + sx = x + ox + if any((sy < 0, sx < 0, sy >= my, sx >= mx)): + continue + s = puzzle_input[sy][sx] + if s > value: + seen = basin(sy, sx, s, seen) + return seen + + for lp, value in self._lowpoints(puzzle_input): + y, x = lp + basins.append(len(basin(y, x, value, set()))) + p1, p2, p3, *_ = sorted(basins, reverse=True) + return p1 * p2 * p3 + + def _lowpoints(self, puzzle_input): + lp = [] lpi = len(puzzle_input) for v, row in enumerate(puzzle_input): lr = len(row) @@ -22,13 +53,18 @@ class Solution(BaseSolution): s3 = puzzle_input[v - 1][i] if v > 0 else 11 s4 = puzzle_input[v + 1][i] if v < lpi - 1 else 11 if all(x < s for s in [s1, s2, s3, s4]): - lp += 1 + x + lp.append(((v, i), x)) return lp - def solve_again(self, puzzle_input): - return True - if __name__ == "__main__": solution = Solution() solution.show_results() + +""" +2199943210 +3987894921 +9856789892 +8767896789 +9899965678 +""" diff --git a/2021-python/tests/test_day_09.py b/2021-python/tests/test_day_09.py index 69e0225..118b12d 100644 --- a/2021-python/tests/test_day_09.py +++ b/2021-python/tests/test_day_09.py @@ -29,8 +29,8 @@ class Day09TestCase(unittest.TestCase): def test_solve_first_part(self): assert self.solution.solve(self.puzzle_input) == 15 - # def test_solve_second_part(self): - # assert self.solution.solve_again(self.puzzle_input) == True + def test_solve_second_part(self): + assert self.solution.solve_again(self.puzzle_input) == 9 * 14 * 9 # 891684 if __name__ == "__main__":