I'm trying to adapt this solution to the Code Jam's Dice Straight problem to Python. Unfortunately, it requires too deep recursion to work correctly in Python (unless both recursion limit and stack size are significantly increased). So I'm trying to convert this recursive method to iterative:
/**
* Attempt to recursively free a die by selecting a different die for the same value.
* @return true if the die has been freed, false if no other die can be found.
*/
boolean freeByShuffling(Die die) {
assert die.valueUsing != null;
// First check if we can just use another dice for the previous value
for (Die otherDie : die.valueUsing.dice) {
if (otherDie.valueUsing == null) {
otherDie.valueUsing = die.valueUsing;
die.valueUsing = null;
return true;
}
}
// Nope, we must free a die recursively
diceVisitedWhileShuffling.add(die);
for (Die otherDie : die.valueUsing.dice) {
if (diceVisitedWhileShuffling.contains(otherDie)) continue;
if (freeByShuffling(otherDie)) {
otherDie.valueUsing = die.valueUsing;
die.valueUsing = null;
return true;
}
}
return false;
}
This is my Python code which doesn't quite work, although it solves most test cases:
def free_by_shuffling(self, die):
assert die.current_value is not None
stack = [(None, die)]
found = False
while stack:
this_die, other_die = stack.pop()
self.visited.add(other_die)
if found:
other_die.current_value = this_die.current_value
this_die.current_value = None
continue
for next_die in other_die.current_value.dice:
if next_die in self.visited:
continue
if next_die.current_value is None:
found = True
stack.append((other_die, next_die))
break
else:
for next_die in other_die.current_value.dice:
if next_die in self.visited:
continue
stack.append((other_die, next_die))
return found
How do I convert the original method to use iteration instead of recursion?
This Python implementation works well for both 'small' and 'large' input files:
def free_by_shuffling(self, die):
assert die.current_value is not None
stack = [die]
found = False
while stack:
this_die = stack.pop()
if found:
if stack:
this_die.current_value = stack[-1].current_value
stack[-1].current_value = None
continue
for other_die in this_die.current_value.dice:
if other_die.current_value is None:
stack.extend((this_die, other_die))
found = True
break
else:
self.visited.add(this_die)
for other_die in this_die.current_value.dice:
if other_die not in self.visited:
stack.extend((this_die, other_die))
break
else:
if stack:
for other_die in stack[-1].current_value.dice:
if other_die not in self.visited:
stack.append(other_die)
break
return found
Any comments and suggestions are welcome.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.