-
Notifications
You must be signed in to change notification settings - Fork 0
/
Day08.cpp
59 lines (49 loc) · 1.34 KB
/
Day08.cpp
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
#include "Solution.hpp"
#include <iterator>
#include <vector>
#include <range/v3/numeric.hpp>
#include <range/v3/view/transform.hpp>
#include <range/v3/view/filter.hpp>
namespace view = ranges::view;
struct node {
std::vector<unsigned long long> meta;
std::vector<node> children;
};
node read(std::istream_iterator<int>& i) {
node n;
int c = *i++, m = *i++;
while (c--) {
n.children.push_back(read(i));
}
while (m--) {
n.meta.push_back(*i++);
}
return n;
}
int total(const node& node) {
return ranges::accumulate(node.children | view::transform(total), 0) + ranges::accumulate(node.meta, 0);
}
int value(const node& node) {
if (node.children.empty()) {
return total(node);
}
return ranges::accumulate(node.meta
| view::filter([&](size_t d) { return d > 0 && d <= node.children.size(); })
| view::transform([&](size_t d) { return value(node.children[d - 1]); }),
0);
}
template <>
template <bool part2>
void
Day<8>::solve(std::istream& is, std::ostream& os) {
std::istream_iterator<int> iter{is};
if constexpr(part2) {
os << value(read(iter)) << '\n';
} else {
os << total(read(iter)) << '\n';
}
}
template void
Day<8>::solve<true>(std::istream&, std::ostream&);
template void
Day<8>::solve<false>(std::istream&, std::ostream&);