1+ #include < array>
2+ #include < cassert>
3+ #include < iostream>
4+ #include < queue>
5+ #include < stack>
6+ #include < vector>
7+
8+ using CartesianIndex = std::array<int , 2 >;
9+
10+ auto inbounds (CartesianIndex size, CartesianIndex loc) {
11+ if (loc[0 ] < 0 || loc[1 ] < 0 ) {
12+ return false ;
13+ } else if (loc[0 ] >= size[0 ] || loc[1 ] >= size[1 ]) {
14+ return false ;
15+ }
16+ return true ;
17+ }
18+
19+ auto find_neighbors (
20+ std::vector<std::vector<float >> const & grid,
21+ CartesianIndex loc,
22+ float old_value,
23+ float /* new_value */ ) {
24+
25+ const std::vector<CartesianIndex> possible_neighbors{
26+ {loc[0 ], loc[1 ] + 1 },
27+ {loc[0 ] + 1 , loc[1 ]},
28+ {loc[0 ], loc[1 ] - 1 },
29+ {loc[0 ] - 1 , loc[1 ]}};
30+
31+ std::vector<CartesianIndex> neighbors;
32+
33+ for (auto const & possible_neighbor : possible_neighbors) {
34+ const auto size = CartesianIndex{
35+ static_cast <int >(grid[0 ].size ()), static_cast <int >(grid.size ())};
36+ const auto x = static_cast <std::size_t >(possible_neighbor[0 ]);
37+ const auto y = static_cast <std::size_t >(possible_neighbor[1 ]);
38+ if (inbounds (size, possible_neighbor) && grid[x][y] == old_value) {
39+ neighbors.push_back (possible_neighbor);
40+ }
41+ }
42+
43+ return neighbors;
44+ }
45+
46+ void recursive_fill (
47+ std::vector<std::vector<float >>& grid,
48+ CartesianIndex loc,
49+ float old_value,
50+ float new_value) {
51+ if (old_value == new_value) {
52+ return ;
53+ }
54+
55+ const auto x = static_cast <std::size_t >(loc[0 ]);
56+ const auto y = static_cast <std::size_t >(loc[1 ]);
57+
58+ grid[x][y] = new_value;
59+
60+ const auto possible_neighbors = find_neighbors (grid, loc, old_value, new_value);
61+ for (auto const & possible_neighbor : possible_neighbors) {
62+ recursive_fill (grid, possible_neighbor, old_value, new_value);
63+ }
64+ }
65+
66+ void queue_fill (
67+ std::vector<std::vector<float >>& grid,
68+ CartesianIndex loc,
69+ float old_value,
70+ float new_value) {
71+ if (old_value == new_value) {
72+ return ;
73+ }
74+
75+ auto q = std::queue<CartesianIndex>{};
76+ q.push (loc);
77+ const auto x = static_cast <std::size_t >(loc[0 ]);
78+ const auto y = static_cast <std::size_t >(loc[1 ]);
79+ grid[x][y] = new_value;
80+
81+ while (q.size () > 0 ) {
82+ const auto current_loc = q.front ();
83+ q.pop ();
84+ const auto possible_neighbors =
85+ find_neighbors (grid, current_loc, old_value, new_value);
86+ for (auto const & neighbor : possible_neighbors) {
87+ const auto neighbor_x = static_cast <std::size_t >(neighbor[0 ]);
88+ const auto neighbor_y = static_cast <std::size_t >(neighbor[1 ]);
89+ grid[neighbor_x][neighbor_y] = new_value;
90+ q.push (neighbor);
91+ }
92+ }
93+ }
94+
95+ void stack_fill (
96+ std::vector<std::vector<float >>& grid,
97+ CartesianIndex loc,
98+ float old_value,
99+ float new_value) {
100+ if (old_value == new_value) {
101+ return ;
102+ }
103+
104+ auto s = std::stack<CartesianIndex>{};
105+ s.push (loc);
106+
107+ while (s.size () > 0 ) {
108+ const auto current_loc = s.top ();
109+ s.pop ();
110+
111+ const auto x = static_cast <std::size_t >(current_loc[0 ]);
112+ const auto y = static_cast <std::size_t >(current_loc[1 ]);
113+
114+ if (grid[x][y] == old_value) {
115+ grid[x][y] = new_value;
116+ const auto possible_neighbors =
117+ find_neighbors (grid, current_loc, old_value, new_value);
118+ for (auto const & neighbor : possible_neighbors) {
119+ s.push (neighbor);
120+ }
121+ }
122+ }
123+ }
124+
125+ int main () {
126+
127+ const std::vector<std::vector<float >> grid{
128+ {0 , 0 , 1 , 0 , 0 },
129+ {0 , 0 , 1 , 0 , 0 },
130+ {0 , 0 , 1 , 0 , 0 },
131+ {0 , 0 , 1 , 0 , 0 },
132+ {0 , 0 , 1 , 0 , 0 }};
133+
134+ const std::vector<std::vector<float >> solution_grid{
135+ {1 , 1 , 1 , 0 , 0 },
136+ {1 , 1 , 1 , 0 , 0 },
137+ {1 , 1 , 1 , 0 , 0 },
138+ {1 , 1 , 1 , 0 , 0 },
139+ {1 , 1 , 1 , 0 , 0 }};
140+
141+ const CartesianIndex start_loc{1 , 1 };
142+
143+ auto test_grid = grid;
144+ recursive_fill (test_grid, start_loc, 0.0 , 1.0 );
145+ assert (test_grid == solution_grid);
146+
147+ test_grid = grid;
148+ queue_fill (test_grid, start_loc, 0.0 , 1.0 );
149+ assert (test_grid == solution_grid);
150+
151+ test_grid = grid;
152+ stack_fill (test_grid, start_loc, 0.0 , 1.0 );
153+ assert (test_grid == solution_grid);
154+
155+ return EXIT_SUCCESS;
156+ }
0 commit comments