aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--2024/src/day10.cpp133
1 files changed, 64 insertions, 69 deletions
diff --git a/2024/src/day10.cpp b/2024/src/day10.cpp
index 58b797f..73e4f92 100644
--- a/2024/src/day10.cpp
+++ b/2024/src/day10.cpp
@@ -1,6 +1,7 @@
1#include <fstream> 1#include <fstream>
2#include <iostream> 2#include <iostream>
3#include <map> 3#include <map>
4#include <numeric>
4#include <queue> 5#include <queue>
5#include <set> 6#include <set>
6#include <string> 7#include <string>
@@ -33,42 +34,8 @@ neighbors(pos_type pos)
33 return { { x - 1, y }, { x, y - 1 }, { x + 1, y }, { x, y + 1 } }; 34 return { { x - 1, y }, { x, y - 1 }, { x + 1, y }, { x, y + 1 } };
34} 35}
35 36
36size_t 37vector<pos_type>
37bfs(const map<pos_type, int>& data, pos_type start_pos) 38get_starts(const map<pos_type, int>& data)
38{
39 size_t peaks = 0;
40
41 set<pos_type> seen;
42 queue<pos_type> queue;
43
44 queue.emplace(start_pos);
45 seen.emplace(start_pos);
46
47 while ( !queue.empty() ) {
48 auto pos = queue.front();
49 queue.pop();
50
51 if ( data.at(pos) == 9 ) {
52 ++peaks;
53 continue;
54 }
55
56 for ( const auto& neighbor: neighbors(pos) ) {
57 if ( !data.contains(neighbor) ||
58 seen.contains(neighbor) ||
59 data.at(neighbor) != data.at(pos) + 1 ) {
60 continue;
61 }
62
63 queue.emplace(neighbor);
64 seen.insert(neighbor);
65 }
66 }
67 return peaks;
68}
69
70void
71part1(const map<pos_type, int>& data)
72{ 39{
73 vector<pos_type> starts; 40 vector<pos_type> starts;
74 for ( const auto& [pos, value]: data ) { 41 for ( const auto& [pos, value]: data ) {
@@ -76,59 +43,87 @@ part1(const map<pos_type, int>& data)
76 starts.push_back(pos); 43 starts.push_back(pos);
77 } 44 }
78 } 45 }
79 46 return starts;
80 size_t sum = 0;
81 for ( const auto& start: starts ) {
82 sum += bfs(data, start);
83 }
84 cout << sum << endl;
85} 47}
86 48
49template<typename BFS>
87size_t 50size_t
88bfs2(const map<pos_type, int>& data, pos_type start_pos) 51solve(const map<pos_type, int>& data, BFS bfs)
89{ 52{
90 size_t paths = 0; 53 auto starts = get_starts(data);
54 return accumulate(starts.begin(), starts.end(), 0U, [&](auto init, auto start) { return init + bfs(data, start); });
55}
91 56
92 queue<pos_type> queue; 57void
58part1(const map<pos_type, int>& data)
59{
60 auto bfs = [](const map<pos_type, int>& data, pos_type start_pos) -> size_t {
61 size_t score = 0;
93 62
94 queue.push(start_pos); 63 set<pos_type> seen;
64 queue<pos_type> queue;
95 65
96 while ( !queue.empty() ) { 66 queue.emplace(start_pos);
97 auto pos = queue.front(); 67 seen.emplace(start_pos);
98 queue.pop();
99 68
100 if ( data.at(pos) == 9 ) { 69 while ( !queue.empty() ) {
101 ++paths; 70 auto pos = queue.front();
102 continue; 71 queue.pop();
103 }
104 72
105 for ( const auto& neighbor: neighbors(pos) ) { 73 if ( data.at(pos) == 9 ) {
106 if ( !data.contains(neighbor) || 74 ++score;
107 data.at(neighbor) != data.at(pos) + 1 ) {
108 continue; 75 continue;
109 } 76 }
110 77
111 queue.emplace(neighbor); 78 for ( const auto& neighbor: neighbors(pos) ) {
79 if ( !data.contains(neighbor) ||
80 seen.contains(neighbor) ||
81 data.at(neighbor) != data.at(pos) + 1 ) {
82 continue;
83 }
84
85 queue.emplace(neighbor);
86 seen.insert(neighbor);
87 }
112 } 88 }
113 } 89 return score;
114 return paths; 90 };
91
92 cout << solve(data, bfs) << endl;
115} 93}
116 94
117void 95void
118part2(const map<pos_type, int>& data) 96part2(const map<pos_type, int>& data)
119{ 97{
120 vector<pos_type> starts; 98 auto bfs = [](const map<pos_type, int>& data, pos_type start_pos) -> size_t {
121 for ( const auto& [pos, value]: data ) { 99 size_t score = 0;
122 if ( value == 0 ) { 100
123 starts.push_back(pos); 101 queue<pos_type> queue;
102
103 queue.push(start_pos);
104
105 while ( !queue.empty() ) {
106 auto pos = queue.front();
107 queue.pop();
108
109 if ( data.at(pos) == 9 ) {
110 ++score;
111 continue;
112 }
113
114 for ( const auto& neighbor: neighbors(pos) ) {
115 if ( !data.contains(neighbor) ||
116 data.at(neighbor) != data.at(pos) + 1 ) {
117 continue;
118 }
119
120 queue.emplace(neighbor);
121 }
124 } 122 }
125 } 123 return score;
124 };
126 125
127 size_t sum = 0; 126 cout << solve(data, bfs) << endl;
128 for ( const auto& start: starts ) {
129 sum += bfs2(data, start);
130 }
131 cout << sum << endl;
132} 127}
133 128
134int 129int