Skip to content

Commit 5df0499

Browse files
committed
Day 10
1 parent 0d97878 commit 5df0499

File tree

4 files changed

+226
-1
lines changed

4 files changed

+226
-1
lines changed

CMakeLists.txt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,4 +13,5 @@ add_executable(day5-binary-boarding day5/binary-boarding.cpp)
1313
add_executable(day6-custom-customs day6/custom-customs.cpp)
1414
add_executable(day7-handy-haversacks day7/handy-haversacks.cpp)
1515
add_executable(day8-handheld-halting day8/handheld-halting.cpp)
16-
add_executable(day9-encoding-error day9/encoding-error.cpp)
16+
add_executable(day9-encoding-error day9/encoding-error.cpp)
17+
add_executable(day10-adapter-array day10/adapter-array.cpp)

day10/adapter-array.cpp

Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
#include "day5/arg_input.hpp"
2+
3+
#include <algorithm>
4+
#include <numeric>
5+
#include <ranges>
6+
#include <vector>
7+
8+
namespace ranges = std::ranges;
9+
10+
using tree_t = std::unordered_map<int, std::vector<int>>;
11+
using cache_t = std::unordered_map<size_t, long long>;
12+
13+
auto traverse_impl(const tree_t& tree, int from, int to, cache_t& cache) -> long long {
14+
auto cache_key = [](int from, int to) {
15+
return static_cast<size_t>(from) << 32u | static_cast<size_t>(to);
16+
};
17+
18+
if (cache.contains(cache_key(from, to))) // if we've seen path (from, to), use the cached value
19+
return cache.at(cache_key(from, to));
20+
21+
// check if the tree contains adapters that will lead to `to`
22+
if (!tree.contains(to))
23+
return 0;
24+
const auto& down = tree.at(to);
25+
// for each adapter that leads to `to`, traverse again. If this is the start, count the path `+1`.
26+
auto ways = std::accumulate(down.cbegin(), down.cend(), 0ll, [&](auto a, auto i) {
27+
if (i == from) // if at the end, count this is a possible path
28+
return a + 1;
29+
return a + traverse_impl(tree, from, i, cache);
30+
});
31+
32+
cache[cache_key(from, to)] = ways;
33+
return ways;
34+
}
35+
36+
template<typename... Args>
37+
auto traverse(Args... args) {
38+
cache_t cache;
39+
return traverse_impl(std::forward<Args>(args)..., cache);
40+
}
41+
42+
auto main(int argc, char* argv[]) -> int {
43+
if (argc != 2) {
44+
std::cout << "Usage: " << argv[0] << " {path-to-file}" << std::endl;
45+
return 1;
46+
}
47+
48+
auto file = get_input(argc, argv);
49+
50+
if (std::holds_alternative<int>(file))
51+
return std::get<int>(file);
52+
53+
auto& input = std::get<std::ifstream>(file);
54+
55+
std::vector<long long> adapters;
56+
for (std::string l; std::getline(input, l); )
57+
adapters.push_back(std::stoll(l));
58+
59+
adapters.push_back(0); // throw the 0-jolts outlet in there
60+
ranges::sort(adapters);
61+
adapters.push_back(adapters.back()+3); // and the 3-jolts PC
62+
63+
// in the sorted range, get the difference between adapters
64+
auto steps = adapters;
65+
ranges::transform(steps, steps.begin(), [](auto a){
66+
static auto prev = a;
67+
auto diff = a - prev;
68+
prev = a;
69+
return diff;
70+
});
71+
72+
// count the occurence of 1- and 3-difference steps
73+
auto occurence = [](const auto& it, const auto& cmp){
74+
return ranges::count_if(it, [&cmp](const auto& v) { return v == cmp; });
75+
};
76+
auto one_diff = occurence(steps, 1),
77+
three_diff = occurence(steps, 3);
78+
std::cout << "Part 1: " << one_diff << " 1-jolt diffs, " << three_diff << " 3-jolt diffs: " << one_diff * three_diff << "\n";
79+
80+
// Part 2: make a tree of which adapters lead to adapter i
81+
auto adapter_tree = tree_t {};
82+
adapter_tree.reserve(adapters.size());
83+
84+
for (size_t i = 1; i < adapters.size(); i++) {
85+
auto adapter = adapters[i];
86+
auto it = adapters.cbegin() + i;
87+
// find in the sorted range [i-3, i) the adapter that suits, then all adapters [i-3,i) will suit
88+
auto least = std::upper_bound(it - std::min(3ul, i), it, adapter - 3 - 1);
89+
adapter_tree[adapter] = tree_t::value_type::second_type(std::distance(least, it));
90+
std::copy(least, it, adapter_tree.at(adapter).begin());
91+
}
92+
93+
std::cout << "Part 2: " << traverse(adapter_tree, adapters.front(), adapters.back()) << "\n";
94+
}

day10/example_input

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
28
2+
33
3+
18
4+
42
5+
31
6+
14
7+
46
8+
20
9+
48
10+
47
11+
24
12+
23
13+
49
14+
45
15+
19
16+
38
17+
39
18+
11
19+
1
20+
32
21+
25
22+
35
23+
8
24+
17
25+
7
26+
9
27+
4
28+
2
29+
34
30+
10
31+
3

day10/input

Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
77
2+
58
3+
25
4+
92
5+
14
6+
154
7+
105
8+
112
9+
147
10+
63
11+
84
12+
109
13+
24
14+
129
15+
49
16+
102
17+
130
18+
128
19+
134
20+
88
21+
95
22+
70
23+
80
24+
4
25+
153
26+
17
27+
145
28+
122
29+
39
30+
117
31+
93
32+
65
33+
3
34+
2
35+
139
36+
101
37+
148
38+
37
39+
27
40+
1
41+
87
42+
64
43+
23
44+
59
45+
42
46+
146
47+
43
48+
151
49+
116
50+
46
51+
115
52+
118
53+
131
54+
94
55+
19
56+
33
57+
12
58+
107
59+
10
60+
7
61+
73
62+
78
63+
53
64+
11
65+
135
66+
79
67+
60
68+
32
69+
141
70+
31
71+
140
72+
98
73+
136
74+
72
75+
38
76+
152
77+
30
78+
74
79+
106
80+
50
81+
13
82+
26
83+
155
84+
67
85+
20
86+
66
87+
91
88+
56
89+
34
90+
125
91+
52
92+
51
93+
18
94+
108
95+
57
96+
81
97+
119
98+
71
99+
144

0 commit comments

Comments
 (0)