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
|
#include <bits/stdc++.h>
namespace views = std::views;
namespace ranges = std::ranges;
using set = std::pair<uint64_t, uint64_t>;
auto parse_input(std::istream& is) {
const std::string input = {
std::istreambuf_iterator<char>(is),
std::istreambuf_iterator<char>()
};
auto const lines = input
| views::split(std::string_view{"\n\n"})
| views::filter([](auto&& line) { return not line.empty(); })
| ranges::to<std::vector<std::string>>();
auto const sets = lines[0]
| views::split('\n')
| views::filter([](auto&& line) { return not line.empty(); })
| views::transform([](auto&& element) -> set {
auto const l = element | views::split('-') | ranges::to<std::vector<std::string>>();
return set{std::stoull(l[0]), std::stoull(l[1])};
})
| ranges::to<std::vector<set>>();
auto const numbers = lines[1]
| views::split('\n')
| views::filter([](auto&& line) { return not line.empty(); })
| views::transform([](auto&& elem) -> uint64_t { return std::stoull(elem | ranges::to<std::string>()); })
| ranges::to<std::vector>();
// Parse input
return std::make_tuple(sets, numbers);
}
void part1(auto const& input) {
// Write first part solution here
auto const& [sets, numbers] = input;
uint64_t answer = 0;
for (auto const n : numbers) {
answer += ranges::count_if(sets, [n](auto const& set) { return set.first <= n and n <= set.second; }) > 0;
}
std::println("{}", answer);
}
std::vector<set> merge_sets(std::vector<set> sets) {
ranges::sort(sets);
std::vector merged_sets = {sets[0]};
merged_sets.reserve(sets.size());
for (auto const& next : sets) {
auto& last = merged_sets.back();
if (last.second + 1 < next.first) {
// gap: [(1, 5), (7, 12)]
merged_sets.push_back(next);
} else {
// no gap: [(1, 5), (4, 8)]
last.second = std::max(last.second, next.second);
}
}
return merged_sets;
}
void part2(auto const& input) {
// Write second part solution here
auto const& [sets, numbers] = input;
auto const merged_sets = merge_sets(sets);
uint64_t answer = 0;
for (auto const set : merged_sets) {
answer += set.second - set.first + 1;
}
std::println("{}", answer);
}
int main() {
auto const input = parse_input(std::cin);
part1(input);
part2(input);
return 0;
}
|