Example

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:
7 1 3 6 4.
Person 1 takes 7 from the list and asks Person 2 to
sort the list 1 3 4 6. Person 2 takes 1 from the list and
ask Person 3 to sort 3 4 6. 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 3 4 6. Person 2 adds 1 to the list giving 1 3 4
6, and Person 1 adds 7 back in, which yields 1 3 4 6
7, 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 N2 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 * log2(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 log2(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.