Piles Karel and the Art and Skill of Universal Solution
Piles Karel is part of the Stanford Code in Place curriculum and by solving this problem in a strategic way, we learn the art and skill of universal solution.
Piles Karel Problem
Piles Karel is a relatively simple problem. In a 7 by 5 world, there are three piles of beepers in the first row, and Karel should pick them up.
The simplest method would be to get Karel to move to each beeper location and pick all the beepers up, and move to the next pile, etc. The code will look at this following the method:
def main():
move()
while beepers_present():
pick_beeper()
move()
move()
while beepers_present():
pick_beeper()
move()
move()
while beepers_present():
pick_beeper()
move()
if __name__ == '__main__':
main()
Incorporating Decomposition
While the above code does the job, it's hard to read.
Karel really is just doing two things while solving this problem:
- move
- pick up beepers
Move is just ... move, and there is no room for further docomposition. However, we can write a new function to have Karel pick all the beepers on a single spot.
def pick_all_beepers():
While beepers_present():
pick_beeper
So whenever there are beepers present, we can just use pick_all_beepers( ):
def pick_all_beepers():
While beepers_present():
pick_beeper
def main():
move()
pick_all_beepers()
move()
move()
pick_all_beepers()
move()
move()
pick_all_beepers()
move()
if __name__ == '__main__':
main()
What if we don't know the exact size of world and locations of beepers?
Before we were dealing with a certain world with a set size and beeper locations. We are using our human eyes to spot where beepers are located, and we are actually doing half of the work.
How can we write codes so that Karel can deal with an uncertain world? Would Karel be able to identify where beepers are located, pick them up, and stop right in front of the wall?
Recall that Karel does only two things in solving this problem:
- move
- pick up beepers
And Karel should be doing exactly those two things while its front is clear. And because we don't know the exact size of the world - the world could be just ONE single column - meaning that Karel may not be able to move at all, we still need Karel to pick up those beepers in her original spot. After that, Karel should move and pick up beepers until she hits the wall.
The final solution
The code then will look like this:
def main():
pick_all_beeper()
while front_is_clear():
move()
pick_all_beeper()
def pick_all_beeper():
while beepers_present():
pick_beeper()
if __name__ == '__main__':
main()
This solution can work in all sizes of worlds, and it's much more readable by human eyes. Karel is doing exactly what the names of those functions are telling you: she first picks all the beepers in her position, and while her front is clear, she will keep moving and picking all beepers in each spot, on spot at a time, until she faces a wall, i.e. her front is NOT clear.