diff --git a/contents/flood_fill/code/c/flood_fill.c b/contents/flood_fill/code/c/flood_fill.c index ea7cc851c..d922412a1 100644 --- a/contents/flood_fill/code/c/flood_fill.c +++ b/contents/flood_fill/code/c/flood_fill.c @@ -25,12 +25,6 @@ int inbounds(struct point p, struct canvas c) { return (p.x < 0 || p.y < 0 || p.y >= c.max_y || p.x >= c.max_x) ? 0 : 1; } -void color(struct canvas c, struct point p, int old_val, int new_val) { - if (inbounds(p, c) && c.data[p.x + c.max_x * p.y] == old_val) { - c.data[p.x + c.max_x * p.y] = new_val; - } -} - int find_neighbors(struct canvas c, struct point p, int old_val, int new_val, struct point *neighbors) { int cnt = 0; @@ -93,7 +87,7 @@ void stack_fill(struct canvas c, struct point p, int old_val, int new_val) { while (!stack_empty(stk)) { struct point cur_loc = stack_pop(&stk); if (c.data[cur_loc.x + c.max_x * cur_loc.y] == old_val) { - color(c, cur_loc, old_val, new_val); + c.data[cur_loc.x + c.max_x * cur_loc.y] = new_val; struct point neighbors[4]; int cnt = find_neighbors(c, cur_loc, old_val, new_val, neighbors); @@ -163,7 +157,7 @@ void queue_fill(struct canvas c, struct point p, int old_val, int new_val) { while (!queue_empty(q)) { struct point cur_loc = dequeue(&q); if (c.data[cur_loc.x + c.max_x * cur_loc.y] == old_val) { - color(c, cur_loc, old_val, new_val); + c.data[cur_loc.x + c.max_x * cur_loc.y] = new_val; struct point neighbors[4]; int cnt = find_neighbors(c, cur_loc, old_val, new_val, neighbors); @@ -184,7 +178,7 @@ void recursive_fill(struct canvas c, struct point p, int old_val, return; } - color(c, p, old_val, new_val); + c.data[p.x + c.max_x * p.y] = new_val; struct point neighbors[4]; int cnt = find_neighbors(c, p, old_val, new_val, neighbors); diff --git a/contents/flood_fill/code/julia/flood_fill.jl b/contents/flood_fill/code/julia/flood_fill.jl index 7658ac808..bc42ac9d0 100644 --- a/contents/flood_fill/code/julia/flood_fill.jl +++ b/contents/flood_fill/code/julia/flood_fill.jl @@ -20,20 +20,6 @@ function inbounds(canvas_size, loc) end end -function color!(canvas, loc::CartesianIndex, old_val, new_val) - # bounds check, do not color if no in bounds! - if !inbounds(size(canvas), loc) - return - end - - # Only change color if the element value is the old value - if (canvas[loc] != old_val) - return - else - canvas[loc] = new_val - end -end - function find_neighbors(canvas, loc::CartesianIndex, old_val, new_val) # Finding north, south, east, west neighbors @@ -65,7 +51,7 @@ function stack_fill!(canvas, loc::CartesianIndex, old_val, new_val) while length(s) > 0 current_loc = pop!(s) if canvas[current_loc] == old_val - color!(canvas, current_loc, old_val, new_val) + canvas[current_loc] = new_val possible_neighbors = find_neighbors(canvas, current_loc, old_val, new_val) for neighbor in possible_neighbors @@ -86,7 +72,7 @@ function queue_fill!(canvas, loc::CartesianIndex, old_val, new_val) enqueue!(q, loc) # Coloring the initial location - color!(canvas, loc, old_val, new_val) + canvas[loc] = new_val while length(q) > 0 current_loc = dequeue!(q) @@ -96,7 +82,7 @@ function queue_fill!(canvas, loc::CartesianIndex, old_val, new_val) # Coloring as we are enqueuing neighbors for neighbor in possible_neighbors - color!(canvas, neighbor, old_val, new_val) + canvas[neighbor] = new_val enqueue!(q,neighbor) end @@ -109,7 +95,7 @@ function recursive_fill!(canvas, loc::CartesianIndex, old_val, new_val) return end - color!(canvas, loc, old_val, new_val) + canvas[loc] = new_val possible_neighbors = find_neighbors(canvas, loc, old_val, new_val) for possible_neighbor in possible_neighbors diff --git a/contents/flood_fill/code/python/flood_fill.py b/contents/flood_fill/code/python/flood_fill.py index 0d22599f5..5b346fa39 100644 --- a/contents/flood_fill/code/python/flood_fill.py +++ b/contents/flood_fill/code/python/flood_fill.py @@ -7,9 +7,6 @@ def inbounds(canvas_shape, p): return min(p) >= 0 and p.x < canvas_shape[0] and p.y < canvas_shape[1] -def color(canvas, p, new_val): - canvas[p] = new_val - def find_neighbors(canvas, p, old_val, new_val): # north, south, east, west neighbors possible_neighbors = [ @@ -35,7 +32,7 @@ def stack_fill(canvas, p, old_val, new_val): while stack: cur_loc = stack.pop() - color(canvas, cur_loc, new_val) + canvas[cur_loc] = new_val stack += find_neighbors(canvas, cur_loc, old_val, new_val) def queue_fill(canvas, p, old_val, new_val): @@ -45,21 +42,21 @@ def queue_fill(canvas, p, old_val, new_val): q = Queue() q.put(p) - color(canvas, p, new_val) + canvas[p] = new_val while not q.empty(): cur_loc = q.get() neighbors = find_neighbors(canvas, cur_loc, old_val, new_val) for neighbor in neighbors: - color(canvas, neighbor, new_val) + canvas[neighbor] = new_val q.put(neighbor) def recursive_fill(canvas, p, old_val, new_val): if old_val == new_val: return - color(canvas, p, new_val) + canvas[p] = new_val neighbors = find_neighbors(canvas, p, old_val, new_val) for neighbor in neighbors: diff --git a/contents/flood_fill/flood_fill.md b/contents/flood_fill/flood_fill.md index 9cf00c577..7c350100c 100644 --- a/contents/flood_fill/flood_fill.md +++ b/contents/flood_fill/flood_fill.md @@ -87,11 +87,11 @@ In code, this might look like this: {% method %} {% sample lang="jl" %} -[import:37-55, lang:"julia"](code/julia/flood_fill.jl) +[import:23-41, lang:"julia"](code/julia/flood_fill.jl) {% sample lang="c" %} -[import:34-52, lang:"c"](code/c/flood_fill.c) +[import:28-46, lang:"c"](code/c/flood_fill.c) {% sample lang="py" %} -[import:13-28, lang="python"](code/python/flood_fill.py) +[import:10-25, lang="python"](code/python/flood_fill.py) {% endmethod %} @@ -105,22 +105,11 @@ In code, it might look like this: {% method %} {% sample lang="jl" %} -[import:106-118, lang:"julia"](code/julia/flood_fill.jl) +[import:92-104, lang:"julia"](code/julia/flood_fill.jl) {% sample lang="c" %} -[import:180-195, lang:"c"](code/c/flood_fill.c) +[import:174-189, lang:"c"](code/c/flood_fill.c) {% sample lang="py" %} -[import:58-66, lang="python"](code/python/flood_fill.py) -{% endmethod %} - -All code snippets for this chapter rely on an exterior `color` function, defined as - -{% method %} -{% sample lang="jl" %} -[import:23-35, lang:"julia"](code/julia/flood_fill.jl) -{% sample lang="c" %} -[import:28-32, lang:"c"](code/c/flood_fill.c) -{% sample lang="py" %} -[import:10-11, lang="python"](code/python/flood_fill.py) +[import:55-63, lang="python"](code/python/flood_fill.py) {% endmethod %} The above code continues recursing through available neighbors as long as neighbors exist, and this should work so long as we are adding the correct set of neighbors. @@ -129,11 +118,11 @@ Additionally, it is possible to do the same type of traversal by managing a stac {% method %} {% sample lang="jl" %} -[import:57-77, lang:"julia"](code/julia/flood_fill.jl) +[import:43-63, lang:"julia"](code/julia/flood_fill.jl) {% sample lang="c" %} -[import:85-108, lang:"c"](code/c/flood_fill.c) +[import:79-102, lang:"c"](code/c/flood_fill.c) {% sample lang="py" %} -[import:30-39, lang="python"](code/python/flood_fill.py) +[import:27-36, lang="python"](code/python/flood_fill.py) {% endmethod %} This is ultimately the same method of traversal as before; however, because we are managing our own data structure, there are a few distinct differences: @@ -170,11 +159,11 @@ The code would look something like this: {% method %} {% sample lang="jl" %} -[import:80-104, lang:"julia"](code/julia/flood_fill.jl) +[import:66-90, lang:"julia"](code/julia/flood_fill.jl) {% sample lang="c" %} -[import:155-178, lang:"c"](code/c/flood_fill.c) +[import:149-172, lang:"c"](code/c/flood_fill.c) {% sample lang="py" %} -[import:41-56, lang="python"](code/python/flood_fill.py) +[import:38-53, lang="python"](code/python/flood_fill.py) {% endmethod %} Now, there is a small trick in this code that must be considered to make sure it runs optimally.