Sort Four
April 11, 2017
Today’s exercise involves sorting:
Write a program that takes exactly four items as input and returns them in sorted order.
Your task is to write a program that sorts exactly four items; can you do it using only five comparisons? When you are finished, you are welcome to read or run a suggested solution, or to post your own solution or discuss the exercise in the comments below.
Like this?
Two versions using Clojure:
Here’s a depth-3 Parallel Fouring Machine program, P, tested with an interpreter written in Python (see below). Parallel Fouring Machine programs are binary trees of commands that act on four registers so that each command sorts both the two indicated registers and the two complementary registers, in parallel, and they continue to the left branch if either pair was swapped, else to right.
Clearly this program P always executes the same three parallel comparisons, so it corresponds to six sequential comparisons. Is off by one close enough? (I was not able to generate even all depth-4 Sequential Fouring Machine programs, let alone enough of the required depth-5. It was a combinatorial explosion, and I had no ideas to prune the search space. So I went on to discover the Parallel Fouring Machine instead. For the Journal of Negative Results, maybe.)
Here’s the interpreter, F, in Python.
There are only 36 depth-3 Parallel Fouring Machine programs that always sort the four registers. Some might contain the clue to the 5-step sequential sorting problem, if they were investigated more closely.
For such a small number of items to sort, we will avoid memory writes, by expanding the decision tree, and keeping the four elements in registers until it’s time to store them in the resulting sorted vector. Between 4 and 5 tests are needed to reach the leaves of the decision tree (on average for equiprobable permutations: 4.5).
@Mike, I should have had the courage :) Here’s an interpreter for a simpler Fouring Machine whose six opcodes just sort a pair of registers without branching anywhere. A program is a sequence of opcodes.
It’s a combinatorial piece of cake to generate a 5-command solution now. There are 12. Here’s one, which turns out to be precisely your (Mike’s) solution.
One could write a compiler to get a Python (or Scheme (or C (or why not some assembler))) program.
This is Scheme.
This scheme version is nice, but scheme compilers won’t be able to avoid the fifth comparison, when it’s useless. You will get exactly 5 comparison, why the Common Lisp expanded version has 4.5 comparisons on average.
MUMP V1:
SORT4 ;New routine
1 (N1,N2,N3,N4) ;
N ARR,I
; When the numbers are placed into the array “ARR”, they are automatically placed in sorted order
F I=N1,N2,N3,N4 S ARR(I)=””
; Write the numbers starting at the least
S I=”” F S I=$O(ARR(I)) Q:I=”” W !,I
Q
MCL> D 1^SORT4(99,87,65,7)
7
65
87
99
Here’s a solution in x86 assembly.
Here’s a C program that calls the function.
Example usage:
Output: