Reputation: 5341
I know what call stack size exceeded
means but I need a way around it.
I get it when I call this recursive function
function fill(x_y) {
var locColor = getPx(x_y[0], x_y[1]);
if (locColor != pref.color) {
setPx(x_y[0], x_y[1], pref.color);
if (getPx(x_y[0] - 1, x_y[1]) == locColor) {
fill([x_y[0] - 1, x_y[1]]);
}
if (getPx(x_y[0], x_y[1] - 1) == locColor) {
fill([x_y[0], x_y[1] - 1]);
}
if (getPx(x_y[0] + 1, x_y[1]) == locColor) {
fill([x_y[0] + 1, x_y[1]]);
}
if (getPx(x_y[0], x_y[1] + 1) == locColor) {
fill([x_y[0], x_y[1] + 1]);
}
}
}
It's for a canvas application.
x_y
is simply x and y coordinates where fill was called.
setPx
prints a rectangle on the canvas given coordinates.
getPx
gets the color of a rectangle of the canvas given it's coordinates
pref.color
is the color that the user has selected for setPx
Can this function be done without recursion?
Upvotes: 0
Views: 670
Reputation: 24324
This fills in order:
(unless I got the coordinates system wrong).
You can do a solution without recursion by using a list of x_y
to process; and instead of using the stack for recursion, you use the list for storing the parameters for your next calls.
function fill(x_y) {
var todo = [x_y];
var iniColor = getPx(x_y[0], x_y[1]);
while (todo.length) {
var curr = todo[0];
var locColor = getPx(curr[0], curr[1]);
todo = todo.slice(1);
if (locColor != iniColor) { continue; }
if (locColor == pref.color) { continue; }
setPx(curr[0], curr[1], pref.color);
todo.push([curr[0]-1,curr[1] ]);
todo.push([curr[0], curr[1]-1]);
todo.push([curr[0]+1,curr[1] ]);
todo.push([curr[0], curr[1]+1]);
}
}
UPDATE: 2015-03-01
From the comments, this is not as good as the algorithm in the question because of the number of iterations. In this block, I didn't check the condition early, which means they are added to the todo
list even though they may not be good candidates. And when the point is processed later, the condition is checked.
todo.push([curr[0]-1,curr[1] ]);
todo.push([curr[0], curr[1]-1]);
todo.push([curr[0]+1,curr[1] ]);
todo.push([curr[0], curr[1]+1]);
Solution: check early as in the question; before calling push
.
Upvotes: 1