-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathchallenge8.cpp
More file actions
89 lines (75 loc) · 4.2 KB
/
challenge8.cpp
File metadata and controls
89 lines (75 loc) · 4.2 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
#include "challenge8.hpp"
#include "helper.hpp"
#include "print.hpp"
#include <algorithm>
#include <ranges>
#include <unordered_map>
#include <unordered_set>
namespace {
using Position = Coordinate<std::int64_t>;
auto findAntennas(MapView map) {
Position::setMaxFromMap(map);
std::unordered_map<char, std::vector<Position>> antennas;
std::ranges::for_each(std::views::cartesian_product(std::views::iota(0LL, Position::MaxRow),
std::views::iota(0LL, Position::MaxColumn)) |
std::views::transform([](auto rowAndColumn) noexcept {
auto [row, column] = rowAndColumn;
return Position{row, column};
}),
[&map, &antennas](Position pos) noexcept {
if ( auto antenna = map[pos]; antenna != '.' ) {
antennas[antenna].push_back(pos);
} //if ( auto antenna = map[pos]; antenna != '.' )
return;
});
return antennas;
}
auto findAntinodes(MapView map, const std::unordered_map<char, std::vector<Position>>& antennas) noexcept {
std::unordered_set<Position> antinodes;
for ( const auto& [antennaType, positions] : antennas ) {
//This tries to add the position of the antennas (but they are filtered out).
std::ranges::copy(std::views::cartesian_product(positions, positions) |
std::views::transform([](auto bothPositions) noexcept {
auto [first, second] = bothPositions;
return first + (second - first) * 2;
}) |
std::views::filter([&map, antennaType](Position pos) noexcept {
return pos.isValid() && map[pos] != antennaType;
}),
std::inserter(antinodes, antinodes.end()));
} //for ( const auto& [antennaType, positions] : antennas )
return antinodes;
}
auto findResonantAntinodes(const std::unordered_map<char, std::vector<Position>>& antennas) noexcept {
std::unordered_set<Position> antinodes;
for ( const auto& [antennaType, positions] : antennas ) {
if ( positions.size() == 1 ) {
continue;
} //if ( positions.size() == 1 )
for ( auto [index, position] : std::views::enumerate(positions) ) {
antinodes.insert(position);
for ( auto nextPosition : positions | std::views::drop(index + 1) ) {
auto offset = nextPosition - position;
for ( auto positionToCheck = nextPosition + offset; positionToCheck.isValid();
positionToCheck += offset ) {
antinodes.insert(positionToCheck);
} //for ( auto positionToCheck = nextPosition + offset; positionToCheck.isValid(); += offset )
offset *= -1;
for ( auto positionToCheck = position + offset; positionToCheck.isValid(); positionToCheck += offset ) {
antinodes.insert(positionToCheck);
} //for ( auto positionToCheck = position + offset; positionToCheck.isValid(); += offset )
} //for ( auto nextPosition : positions | std::views::drop(index + 1) )
} //for ( auto [index, position] : std::views::enumerate(positions) )
} //for ( const auto& [antennaType, positions] : antennas )
return antinodes;
}
} //namespace
bool challenge8(const std::vector<std::string_view>& input) {
const auto antennas = findAntennas(input);
const auto antinodes = findAntinodes(input, antennas);
const auto numberOfAntinodes = antinodes.size();
myPrint(" == Result of Part 1: {:d} ==\n", numberOfAntinodes);
const auto numberOfResonantAntinodes = findResonantAntinodes(antennas).size();
myPrint(" == Result of Part 2: {:d} ==\n", numberOfResonantAntinodes);
return numberOfAntinodes == 273 && numberOfResonantAntinodes == 1017;
}