1- #include < map>
2-
31#include " default_includes.hpp"
42#include " solution.hpp"
53
6- using coords = std::pair<int , int >;
7-
84enum Dir {
95 Dir_Right,
106 Dir_Up,
@@ -13,22 +9,31 @@ enum Dir {
139 Dir_Max
1410};
1511
12+ static constexpr int64_t coords_key (int32_t x, int32_t y)
13+ {
14+ return (static_cast <int64_t >(*reinterpret_cast <uint32_t *>(&x)) << 32 )
15+ | (*reinterpret_cast <uint32_t *>(&y));
16+ }
17+
1618static constexpr Dir next_dir (Dir dir)
1719{
1820 return static_cast <Dir>((dir + 1 ) % Dir_Max);
1921}
2022
21- static int neighbor_sum (std::map<coords, int >& nodes, int x, int y)
23+ static int neighbor_sum (
24+ std::unordered_map<int64_t , int >& nodes,
25+ int32_t x,
26+ int32_t y)
2227{
23- static const std::array<coords , 8 > deltas{{
28+ static const std::array<std::pair< int32_t , int32_t > , 8 > deltas{{
2429 { 0 , 1 }, {1 , 0 }, { 1 , 1 }, { 1 , -1 },
2530 {-1 , 1 }, {0 , -1 }, {-1 , 0 }, {-1 , -1 }
2631 }};
2732
2833 return std::accumulate (deltas.begin (), deltas.end (), 0 ,
29- [&](int sum, const coords & p) {
34+ [&](int sum, const std::pair< int32_t , int32_t > & p) {
3035 auto [x_d, y_d] = p;
31- return sum + nodes[{( x + x_d), (y + y_d)} ];
36+ return sum + nodes[coords_key (( x + x_d), (y + y_d)) ];
3237 });
3338}
3439
@@ -38,37 +43,35 @@ void solve<Day03>(std::istream& ins, std::ostream& outs)
3843 int input;
3944 ins >> input;
4045
41- std::map<coords , int > nodes;
42- std::array<coords , Dir_Max> dir_deltas;
46+ std::unordered_map< int64_t , int > nodes;
47+ std::array<std::pair< int32_t , int32_t > , Dir_Max> dir_deltas;
4348
4449 dir_deltas[Dir_Right] = { 1 , 0 };
4550 dir_deltas[Dir_Up] = { 0 , -1 };
4651 dir_deltas[Dir_Left] = {-1 , 0 };
4752 dir_deltas[Dir_Down] = { 0 , 1 };
4853
49- auto dir = Dir_Right;
50- coords pos = { 0 , 0 };
51- nodes[pos ] = 1 ;
54+ auto dir{ Dir_Right} ;
55+ int32_t x{ 0 }, y{ 0 };
56+ nodes[coords_key (x, y) ] = 1 ;
5257
53- while (nodes[pos ] < input)
58+ while (nodes[coords_key (x, y) ] < input)
5459 {
5560 // Next pos and calc sum of neighbors.
56- auto [x_d, y_d] = dir_deltas[dir];
57- pos.first += x_d;
58- pos.second += y_d;
59- auto [x, y] = pos;
60- nodes[pos] = neighbor_sum (nodes, x, y);
61+ auto [x_d, y_d] = dir_deltas[dir];
62+ x += x_d;
63+ y += y_d;
64+ nodes[coords_key (x, y)] = neighbor_sum (nodes, x, y);
6165
6266 // Check if direction needs to be changed.
63- auto [xn_d, yn_d] = dir_deltas[next_dir (dir)];
64- pos.first += xn_d;
65- pos.second += yn_d;
66- if (nodes[pos] == 0 ) { dir = next_dir (dir); }
67-
68- pos.first = x;
69- pos.second = y;
67+ auto [xn_d, yn_d] = dir_deltas[next_dir (dir)];
68+ if (nodes[coords_key ((x + xn_d), (y + yn_d))] == 0 )
69+ {
70+ dir = next_dir (dir);
71+ }
7072 }
7173
72- outs << " (Part 2) Next spiral value = " << nodes[pos] << std::endl;
74+ outs << " (Part 2) Next spiral value = "
75+ << nodes[coords_key (x, y)] << std::endl;
7376}
7477
0 commit comments