From 7ed9dc3ccdcf0b48ec244ce5a73f4c5d1b69244f Mon Sep 17 00:00:00 2001 From: Luc Rubio Date: Sun, 8 Dec 2024 21:26:22 +0100 Subject: [PATCH] AoC 2024 day 8 part 1 --- aoc2024/src/day08/__init__.py | 0 aoc2024/src/day08/python/__init__.py | 0 aoc2024/src/day08/python/solution.py | 50 ++++++++++++++++++++++ aoc2024/test/day08/__init__.py | 0 aoc2024/test/day08/python/__init__.py | 0 aoc2024/test/day08/python/example1.txt | 12 ++++++ aoc2024/test/day08/python/input.txt | 50 ++++++++++++++++++++++ aoc2024/test/day08/python/test_solution.py | 32 ++++++++++++++ 8 files changed, 144 insertions(+) create mode 100644 aoc2024/src/day08/__init__.py create mode 100644 aoc2024/src/day08/python/__init__.py create mode 100644 aoc2024/src/day08/python/solution.py create mode 100644 aoc2024/test/day08/__init__.py create mode 100644 aoc2024/test/day08/python/__init__.py create mode 100644 aoc2024/test/day08/python/example1.txt create mode 100644 aoc2024/test/day08/python/input.txt create mode 100644 aoc2024/test/day08/python/test_solution.py diff --git a/aoc2024/src/day08/__init__.py b/aoc2024/src/day08/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/aoc2024/src/day08/python/__init__.py b/aoc2024/src/day08/python/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/aoc2024/src/day08/python/solution.py b/aoc2024/src/day08/python/solution.py new file mode 100644 index 0000000..8e88a18 --- /dev/null +++ b/aoc2024/src/day08/python/solution.py @@ -0,0 +1,50 @@ +# Copyright 2024 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +from typing import Sequence +from collections import defaultdict + +_NO_ANTENNA = '.' + +# Antenas +type Pos = tuple[int, int] + +def _find_antennas(city_map: Sequence[str]) -> dict[str, set[Pos]]: + """Finds antenna locations and groups them by frequency. + Frequency is represented by character, for example 'a'.""" + antennas = defaultdict(set) + for y in range(len(city_map)): + for x in range(len(city_map[0])): + value = city_map[y][x] + if value != _NO_ANTENNA: + antennas[value].add((y, x)) + return antennas + + +def count_antinodes(city_map: Sequence[str]) -> int: + """Counts the antinodes resulting from antennas in the city.""" + city_width = len(city_map[0]) + city_height = len(city_map) + antennas: dict[chr, set[Pos]] = _find_antennas(city_map) + antinode_positions: set[Pos] = set() + for positions in antennas.values(): + for curr_pos in positions: + for other_pos in positions: + if curr_pos == other_pos: + continue # Skip same antenna. + distance = (other_pos[0] - curr_pos[0], other_pos[1] - curr_pos[1]) + antinode_pos = (other_pos[0] + distance[0], other_pos[1] + distance[1]) + if 0 <= antinode_pos[0] < city_height and 0 <= antinode_pos[1] < city_width: + # Antinode is within city bounds + antinode_positions.add(antinode_pos) + return len(antinode_positions) \ No newline at end of file diff --git a/aoc2024/test/day08/__init__.py b/aoc2024/test/day08/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/aoc2024/test/day08/python/__init__.py b/aoc2024/test/day08/python/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/aoc2024/test/day08/python/example1.txt b/aoc2024/test/day08/python/example1.txt new file mode 100644 index 0000000..de0f909 --- /dev/null +++ b/aoc2024/test/day08/python/example1.txt @@ -0,0 +1,12 @@ +............ +........0... +.....0...... +.......0.... +....0....... +......A..... +............ +............ +........A... +.........A.. +............ +............ \ No newline at end of file diff --git a/aoc2024/test/day08/python/input.txt b/aoc2024/test/day08/python/input.txt new file mode 100644 index 0000000..9fc6357 --- /dev/null +++ b/aoc2024/test/day08/python/input.txt @@ -0,0 +1,50 @@ +.....wV....q.....................................n +.......w......q.h.....Vn.........................D +............w.S..G.....................DT......... +......S........h......e..T.....y......D........... +......m.......Ae.......T........o................. +....m....S........................................ +...m..........................n........8.......... +.........2...G......................n............. +..2........V.......h................Q............. +............................o..................... +.Z......I..U....e...u.....G....o.................. +...N..G.........................................y. +.....I............q.......h...................s... +......U........qI....o.V..Rz........8........k.... +......d.Z.........................R.......8y...... +.........e..............T.....l................... +.......2.........................u...R............ +.....d.............................Q.............. +...................v.....................s.Q....M. +........2..........4.....................8..7.k... +...........x..N..................A..........k..... +...........ZN...........v...............K......... +...d.......N.....................Ky.6............. +...........................l6..................... +....L....g.................4.......k..K.......0... +..............L...........4R................s..... +U......r..............H.4......................... +.......U.............a.......H.............u...... +......xY...............l.......................... +...................................6..u........... +........Y......L......l............0.............. +......9..L...........A.....v..HEa........K........ +..................v........6.EX.............z..... +d..Y.............m......A......................... +......................a.i......M...........z...... +...................g.......................0...... +...............................H.........i........ +..........3................W........E...i...0..... +.................t.a....g.................5....... +.r...t...........................7.....5.......... +....................................7....5........ +....................g.Y...wMz..................... +9..........O....3................W.7..E..XD...1... +t..............3.x.....9..........W.M............. +...9............W................................. +Z.............x................X.i......5......... +...........3.....................................1 +...................O.......s....X................. +..............r................................... +..........................O.................1..... \ No newline at end of file diff --git a/aoc2024/test/day08/python/test_solution.py b/aoc2024/test/day08/python/test_solution.py new file mode 100644 index 0000000..f321eb0 --- /dev/null +++ b/aoc2024/test/day08/python/test_solution.py @@ -0,0 +1,32 @@ +# Copyright 2024 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +import unittest + +from common.python3.AdventOfCodeTestCase import AdventOfCodeTestCase +from aoc2024.src.day08.python.solution import count_antinodes + + +class TestDay08Solution(AdventOfCodeTestCase): + def __init__(self, *args, **kwargs): + (super(TestDay08Solution, self).__init__(__file__, *args, **kwargs)) + + def test_part1_withExample_counts(self): + self.assertEqual(14, count_antinodes(self.examples[0])) + + def test_part1_withPuzzleInput_counts(self): + self.assertEqual(327, count_antinodes(self.input)) + + +if __name__ == '__main__': + unittest.main()