Pass the Buck Every good programmer is lazy, arrogant, and impatient. In the game “Pass the Buck” you try to do as little work as possible, by making your neighbor do most of the work. Your neighbor is nearly as smart as you, and can do what you can do – almost, so the problem that you give your name has to be (at least) a little smaller than the problem that you have to solve.
Example Suppose that you are asked to sort a list of 10 numbers. Instead of doing all the work, you just take the first number off the list, and then pass the buck to your neighbor – you ask your neighbor to sort the remaining list of 9 numbers. When your neighbor gives you his or her answer, you just have to insert that first number back into the right place in the list and you're done.
Pass the Buck (cont'd) You pass the buck to your neighbor. Your neighbor is also lazy, and will try to do as little work as possible by playing Pass the Buck. So, your neighbor, in this example, will take the first number from the list and then pass the buck to his or her neighbor, who does the same thing. And so on and so on, until...
The Idiot Case The buck is passed until the problem is so simple, that any idiot could solve it (the idiot case.) In our example, this would be the list with just one number. So, the last person – the idiot – just solves the problem directly, and returns the answer to the neighbor who gave it to him or her. That person finds the solution to their problem, and returns it to their neighbor who gave them the problem...
Example In the problem is to sort a list of five numbers: Person 1 takes 7 from the list and asks Person 2 to sort the list Person 2 takes 1 from the list and ask Person 3 to sort Person 3 takes 3 from the list and asks Person 4 to sort 4 6. Person 4 takes 6 from the list and asks Person 5 to sort the list 4. This is the idiot case, so Person 6 returns 4.
Example (cont'd) Person 4 then adds 6 in the proper place and gives back the list 4 6. Person 3 adds 3 back to the list, giving Person 2 adds 1 to the list giving , and Person 1 adds 7 back in, which yields , the correct answer.
Another Example Suppose instead of just taking the first number from the list, Person 1 (and hence everyone else, since they all should do the same thing except for the idiot), finds the smallest number from the list and removes that number. Then, after passing the buck and getting back the list from Person 2, Person 1 just has to stick the smallest number to the beginning of the list to sort the whole list.
Sorting The first example is actually insertion sort, and then second example is selection sort. Is this just another way of writing the sort, or is it more efficient? Each person does a little bit of work, but how much work does everyone do put together? In the first example, each person (except for the idiot), removes the first number which takes constant time, and then later has to put the number back in the right place.
Sorting (cont'd) This takes N-1 comparisons if the list has N numbers. So, Person 1 does 5 – 1 comparisions, Person 2, does 4 – 1 comparisons, and so on...until the idiot who does no comparisons. In general, given a list of size N, Person 1 does N-1 comparisons, Person 2 does N- 2 comparisons...down to 1, then 0 comparison, for a total of N*(N-1)/2 comparisons which is the same as insertion sort.
Other Sorting In the second example, Person 1 finds the smallest number first which takes N-1 comparisons. To finish up the job, Person 1 just sticks the number back at the beginning of the list which is constant time. So, again, the total number of comparisons is N * (N-1)/2 which is the same as selection sort.
The Rules of Pass the Buck Given a problem of size N, you must find a smaller problem of the same type, and give that problem to your neighbor. Your neighbor solves his or her problem and gives you back the solution. You must then extend that solution to be a solution to the original problem. Since your neighbor also passes the back, the problem keeps getting smaller and smaller until any idiot can do it. The idiot solves his or her problem directly and returns the answer.
Tower of Hanoi Problem An example where it's easier to play Pass the Buck then to solve a problem directly is the Tower of Hanoi problem. The puzzle has three wooden pegs. On one peg are place a number of disks of various sizes, with the biggest disk on the bottom and then disks getting smaller as you go up. The problem is to move the stack of disks from the first peg to the third peg.
Tower of Hanoi (cont'd) However, you can only move one disk at a time, and you may not put a larger disk on top of a smaller disk, i.e., a disk can only be moved to an empty peg, or onto a larger disk.
Solution If your problem is to move N disks from peg 1 to peg 3, then you pass the buck by asking your neighbor to move N-1 disks (the top N-1 disks) from peg 1 to peg 2 (the spare peg). Then you move the bottom disk from peg 1 to peg 3. Finally you ask your neighbor to move the stack of N-1 disks from peg 2 to peg 3, completing the entire task. The idiot case is when there is just one disk in the stack – just move the disk directly.
Sorting Redux Another way to sort is to make the list smaller by more than one element. Split the list in half – have a neighbor sort the first half, and then have a neighbor sort the second half. Then you must merge the two sorted lists into one sorted list. Merging takes N-1 comparisons (at worst), so it is simpler than sorting.
Mergesort The idiot case is again, when there is just one number in the list or the list is empty. In both cases, there's nothing to do, just return the list. The first person does N-1 comparisons for the merge step - the split is constant. The second person has to sort a list of size N/2, which takes N/2-1 comparisons, but is asked to do that twice. The third person sorts 4 lists, of size N/4, and so on. The total number of comparison is N * log 2 (N).
Another Sort Another way to split the list of numbers is into a list of small numbers and a list of large numbers. For this example, we will use the first number of the list to decide which numbers are large and which numbers are small. Numbers less than the first number are considered small, and numbers greater than the first number are considered large. We assume no duplicate numbers in this example.
Another Sort (cont'd) So, the first person removes the first number from the list, and then using that number splits the list into two (not necessarily equal) pieces – the numbers that are less than the first number and the numbers that are greater than the first number. The buck is passed (twice) and both sub-lists are sorted. The first person just puts the two lists together with the first number in between them.
How much work is done? It takes linear time to split the list into the two pieces, but only constant time to put the lists back together (assuming that we're working with arrays and keeping the numbers in place). However, since the list isn't split in half, we can't assume that the two lists are size N/2. If we're lucky, and they are, then the time is the same as mergesort, i.e., N log 2 (N).
Worst Case In the worst case, the first number is the smallest number in the list (or the largest) and then all the rest of the numbers fall in the list of large numbers with none in the small number list. So, the buck is passed twice, once with the empty list (an idiot case) and once with a list of size N-1. This becomes (if repeated) the same as insertion sort, i.e., N*(N-1)/2.