I’m still a newbie in Python, so please tolerate my poor syntax and logic if any were bad. Anyhow, I have a function that I’m trying to cleanly (no fancy moves please) break out of a recursive loop. It’s a function in a program that iterate through recursively of 1s and 0s (see input file below), and identify the adjacent 0s as distinct subsets. I have a recursive function called “checkAllInOneDirection” that will loop through each position, going right, left, up, down positions to check for 0s. (It goes only one left deep/further on each of the 4 directions for each recursion).
The problem is for some reason the output of third set should detect only 0,9 and 0,10 as one distinct set but when it breaks out of the recursive after the second set detection, it picked up [0, 4] and [1, 3] at the beginning of the check of the third set… Any help?
This is the output [row, column]:
Distinct subset found : [[0, 0]]
Distinct subset found : [[0, 3], [0, 4], [1, 3], [0, 5], [1, 4], [1, 5]]
Distinct subset found : [[0, 9], [0, 4], [1, 3], [0, 10]]
The correct third subset should be only :
Distinct subset found : [[0, 9], [0, 10]]
Here’s a sample input file:
01100011100100000
11100011111111011
10011111101011011
Here’s a snippet of the function, it’s called “checkAllInOneDirection”:
isItLast = checkLast(forBoo, bakBoo, upBoo, dwnBoo)
if isItLast:
for each in tempCatch:
if not each in finalCatch:
finalCatch.append(each)
tempCatch=[]
for each in newCatch:
if not each in finalCatch:
finalCatch.append(each)
newCatch=[]
return finalCatch, newCatch, columnCount, rowCount, width, height, posToCheck, forBoo, bakBoo, upBoo, dwnBoo
else:
for each in tempCatch:
if not each in finalCatch:
finalCatch.append(each)
tempCatch =[]
for each in newCatch:
if not each in finalCatch:
finalCatch.append(each)
tempCatch.append(each)
newCatch = []
return checkAllInOneDirection(finalCatch,tempCatch,recursiveCount,newCatch, columnCount, rowCount, width, height, posToCheck, forBoo, bakBoo, upBoo, dwnBoo)
Here’s the entire function, hope it only clarifies not make my question any more confusing:
def checkAllInOneDirection(finalCatch,tempCatch,recursiveCount,newCatch, columnCount, rowCount, width, height, posToCheck, forBoo, bakBoo, upBoo, dwnBoo):
for each in range (0, len(tempCatch)):
posToCheck = posToCheckBak = posToCheckUp = posToCheckDwn = [tempCatch[each][0], tempCatch[each][1]]
newPosForward = checkForward(posToCheck, width)
if newPosForward != False:
tempLocale = locale[newPosForward[0]][newPosForward[1]]
elif newPosForward == False:
tempLocale = 1
if newPosForward != False and tempLocale ==0 and not newPosForward in finalCatch and not newPosForward in newCatch:
forVal = locale[newPosForward[0]][newPosForward[1]]
newCatch.append(newPosForward)
posToCheck = newPosForward
forBoo = True
elif newPosForward == False and tempLocale == 1 and not newPosForward in newCatch:
forBoo = False
newPosBackward = checkBackward(posToCheckBak)
if newPosBackward != False:
tempLocale = locale[newPosBackward[0]][newPosBackward[1]]
elif newPosBackward == False:
tempLocale = 1
if newPosBackward != False and tempLocale ==0 and not newPosBackward in finalCatch and not newPosBackward in newCatch:
forVal = locale[newPosBackward[0]][newPosBackward[1]]
newCatch.append(newPosBackward)
posToCheckBak = newPosBackward
bakBoo = True
elif newPosBackward == False and tempLocale == 1 and not newPosBackward in newCatch:
bakBoo = False
newPosUp = checkUpRow(posToCheckUp)
if newPosUp != False:
tempLocale = locale[newPosUp[0]][newPosUp[1]]
elif newPosUp == False:
tempLocale = 1
if newPosUp != False and tempLocale ==0 and not newPosUp in finalCatch and not newPosUp in newCatch:
forVal = locale[newPosUp[0]][newPosUp[1]]
newCatch.append(newPosUp)
posToCheckUp = newPosUp
upBoo = True
elif newPosUp == False and tempLocale == 1 and not newPosUp in newCatch:
upBoo = False
newPosDwn = checkDwnRow(posToCheckDwn, height)
if newPosDwn != False:
tempLocale = locale[newPosDwn[0]][newPosDwn[1]]
elif newPosDwn == False:
tempLocale = 1
if newPosDwn != False and tempLocale ==0 and not newPosDwn in finalCatch and not newPosDwn in newCatch:
forVal = locale[newPosDwn[0]][newPosDwn[1]]
newCatch.append(newPosDwn)
posToCheckDwn = newPosDwn
dwnBoo = True
elif newPosDwn == False and tempLocale == 1 and not newPosDwn in newCatch:
dwnBoo = False
isItLast = checkLast(forBoo, bakBoo, upBoo, dwnBoo)
if isItLast:
for each in tempCatch:
if not each in finalCatch:
finalCatch.append(each)
tempCatch=[]
for each in newCatch:
if not each in finalCatch:
finalCatch.append(each)
newCatch=[]
return finalCatch, newCatch, columnCount, rowCount, width, height, posToCheck, forBoo, bakBoo, upBoo, dwnBoo
else:
for each in tempCatch:
if not each in finalCatch:
finalCatch.append(each)
tempCatch =[]
for each in newCatch:
if not each in finalCatch:
finalCatch.append(each)
tempCatch.append(each)
newCatch = []
return checkAllInOneDirection(finalCatch,tempCatch,recursiveCount,newCatch, columnCount, rowCount, width, height, posToCheck, forBoo, bakBoo, upBoo, dwnBoo)
When using recursion, you really shouldn’t be using phrases like “loop” and “break.” Instead, think of the problem as consisting of similar subproblems that become trivial at the base cases.
Your general problem is to find
0‘s that are next to other0‘s. (This is called a 4-direction flood fill, by the way.) So the larger problem has identical subproblems; the list of all the connected0‘s is the same as the combination of:00‘s to the right of the “start point”00‘s to the left of the “start point”00‘s above the “start point”00‘s below the “start point”0So somewhere in your recursive function, you’ll have something to the effect of:
Knowing this, you need to then think about your base cases, the cases where
getConnectedZeros()will have to return something different than the combination of its subproblems’ solutions. To me, the base cases are:10that has already been “found”For both cases, simply returning an empty list will work since when
[]is returned, it is in place of more recursive calls. If these conditions were not included, then the recursion would run forever, and neverbreakhit a base case.Based on those ideas, here is a solution to your problem:
Hopefully that helps some. (And hopefully it was coherent, it’s 5 am here…)