// Solutions to the Advent Of Code 2024. // Copyright (C) 2025 Stefan Müller // // This program is free software: you can redistribute it and/or modify it under // the terms of the GNU General Public License as published by the Free Software // Foundation, either version 3 of the License, or (at your option) any later // version. // // This program is distributed in the hope that it will be useful, but WITHOUT // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS // FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. // // You should have received a copy of the GNU General Public License along with // this program. If not, see . #include const std::string ResonantCollinearity::getPuzzleName() const { return "Resonant Collinearity"; } const int ResonantCollinearity::getPuzzleDay() const { return 8; } void ResonantCollinearity::finish() { Grid antinodeGrid1{ lines.size(), lines[0].size() }; antinodeGrid1.fill(false); Grid antinodeGrid2{ lines.size(), lines[0].size() }; antinodeGrid2.fill(false); for (int j = 0; j < lines.size(); j++) { for (int i = 0; i < lines[j].size(); i++) { if (lines[j][i] != getEmptyChar()) { addNewAntenna(antinodeGrid1, antinodeGrid2, { i, j }); } } } } constexpr char ResonantCollinearity::getEmptyChar() { return '.'; } void ResonantCollinearity::addNewAntenna(Grid& antinodeGrid1, Grid& antinodeGrid2, Point2&& newPosition) { const auto [it, success] = antennas_.insert({ getCharAt(newPosition), { newPosition } }); if (!success) { // Adds the new antenna position itself as an antinode for part 2. if (it->second.size() == 1) { addNewAntinode(antinodeGrid2, it->second.front(), part2); } addNewAntinode(antinodeGrid2, newPosition, part2); // Adds antinodes for all pairs of the new antenna position and each of the already processed other antenna // positions with the same frequency. for (const auto& other : it->second) { Point2 diff = newPosition - other; findNewAntinodes(antinodeGrid1, antinodeGrid2, newPosition + diff, diff); diff = -diff; findNewAntinodes(antinodeGrid1, antinodeGrid2, other + diff, diff); } it->second.push_back(newPosition); } } void ResonantCollinearity::findNewAntinodes(Grid& antinodeGrid1, Grid& antinodeGrid2, Point2&& start, const Point2& increment) { if (isInBounds(start)) { addNewAntinode(antinodeGrid1, start, part1); addNewAntinode(antinodeGrid2, start, part2); start += increment; while (isInBounds(start)) { addNewAntinode(antinodeGrid2, start, part2); start += increment; } } } void ResonantCollinearity::addNewAntinode(Grid& antinodeGrid, Point2& newPosition, long long int& count) { if (!antinodeGrid[newPosition.y][newPosition.x]) { antinodeGrid[newPosition.y][newPosition.x] = true; count++; } }