# Sort three variables

**Sort three variables**

You are encouraged to solve this task according to the task description, using any language you may know.

**Sorting Algorithm**

This is a sorting algorithm. It may be applied to a set of data in order to sort it.

**O(**

*n*log*n*) SortsHeapsort | Mergesort | Quicksort

**O(**

*n*log^{2}*n*) SortsShell Sort

**O(**

*n*^{2}) SortsBubble sort | Cocktail sort | Comb sort | Gnome sort | Insertion sort | Selection sort | Strand sort

**Other Sorts**

Bead sort | Bogosort | Counting sort | Pancake sort | Permutation sort | Radix sort | Sleep sort | Stooge sort |

**Sort three variables**

- Task

Sort (the values of) three variables (**X**, **Y**, and **Z**) that contain any value (numbers and/or literals).

If that isn't possible in your language, then just sort numbers (and note if they can be floating point, integer, or other).

I.E.: (for the three variables **x**, **y**, and **z**), where:

x = 'lions, tigers, and' y = 'bears, oh my!' z = '(from the "Wizard of OZ")'

After sorting, the three variables would hold:

x = '(from the "Wizard of OZ")' y = 'bears, oh my!' z = 'lions, tigers, and'

For numeric value sorting, use:

I.E.: (for the three variables **x**, **y**, and **z**), where:

x = 77444 y = -12 z = 0

After sorting, the three variables would hold:

x = -12 y = 0 z = 77444

The variables should contain some form of a number, but specify if the algorithm used can be for floating point or integers. Note any limitations.

The values may or may not be unique.

The method used for sorting can be any algorithm; the goal is to use the most idiomatic in the computer programming language used.

More than one algorithm could be shown if one isn't clearly the better choice.

One algorithm could be:

Θ store the three variablesx,y, andzinto an array (or a list)A

Θ sort (the three elements of) the arrayA

Θ extract the three elements from the array and place them in the variablesx,y, andzin order of extraction

Show the results of the sort here on this page using at least the values of those shown above.

## ALGOL 68[edit]

This uses Algol 68's UNION facility which allows a variable to have values of a number of types whilst maintaining Algol 68's strong-typing.

Assignment allows any value of one of the UNION MODEs to be directly assigned to the variable.
When using the variable, its MODE (type) and value must be tested and extracted using a CASE construct.

As the task only requires sorting three values, we use a simple, three-element specific sort routine.

BEGIN

# MODE that can hold integers and strings - would need to be extended to #

# allow for other types #

MODE INTORSTRING = UNION( INT, STRING );

# returns TRUE if a is an INT, FALSE otherwise #

OP ISINT = ( INTORSTRING a )BOOL: CASE a IN (INT): TRUE OUT FALSE ESAC;

# returns TRUE if a is an INT, FALSE otherwise #

OP ISSTRING = ( INTORSTRING a )BOOL: CASE a IN (STRING): TRUE OUT FALSE ESAC;

# returns the integer in a or 0 if a isn't an integer #

OP TOINT = ( INTORSTRING a )INT: CASE a IN (INT i): i OUT 0 ESAC;

# returns the string in a or "" if a isn't a string #

OP TOSTRING = ( INTORSTRING a )STRING: CASE a IN (STRING s): s OUT "" ESAC;

# returns TRUE if a < b, FALSE otherwise #

# a and b must have the same type #

PRIO LESSTHAN = 4;

OP LESSTHAN = ( INTORSTRING a, b )BOOL:

IF ISSTRING a AND ISSTRING b THEN

# both strings #

TOSTRING a < TOSTRING b

ELIF ISINT a AND ISINT b THEN

# both integers #

TOINT a < TOINT b

ELSE

# different MODEs #

FALSE

FI # LESSTHAN # ;

# exchanges the values of a and b #

PRIO SWAP = 9;

OP SWAP = ( REF INTORSTRING a, b )VOID: BEGIN INTORSTRING t := a; a := b; b := t END;

# sorts a, b and c #

PROC sort 3 = ( REF INTORSTRING a, b, c )VOID:

BEGIN

IF b LESSTHAN a THEN a SWAP b FI;

IF c LESSTHAN a THEN a SWAP c FI;

IF c LESSTHAN b THEN b SWAP c FI

END # sort 3 # ;

# task test cases #

INTORSTRING x, y, z;

x := "lions, tigers, and";

y := "bears, oh my!";

z := "(from the ""Wizard of OZ"")";

sort 3( x, y, z );

print( ( x, newline, y, newline, z, newline ) );

x := 77444;

y := -12;

z := 0;

sort 3( x, y, z );

print( ( x, newline, y, newline, z, newline ) )

END

- Output:

(from the "Wizard of OZ") bears, oh my! lions, tigers, and -12 +0 +77444

## Fortran[edit]

Fortran does not offer a multi-mode facility whereby a variable can be the union of various basic types such as integer or floating-point or character. The EQUIVALENCE statement can cause three such different variables to be placed at the same storage location or indeed, because parameter type-checking is rarely performed by a Fortran compiler (especially with routines compiled separately) it is often possible to pass a floating-point variable to a subroutine expecting an integer, and so forth. Leaving aside questions of storage size mismatch (as when a subroutine stores a sixty-four bit double-precision value into a parameter it had been supplied as a sixteen-bit integer, say) the bit patterns of disparate types will rarely involve a useful ordering. For example, an eight-byte floating-point variable could contain the bit pattern of "Hi There" but the numerical value that will manifest will not likely be useful in sorting text. Though it could be. Imagine having a collection of eight-character codes that is to be searched frequently by a binary chop method. If the actual ordering is unimportant, they could be both sorted and searched as REAL*8 variables, dealing with all eight characters at one blow. However, given the modern floating-point usage of Not-a-Number and the like, it would probably be safer to work with integer variables so that every bit pattern would be distinct. Alas, on the B6700, the high-order bit of its 48-bit word was not used in arithmetic so if an eight-bit character code were placed in the high-order eight bits, some character codes were not distinguished.

It is possible to use floating-point variables to store integer values and their ordering will be sensible, but the bit patterns of integer and floating-point values are usually very different. Again, a subroutine that is supplied integer variables (even of the right size) but which works with floating-point variables (or *vice-versa*) will not produce a sensible ordering. Except perhaps on a B6700 where integer values were represented as floating-point numbers with no fractional part. Operations such as add, subtract, and multiply proceeded as normal while divide discarded any resulting fractional part.

The most flexible type of variable is text, as the text can represent any type of value - but as text, not as a proper number. The ordering resulting from numbers represented as text will be very dependent on their format. This is discussed in Natural_sorting for example.

The example source uses F90 mainly to enable the contained routine SWAPC though it could be made into a separate subroutine. Further F90 facilities would allow the definition of a "generic" SORT3 routine, with a lot of syntax that would enable a SORT3I2, SORT3I4, SORT3F4, *etc.* routines for INTEGER*2, INTEGER*4, REAL*4, *etc.* to be selected for each case. A suitable pre-processor scheme could perhaps generate these variations, but alas, it is not standard. There would be similar requirements for a SWAP routine for each type of parameter, for alas, Fortran does not define a SWAP statement. The temporary variable needed for the SWAP process is defined rather intimidatingly as having the size of the largest of the three parameters; prior to F90 variables defined in a routine could only have a size defined at compile time, which would have to be "surely big enough". Rather than have this redefined for each invocation of SWAPC (where it would be the larger of the two parameters) it is defined once in SORT3. However, all three parameters should be the same size, or risk truncation. Using a great deal more syntax (or, as standardised in F2003) it is possible to have character variables be resized on each assignment to them to accommodate the length of text being assigned.

TYPE(MONGREL)

INTEGER TYPEIS

INTEGER VI

REAL VF

CHARACTER*(enuff) VC

...etc...

END TYPE MONGREL

TYPE (MONGREL) DOG

So that DOG.TYPEIS would indicate which component to access. Still further ploys would enable storage to be allocated only for the type currently in use, especially for CHARACTER variables, and via a great deal more syntax defining how to perform operations such as .GT. and the like, MONGREL type variables can be used in expressions involving such operators just as can variables of the basic types. This sort of approach is demonstrated in Arithmetic/Rational#Fortran, but otherwise, every reference to a MONGREL will involve some sort of CASE statement to select the appropriate usage, hopefully of related types only. Serious computation with such MONGREL variables surely will not be speedy and thus would be un-Fortrannish. What to do when a text string meets a complex number remains obscure - convert the number to a text (but, what format?), does the text represent a number? And what type results from such miscegnation?

Routines that modify their parameters should not be invoked with constants (or text literals) as such parameters... Some systems allow constants to be in protected storage, and if so, an attempt to modify such storage will produce a run-time error. Otherwise, it all depends on how constants are passed as parameters. If a temporary storage item is loaded with the desired value and the address of that scratch variable is passed, then disaster will be averted - though good results may not be produced.

For convenience in setting up the two examples, an array is used to hold the test data. The subroutine is not invoked with an array parameter, it is invoked with three separate elements of the array. The DATA statement initialising the array looks to be the transpose of the desired ordering, because of the way Fortran orders elements in storage.SUBROUTINE SORT3(X,Y,Z) !Perpetrate a bubblesort in-line.

CHARACTER*(*) X,Y,Z !Just three to rearrange.

CHARACTER*(MAX(LEN(X),LEN(Y),LEN(Z))) T !Really, they should all be the same length.

IF (X.GT.Y) CALL SWAPC(X,Y) !The first pass: for i:=2:3 do if a(i - 1) > a(i) swap

IF (Y.GT.Z) CALL SWAPC(Y,Z) !The second test of the first pass.

IF (X.GT.Y) CALL SWAPC(X,Y) !The second pass: for i:=2:2...

CONTAINS !Alas, Fortran does not offer a SWAP statement.

SUBROUTINE SWAPC(A,B) !So, one must be devised for each case.

CHARACTER*(*) A,B !To have their content swapped.

T = A !Ccpy the first to a safe space.

A = B !Copy the second on to the first.

B = T !Copy what had been first to the second.

END SUBROUTINE SWAPC !One of these will be needed for each type of datum.

END SUBROUTINE SORT3 !No attempt is made to stop early, as for already-ordered data.

PROGRAM POKE

CHARACTER*28 XYZ(3,2) !Encompass the two examples.

DATA XYZ/ !Storage order is "column-major".

1 'lions, tigers, and','bears, oh my!','(from the "Wizard of OZ")', !So (1,1), (2,1), (3,1)

2 '77444',' -12',' 0'/ !So this looks like a transposed array. But (1,2), (2,2), (3,2)

INTEGER I !A stepper for the loop.

DO I = 1,2 !Two examples.

WRITE (6,66) "Supplied: ", XYZ(1:3,I) !As given.

66 FORMAT (A12,3(" >",A,"<")) !Show as >text< for clarity.

CALL SORT3(XYZ(1,I),XYZ(2,I),XYZ(3,I)) !Three separate variables, that happen to be in an array.

WRITE (6,66) "Sorted, ? ", XYZ(1:3,I) !The result.

END DO !On to the next example.

END !Nothing much.

Output: the texts showing numbers appear in text order, not the order of their numbers. Incidentally, not everything is done in ASCII. The EBCDIC ordering is different.

Supplied: >lions, tigers, and < >bears, oh my! < >(from the "Wizard of OZ") < Sorted, ? >(from the "Wizard of OZ") < >bears, oh my! < >lions, tigers, and < Supplied: >77444 < > -12 < > 0 < Sorted, ? > 0 < > -12 < >77444 <

## Kotlin[edit]

Kotlin's standard library contains a sort() function which can sort any generic array whose element type has a defined ordering between its instances. This includes strings, integers and floats examples of which are shown below:

// version 1.1.2

inline fun <reified T : Comparable<T>> sortThree(x: T, y: T, z: T): Triple<T, T, T> {

val a = arrayOf(x, y, z)

a.sort()

return Triple(a[0], a[1], a[2])

}

fun <T> printThree(x: T, y: T, z: T) = println("x = $x\ny = $y\nz = $z\n")

fun main(args: Array<String>) {

var x = "lions, tigers, and"

var y = "bears, oh my!"

var z = """(from the "Wizard of OZ")"""

val t = sortThree(x, y, z)

x = t.first

y = t.second

z = t.third

printThree(x, y, z)

var x2 = 77444

var y2 = -12

var z2 = 0

val t2 = sortThree(x2, y2, z2)

x2 = t2.first

y2 = t2.second

z2 = t2.third

printThree(x2, y2, z2)

var x3 = 174.5

var y3 = -62.5

var z3 = 41.7

val t3 = sortThree(x3, y3, z3)

x3 = t3.first

y3 = t3.second

z3 = t3.third

printThree(x3, y3, z3)

}

- Output:

x = (from the "Wizard of OZ") y = bears, oh my! z = lions, tigers, and x = -12 y = 0 z = 77444 x = -62.5 y = 41.7 z = 174.5

## Lua[edit]

Essentially the same as the example algorithm except that the function is variadic. Sorting is done by the in-built table.sort and copying the unknown number of variables in and out of the table is made simple by the (...) in the parameter list and the unpack function respectively.

function variadicSort (...)

local t = {}

for _, x in pairs{...} do

table.insert(t, x)

end

table.sort(t)

return unpack(t)

end

local testCases = {

{ x = 'lions, tigers, and',

y = 'bears, oh my!',

z = '(from the "Wizard of OZ")'

},

{ x = 77444,

y = -12,

z = 0

}

}

for i, case in ipairs(testCases) do

x, y, z = variadicSort(case.x, case.y, case.z)

print("\nCase " .. i)

print("\tx = " .. x)

print("\ty = " .. y)

print("\tz = " .. z)

end

- Output:

Case 1 x = (from the "Wizard of OZ") y = bears, oh my! z = lions, tigers, and Case 2 x = -12 y = 0 z = 77444

## Perl 6[edit]

Perl 6 has a built in sort routine which uses a variation of quicksort. The built in sort routine will automatically select a numeric sort if given a list of Real numeric items and a lexical Unicode sort if given a list that contains strings. The default numeric sort won't sort complex numbers unless you give it a custom comparitor. It is trivial to modify the sort comparitor function to get whatever ordering you want though.

The list (77444, -12, 0) is a poor choice to demonstrate numeric sort since it will sort the same numerically or lexically. Instead we'll use (7.7444e4, -12, 18/2). ( A Num, an Int, and a Rat. )

# Sorting strings. Added a vertical bar between strings to make them discernable

my ($a, $b, $c) = 'lions, tigers, and', 'bears, oh my!', '(from "The Wizard of Oz")';

say "sorting: {($a, $b, $c).join('|')}";

say ($a, $b, $c).sort.join('|'), ' - standard lexical string sort';

# Sorting numeric things

my ($x, $y, $z) = 7.7444e4, -12, 18/2;

say "\nsorting: $x $y $z";

say ($x, $y, $z).sort, ' - standard numeric sort, low to high';

# Or, with a modified comparitor:

for -*, ' - numeric sort high to low',

~*, ' - lexical "string" sort',

*.chars, ' - sort by string length short to long',

-*.chars, ' - or long to short'

-> $comparitor, $type {

my ($x, $y, $z) = 7.7444e4, -12, 18/2;

say ($x, $y, $z).sort( &$comparitor ), $type;

}

say '';

# sort ALL THE THINGS

# sorts by lexical order with numeric values by magnitude.

.say for ($a, $b, $c, $x, $y, $z).sort;

- Output:

sorting: lions, tigers, and|bears, oh my!|(from "The Wizard of Oz") (from "The Wizard of Oz")|bears, oh my!|lions, tigers, and - standard lexical string sort sorting: 77444 -12 9 (-12 9 77444) - standard numeric sort, low to high (77444 9 -12) - numeric sort high to low (-12 77444 9) - lexical "string" sort (9 -12 77444) - sort by string length short to long (77444 -12 9) - or long to short (from "The Wizard of Oz") -12 9 77444 bears, oh my! lions, tigers, and

## REXX[edit]

Since Classic REXX has no native sorting built-in, here is an alternative algorithm.

### generic[edit]

This version will sort numbers and/or literals.

The literals can be of any length (only limited by virtual memory or language limitations).

/*REXX program sorts three (any value) variables (X, Y, and Z) into ascending order.*/

parse arg x y z . /*obtain the three variables from C.L. */

if x=='' | x=="," then x= 'lions, tigers, and' /*Not specified? Use the default*/

if y=='' | y=="," then y= 'bears, oh my!' /* " " " " " */

if z=='' | z=="," then z= '(from "The Wizard of Oz")' /* " " " " " */

say '───── original value of X: ' x

say '───── original value of Y: ' y

say '───── original value of Z: ' z

if x>y then do; _=x; x=y; y=_; end /*swap the values of X and Y. */ /* ◄─── sorting.*/

if y>z then do; _=y; y=z; z=_; end /* " " " " Y " Z. */ /* ◄─── sorting.*/

if x>y then do; _=x; x=y; y=_; end /* " " " " X " Y. */ /* ◄─── sorting */

say /*stick a fork in it, we're all done. */

say '═════ sorted value of X: ' x

say '═════ sorted value of Y: ' y

say '═════ sorted value of Z: ' z

- output when using the default inputs:

───── original value of X: lions, tigers, and ───── original value of Y: bears, oh my! ───── original value of Z: (from "The Wizard of Oz") ═════ sorted value of X: (from "The Wizard of Oz") ═════ sorted value of Y: bears, oh my! ═════ sorted value of Z: lions, tigers, and

### numeric only[edit]

This version will sort numbers (the numbers can be in any form, floating point and/or integer).

The maximum integer than be kept *as an integer* is (in this program) is 1,000 decimal digits.

/*REXX program sorts three (numeric) variables (X, Y, and Z) into ascending order. */

numeric digits 1000 /*handle some pretty gihugic integers. */ /*can be bigger.*/

parse arg x y z . /*obtain the three variables from C.L. */

if x=='' | x=="," then x= 77444 /*Not specified? Then use the default.*/

if y=='' | y=="," then y= -12 /* " " " " " " */

if z=='' | z=="," then z= 0 /* " " " " " " */

w=max( length(x), length(y), length(z) ) + 5 /*find max width of the values, plus 5.*/

say '───── original values of X, Y, and Z: ' right(x, w) right(y, w) right(z, w)

low = x /*assign a temporary variable. */ /* ◄─── sorting.*/

mid = y /* " " " " */ /* ◄─── sorting.*/

high= z /* " " " " */ /* ◄─── sorting.*/

x=min(low, mid, high) /*determine the lowest value of X,Y,Z. */ /* ◄─── sorting.*/

z=max(low, mid, high) /* " " highest " " " " " */ /* ◄─── sorting.*/

y= low + mid + high - x - z /* " " middle " " " " " */ /* ◄─── sorting.*/

/*stick a fork in it, we're all done. */

say '═════ sorted values of X, Y, and Z: ' right(x, w) right(y, w) right(z, w)

- output when using the default inputs:

───── original values of X, Y, and Z: 77444 -12 0 ═════ sorted values of X, Y, and Z: -12 0 77444

## zkl[edit]

This solution uses list assignment and list sorting. Lists are not homogeneous, but sorting usually expects that. If that is a problem, you can give the sort a compare function. Numbers (real and integer) are homogeneous enough to sort.

x,y,z := "lions, tigers, and", "bears, oh my!", 0'|(from the "Wizard of OZ")|;

x,y,z = List(x,y,z).sort();

println(x," | ",y," | ",z);

x,y,z := 77444, -12, 0;

x,y,z = List(x,y,z).sort();

println(x," ",y," ",z);

- Output:

(from the "Wizard of OZ") | bears, oh my! | lions, tigers, and -12 0 77444