forked from algorithm-archivists/algorithm-archive
-
Notifications
You must be signed in to change notification settings - Fork 0
/
flood_fill.jl
139 lines (104 loc) · 3.4 KB
/
flood_fill.jl
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
using DataStructures
using Test
# Function to check to make sure we are on the canvas
function inbounds(canvas_size, loc)
# Make sure we are not beneath or to the left of the canvas
if minimum(Tuple(loc)) < 1
return false
# Make sure we are not to the right of the canvas
elseif loc[2] > canvas_size[2]
return false
# Make sure we are not above the canvas
elseif loc[1] > canvas_size[1]
return false
else
return true
end
end
function find_neighbors(canvas, loc::CartesianIndex, old_val, new_val)
# Finding north, south, east, west neighbors
possible_neighbors = [loc + CartesianIndex(0, 1),
loc + CartesianIndex(1, 0),
loc + CartesianIndex(0, -1),
loc + CartesianIndex(-1, 0)]
# Exclusing neighbors that should not be colored
neighbors = []
for possible_neighbor in possible_neighbors
if inbounds(size(canvas), possible_neighbor) &&
canvas[possible_neighbor] == old_val
push!(neighbors, possible_neighbor)
end
end
return neighbors
end
function stack_fill!(canvas, loc::CartesianIndex, old_val, new_val)
if new_val == old_val
return
end
s = Stack{CartesianIndex}()
push!(s, loc)
while length(s) > 0
current_loc = pop!(s)
if canvas[current_loc] == old_val
canvas[current_loc] = new_val
possible_neighbors = find_neighbors(canvas, current_loc,
old_val, new_val)
for neighbor in possible_neighbors
push!(s,neighbor)
end
end
end
end
function queue_fill!(canvas, loc::CartesianIndex, old_val, new_val)
if new_val == old_val
return
end
q = Queue{CartesianIndex}()
enqueue!(q, loc)
# Coloring the initial location
canvas[loc] = new_val
while length(q) > 0
current_loc = dequeue!(q)
possible_neighbors = find_neighbors(canvas, current_loc,
old_val, new_val)
# Coloring as we are enqueuing neighbors
for neighbor in possible_neighbors
canvas[neighbor] = new_val
enqueue!(q,neighbor)
end
end
end
function recursive_fill!(canvas, loc::CartesianIndex, old_val, new_val)
if (old_val == new_val)
return
end
canvas[loc] = new_val
possible_neighbors = find_neighbors(canvas, loc, old_val, new_val)
for possible_neighbor in possible_neighbors
recursive_fill!(canvas, possible_neighbor, old_val, new_val)
end
end
function main()
# Creation of a 5x5 grid with a single row of 1.0 elements
grid = zeros(5,5)
grid[3,:] .= 1
# Create solution grid
answer_grid = zeros(5,5)
answer_grid[1:3, :] .= 1
# Start filling at 1,1
start_loc = CartesianIndex(1,1)
@testset "Fill Methods" begin
# Use recursive method and reinitialize grid
recursive_fill!(grid, start_loc, 0.0, 1.0)
@test grid == answer_grid
grid[1:2,:] .= 0
# Use queue method and reinitialize grid
queue_fill!(grid, start_loc, 0.0, 1.0)
@test grid == answer_grid
grid[1:2,:] .= 0
# Use stack method and reinitialize grid
stack_fill!(grid, start_loc, 0.0, 1.0)
@test grid == answer_grid
end
end
main()