99#include < stack>
1010#include < queue>
1111
12- struct Node {
13- Node* left;
14- Node* right ;
15- int value ;
16- int steps_to_split ;
12+ struct Node
13+ {
14+ Node *left ;
15+ Node *right ;
16+ uint64_t value ;
1717};
1818
1919struct Data
2020{
2121 std::vector<int > stones;
2222};
2323
24- int part1 (const Data &data)
24+ Node *get_node (uint64_t new_value, std::map<uint64_t , std::unique_ptr<Node>> &splits)
25+ {
26+ if (!splits.contains (new_value))
27+ {
28+ splits[new_value] = std::make_unique<Node>(Node{.left = nullptr , .right = nullptr , .value = new_value});
29+ }
30+ return splits[new_value].get ();
31+ }
32+
33+ uint64_t part1 (const Data &data)
2534{
26- std::map<int , std::unique_ptr<Node>> splits;
27- int sum = 0 ;
35+ std::map<uint64_t , std::unique_ptr<Node>> splits;
36+ uint64_t sum = 0 ;
2837
2938 for (auto &stone : data.stones )
3039 {
3140 // stone value, depth
32- std::queue<std::pair<int , int >> q;
41+ std::queue<std::pair<uint64_t , uint64_t >> q;
3342 q.push ({stone, 0 });
3443 sum += 1 ;
35- int n_steps = 6 ;
44+ uint64_t n_steps = 25 ;
3645
3746 while (!q.empty ())
3847 {
3948 auto val = q.front ();
40- Node* cur = nullptr ;
49+ Node * cur = get_node (val. first , splits) ;
4150
42- if (!splits.contains (val.first )) {
43- splits[val.first ] = std::make_unique<Node>(Node{.left = nullptr , .right = nullptr , .value = val.first , .steps_to_split = 0 });
44- }
45- cur = splits[val.first ].get ();
4651
4752 for (size_t blink = val.second ; blink < n_steps; ++blink)
4853 {
49- if (splits. contains (val. first ) && cur->left != nullptr )
54+ while ( cur->left != nullptr && blink < n_steps )
5055 {
51- cur = splits[val.first ].get ();
52- if (cur->left != nullptr && cur->right != nullptr )
56+ if (cur->right != nullptr )
5357 {
54- if (cur->steps_to_split + blink > n_steps)
55- {
56- break ;
57- }
58- sum += 1 ;
59- blink += cur->steps_to_split ;
60- cur = cur->left ;
61- val.first = cur->value ;
62- continue ;
58+ ++sum;
59+ q.push ({cur->right ->value , blink + 1 });
6360 }
61+ ++blink;
62+ cur = cur->left ;
6463 }
65-
66- int num_digits = std::floor (std::log10 (val.first )) + 1 ;
67- if (val.first == 0 )
64+ if (blink >= n_steps)
65+ break ;
66+ uint64_t num_digits = std::floor (std::log10 (cur->value )) + 1 ;
67+ if (cur->value == 0 )
6868 {
69- val.first = 1 ;
70- cur->steps_to_split += 1 ;
69+ Node *next = get_node (1 , splits);
70+ cur->left = next;
71+ cur = cur->left ;
7172 }
7273 else if (num_digits % 2 == 0 )
7374 {
74- int right_half = val. first % int (std::pow (10 , num_digits / 2 ));
75- val. first /= std::pow (10 , num_digits / 2 );
75+ uint64_t right_half = cur-> value % uint64_t (std::pow (10 , num_digits / 2 ));
76+ uint64_t left_half = cur-> value / std::pow (10 , num_digits / 2 );
7677 sum += 1 ;
77- if (!splits.contains (right_half))
78- {
79- splits[right_half] = std::make_unique<Node>(Node{.left = nullptr , .right = nullptr , .value = right_half, .steps_to_split = 0 });
80- }
81- if (!splits.contains (val.first ))
82- {
83- splits[val.first ] = std::make_unique<Node>(Node{.left = nullptr , .right = nullptr , .value = val.first , .steps_to_split = 0 });
84- }
85- cur->left = splits[val.first ].get ();
86- cur->right = splits[right_half].get ();
78+ Node *left = get_node (left_half, splits);
79+ Node *right = get_node (right_half, splits);
80+ cur->left = left;
81+ cur->right = right;
8782 cur = cur->left ;
8883 q.push ({right_half, blink + 1 });
8984 }
9085 else
9186 {
92- val.first *= 2024 ;
93- cur->steps_to_split += 1 ;
87+ Node *next = get_node (cur->value * 2024 , splits);
88+ cur->left = next;
89+ cur = cur->left ;
9490 }
9591 }
9692 q.pop ();
@@ -137,7 +133,7 @@ BENCHMARK_DEFINE_F(BenchmarkFixture, Part1Benchmark)
137133{
138134 for (auto _ : state)
139135 {
140- int s = part1 (data);
136+ uint64_t s = part1 (data);
141137 benchmark::DoNotOptimize (s);
142138 }
143139}
@@ -159,7 +155,7 @@ int main(int argc, char **argv)
159155{
160156 Data data = parse ();
161157
162- int answer1 = 0 ;
158+ uint64_t answer1 = 0 ;
163159 int answer2 = 0 ;
164160
165161 auto first = part1 (data);
0 commit comments