Add solution for "Day 8: Resonant Collinearity", part 2
The Point2::operator<() was introduced for set<Point2>, which is not actually required.
This commit is contained in:
@@ -47,11 +47,6 @@ bool Point2::operator!=(const Point2& rhs) const
|
||||
return !(*this == rhs);
|
||||
}
|
||||
|
||||
bool Point2::operator<(const Point2& rhs) const
|
||||
{
|
||||
return x < rhs.x || (x == rhs.x && y < rhs.y);
|
||||
}
|
||||
|
||||
Point2 Point2::operator+(const Point2& rhs) const
|
||||
{
|
||||
return Point2(x + rhs.x, y + rhs.y);
|
||||
|
||||
@@ -29,18 +29,21 @@ const std::string ResonantCollinearity::getInputFileName() const
|
||||
|
||||
void ResonantCollinearity::finish()
|
||||
{
|
||||
Grid<bool> antinodeGrid1{ lines.size(), lines[0].size() };
|
||||
antinodeGrid1.fill(false);
|
||||
Grid<bool> 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({ i, j });
|
||||
addNewAntenna(antinodeGrid1, antinodeGrid2, { i, j });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
part1 = antinodes_.size();
|
||||
}
|
||||
|
||||
constexpr char ResonantCollinearity::getEmptyChar()
|
||||
@@ -48,25 +51,53 @@ constexpr char ResonantCollinearity::getEmptyChar()
|
||||
return '.';
|
||||
}
|
||||
|
||||
void ResonantCollinearity::addNewAntenna(Point2&& newPosition)
|
||||
void ResonantCollinearity::addNewAntenna(Grid<bool>& antinodeGrid1, Grid<bool>& antinodeGrid2, Point2&& newPosition)
|
||||
{
|
||||
const auto [it, success] = antennas_.insert({ getPosition(newPosition), { newPosition } });
|
||||
if (!success)
|
||||
{
|
||||
for (const auto& oldPosition : it->second)
|
||||
// Adds the new antenna position itself as an antinode for part 2.
|
||||
if (it->second.size() == 1)
|
||||
{
|
||||
addNewAntinode(newPosition * 2 - oldPosition);
|
||||
addNewAntinode(oldPosition * 2 - newPosition);
|
||||
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::addNewAntinode(Point2&& newPosition)
|
||||
void ResonantCollinearity::findNewAntinodes(Grid<bool>& antinodeGrid1, Grid<bool>& antinodeGrid2, Point2&& start,
|
||||
const Point2& increment)
|
||||
{
|
||||
if (isInBounds(newPosition))
|
||||
if (isInBounds(start))
|
||||
{
|
||||
antinodes_.insert(newPosition);
|
||||
addNewAntinode(antinodeGrid1, start, part1);
|
||||
addNewAntinode(antinodeGrid2, start, part2);
|
||||
start += increment;
|
||||
while (isInBounds(start))
|
||||
{
|
||||
addNewAntinode(antinodeGrid2, start, part2);
|
||||
start += increment;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ResonantCollinearity::addNewAntinode(Grid<bool>& antinodeGrid, Point2& newPosition, long long int& count)
|
||||
{
|
||||
if (!antinodeGrid[newPosition.y][newPosition.x])
|
||||
{
|
||||
antinodeGrid[newPosition.y][newPosition.x] = true;
|
||||
count++;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user