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
+ 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 possible_neighbor : possible_neighbors) {
34
+ auto size = CartesianIndex{
35
+ static_cast <int >(grid[0 ].size ()), static_cast <int >(grid.size ())};
36
+ auto x = static_cast <std::size_t >(possible_neighbor[0 ]);
37
+ 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
+ auto x = static_cast <std::size_t >(loc[0 ]);
56
+ auto y = static_cast <std::size_t >(loc[1 ]);
57
+
58
+ grid[x][y] = new_value;
59
+
60
+ auto possible_neighbors = find_neighbors (grid, loc, old_value, new_value);
61
+ for (auto 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
+ auto x = static_cast <std::size_t >(loc[0 ]);
78
+ auto y = static_cast <std::size_t >(loc[1 ]);
79
+ grid[x][y] = new_value;
80
+
81
+ while (q.size () > 0 ) {
82
+ auto current_loc = q.front ();
83
+ q.pop ();
84
+ auto possible_neighbors =
85
+ find_neighbors (grid, current_loc, old_value, new_value);
86
+ for (auto neighbor : possible_neighbors) {
87
+ auto neighbor_x = static_cast <std::size_t >(neighbor[0 ]);
88
+ 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
+ auto current_loc = s.top ();
109
+ s.pop ();
110
+
111
+ auto x = static_cast <std::size_t >(current_loc[0 ]);
112
+ 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
+ auto possible_neighbors =
117
+ find_neighbors (grid, current_loc, old_value, new_value);
118
+ for (auto neighbor : possible_neighbors) {
119
+ s.push (neighbor);
120
+ }
121
+ }
122
+ }
123
+ }
124
+
125
+ int main () {
126
+
127
+ 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
+ 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
+ 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