# This code takes a ridiculously inefficient algorithm and rather futilely
# optimizes one part of it.  Permutations are computed lazily.

sorted_copy = (a) ->
  # This returns a sorted copy of an array by lazily generating
  # permutations of indexes and stopping when the indexes yield
  # a sorted array.
  indexes = [0...a.length]
  ans = find_matching_permutation indexes, (permuted_indexes) ->
    new_array = (a[i] for i in permuted_indexes)
    console.log permuted_indexes, new_array
    in_order(new_array)
  (a[i] for i in ans)

in_order = (a) ->
  # return true iff array a is in increasing order.
  return true if a.length <= 1
  for i in [0...a.length-1]
    return false if a[i] > a[i+1]
  true

get_factorials = (n) ->
  # return an array of the first n+1 factorials, starting with 0!
  ans = [1]
  f = 1
  for i in [1..n]
    f *= i
    ans.push f
  ans

permutation = (a, i, factorials) ->
  # Return the i-th permutation of an array by
  # using remainders of factorials to determine
  # elements.
  while a.length > 0
    f = factorials[a.length-1]
    n = Math.floor(i / f)
    i = i % f
    elem = a[n]
    a = a[0...n].concat(a[n+1...])
    elem
  # The above loop gets treated like
  # an array expression, so it returns
  # all the elements.

find_matching_permutation = (a, f_match) ->
  factorials = get_factorials(a.length)
  for i in [0...factorials[a.length]]
    permuted_array = permutation(a, i, factorials)
    if f_match permuted_array
      return permuted_array
  null

do ->
  a = ['c', 'b', 'a', 'd']
  console.log 'input:', a
  ans = sorted_copy a
  console.log 'DONE!'
  console.log 'sorted copy:', ans


10 'SAVE"SELSORT",A
20 ' Selection Sort Algorithm
30 '
40 ' VAR
50 DEFINT A-Z
60 OPTION BASE 1
70 I=0: J=0: IMINV = 0: IMAX = 0: TP! = 0: TL! = 0
80 '
90 CLS
100 PRINT "This program does the Selection Sort Algorithm"
110 INPUT "Number of elements to sort (Max=1000, Enter=10)";IMAX
120 IF IMAX = 0 THEN IMAX = 10
130 IF IMAX > 1000 THEN IMAX = 1000
140 DIM N(IMAX)
150 ' Creates and shows the unsorted list
160 RANDOMIZE TIMER
170 FOR I=1 TO IMAX: N(I) = I: NEXT I
180 FOR I=1 TO IMAX
190   J = INT(RND*IMAX)+1
200   SWAP N(I), N(J)
210 NEXT I
220 PRINT: PRINT "Unsorted list:";
230 FOR I=1 TO IMAX: PRINT N(I);: NEXT I
240 PRINT: PRINT
250 ' Sorts the list through the Selection Sort Algorithm and shows the results
260 TL! = TIMER
270 PRINT "Sorting"; IMAX; "numbers";
280 COLOR 7+16: X = POS(0): PRINT"...";: COLOR 7
290 ITP = 0
300 FOR I=1 TO IMAX-1
310   IMINV = I
320   FOR J=I+1 TO IMAX
330     IF N(IMINV)>N(J) THEN IMINV = J
340   NEXT J
350   IF IMINV>I THEN SWAP N(IMINV), N(I): TP! = TP! + 1
360 NEXT I
370 LOCATE ,X: PRINT ". Done!"
380 PRINT: PRINT "Sorted list:";
390 FOR I=1 TO IMAX: PRINT N(I);: NEXT I
400 ' Final results
410 PRINT: PRINT: PRINT "Numbers sorted:"; IMAX
420 PRINT "Total permutations done:";TP!
430 PRINT "Time lapse:"; TIMER-TL!; "seconds."
440 PRINT
450 PRINT "End of program"
460 END


(defun factorial (n)
  (loop for result = 1 then (* i result)
        for i from 2 to n
        finally (return result)))

(defun nth-permutation (k sequence)
  (if (zerop (length sequence))
      (coerce () (type-of sequence))
      (let ((seq (etypecase sequence
                   (vector (copy-seq sequence))
                   (sequence (coerce sequence 'vector)))))
        (loop for j from 2 to (length seq)
              do (setq k (truncate (/ k (1- j))))
              do (rotatef (aref seq (mod k j))
                          (aref seq (1- j)))
              finally (return (coerce seq (type-of sequence)))))))

(defun sortedp (fn sequence)
  (etypecase sequence
    (list (loop for previous = #1='#:foo then i
                for i in sequence
                always (or (eq previous #1#)
                           (funcall fn i previous))))
    ;; copypasta
    (vector (loop for previous = #1# then i
                  for i across sequence
                  always (or (eq previous #1#)
                             (funcall fn i previous))))))

(defun permutation-sort (fn sequence)
  (loop for i below (factorial (length sequence))
        for permutation = (nth-permutation i sequence)
        when (sortedp fn permutation)
          do (return permutation)))


def sorted?(items : Array)
    prev = items[0]
    items.each do |item|
        if item < prev
            return false
        end
        prev = item
    end
    return true
end

def permutation_sort(items : Array)
    items.each_permutation do |permutation|
        if sorted?(permutation)
            return permutation
        end
    end
end


import std.stdio, std.algorithm, permutations2;

void permutationSort(T)(T[] items) pure nothrow @safe @nogc {
    foreach (const perm; items.permutations!false)
        if (perm.isSorted)
            break;
}

void main() {
    auto data = [2, 7, 4, 3, 5, 1, 0, 9, 8, 6, -1];
    data.permutationSort;
    data.writeln;
}


get "libhdr"

let selectionsort(A, len) be if len > 1
$(  let minloc = A and t = ?
    for i=0 to len-1
        if !minloc > A!i do minloc := A+i
    t := !A
    !A := !minloc
    !minloc := t
    selectionsort(A+1, len-1)
$)

let writearray(A, len) be
    for i=0 to len-1 do
        writed(A!i, 6)

let start() be
$(  let array = table 52, -5, -20, 199, 65, -3, 190, 25, 9999, -5342
    let length = 10

    writes("Input:  ") ; writearray(array, length) ; wrch('*N')
    selectionsort(array, length)
    writes("Output: ") ; writearray(array, length) ; wrch('*N')
$)


def swap(container, ixA, ixB) {
    def temp := container[ixA]
    container[ixA] := container[ixB]
    container[ixB] := temp
}

/** Reverse order of elements of 'sequence' whose indexes are in the interval [ixLow, ixHigh] */
def reverseRange(sequence, var ixLow, var ixHigh) {
    while (ixLow < ixHigh) {
        swap(sequence, ixLow, ixHigh)
        ixLow += 1
        ixHigh -= 1
    }
}

/** Algorithm from <http://marknelson.us/2002/03/01/next-permutation>, allegedly from a version of the C++ STL */
def nextPermutation(sequence) {
    def last := sequence.size() - 1
    var i := last
    while (true) {
        var ii := i
        i -= 1
        if (sequence[i] < sequence[ii]) {
            var j := last + 1
            while (!(sequence[i] < sequence[j -= 1])) {} # buried side effect
            swap(sequence, i, j)
            reverseRange(sequence, ii, last)
            return true
        }
        if (i == 0) {
            reverseRange(sequence, 0, last)
            return false
        }
    }
}

/** Note: Worst case on sorted list */
def permutationSort(flexList) {
    while (nextPermutation(flexList)) {}
}


;; This efficient sort method uses the list library for permutations

(lib 'list)
(define (in-order L)
(cond
    ((empty? L) #t)
    ((empty? (rest L)) #t)
    (else (and ( < (first L) (second  L)) (in-order (rest L))))))

(define L (shuffle (iota 6)))
    → (1 5 4 2 0 3)

(for ((p (in-permutations (length L ))))
    #:when (in-order (list-permute L p))
       (writeln (list-permute L p)) #:break #t)

    → (0 1 2 3 4 5)


class SelectionSort<T> where T : IComparable {
    public T[] Sort(T[] list) {
        int k;
        T temp;

        for (int i = 0; i < list.Length; i++) {
            k = i;
            for (int j=i + 1; j < list.Length; j++) {
                if (list[j].CompareTo(list[k]) < 0) {
                    k = j;
                }
            }
            temp = list[i];
            list[i] = list[k];
            list[k] = temp;
        }

        return list;
    }
}


defmodule Sort do
  def permutation_sort([]), do: []
  def permutation_sort(list) do
    Enum.find(permutation(list), fn [h|t] -> in_order?(t, h) end)
  end

  defp permutation([]), do: [[]]
  defp permutation(list) do
    for x <- list, y <- permutation(list -- [x]), do: [x|y]
  end

  defp in_order?([], _), do: true
  defp in_order?([h|_], pre) when h<pre, do: false
  defp in_order?([h|t], _), do: in_order?(t, h)
end

IO.inspect list = for _ <- 1..9, do: :rand.uniform(20)
IO.inspect Sort.permutation_sort(list)


USING: grouping io math.combinatorics math.order prettyprint ;
IN: rosetta-code.permutation-sort

: permutation-sort ( seq -- seq' )
    [ [ before=? ] monotonic? ] find-permutation ;

{ 10 2 6 8 1 4 3 } permutation-sort .
"apple" permutation-sort print


' version 07-04-2017
' compile with: fbc -s console

' Heap's algorithm non-recursive
Function permutation_sort(a() As ULong) As ULong

    Dim As ULong i, j, count
    Dim As ULong lb = LBound(a), ub = UBound(a)
    Dim As ULong n = ub - lb +1
    Dim As ULong c(lb To ub)

    While i < n
        If c(i) < i Then
            If (i And 1) = 0 Then
                Swap a(0), a(i)
            Else
                Swap a(c(i)), a(i)
            End If
            count += 1
            For j = lb To ub -1
                If a(j) > a(j +1) Then j = 99
            Next
            If j < 99 Then Return count
            c(i) += 1
            i = 0
        Else
            c(i) = 0
            i += 1
        End If
    Wend

End Function

' ------=< MAIN >=------

Dim As ULong k, p, arr(0 To 9)
Randomize Timer

Print "unsorted array"
For k = LBound(arr) To UBound(arr)
    arr(k) = Rnd * 1000
    Print arr(k) & IIf(k = UBound(arr), "", ", ");
Next
Print : Print

p = permutation_sort(arr())

Print "sorted array"
For k = LBound(arr) To UBound(arr)
    Print arr(k) & IIf(k = UBound(arr), "", ", ");
Next
Print : Print
Print "sorted array in "; p; " permutations"

' empty keyboard buffer
While Inkey <> "" : Wend
Print : Print "hit any key to end program"
Sleep
End


(import 'java.util.ArrayList)

(defn arr-swap! [#^ArrayList arr i j]
  (let [t (.get arr i)]
    (doto arr
      (.set i (.get arr j))
      (.set j t))))

(defn sel-sort!
  ([arr] (sel-sort! compare arr))
  ([cmp #^ArrayList arr]
     (let [n (.size arr)]
       (letfn [(move-min!
		[start-i]
		(loop [i start-i]
		  (when (< i n)
		    (when (< (cmp (.get arr i) (.get arr start-i)) 0)
		      (arr-swap! arr start-i i))
		    (recur (inc i)))))]
	 (doseq [start-i (range (dec n))]
	   (move-min! start-i))
	 arr))))


           PERFORM E-SELECTION VARYING WB-IX-1 FROM 1 BY 1
                               UNTIL WB-IX-1 = WC-SIZE.

...

       E-SELECTION SECTION.
       E-000.
           SET WC-LOWEST   TO WB-IX-1.
           ADD 1 WC-LOWEST GIVING WC-START

           PERFORM F-PASS VARYING WB-IX-2 FROM WC-START BY 1
                          UNTIL WB-IX-2 > WC-SIZE.

           IF WB-IX-1 NOT = WC-LOWEST
              MOVE WB-ENTRY(WC-LOWEST) TO WC-TEMP
              MOVE WB-ENTRY(WB-IX-1)   TO WB-ENTRY(WC-LOWEST)
              MOVE WC-TEMP             TO WB-ENTRY(WB-IX-1).

       E-999.
           EXIT.

       F-PASS SECTION.
       F-000.
           IF WB-ENTRY(WB-IX-2) < WB-ENTRY(WC-LOWEST)
              SET WC-LOWEST TO WB-IX-2.

       F-999.
           EXIT.


package main

import "fmt"

var a = []int{170, 45, 75, -90, -802, 24, 2, 66}

// in place permutation sort of slice a
func main() {
    fmt.Println("before:", a)
    if len(a) > 1 && !recurse(len(a) - 1) {
        // recurse should never return false from the top level.
        // if it does, it means some code somewhere is busted,
        // either the the permutation generation code or the
        // sortedness testing code.
        panic("sorted permutation not found!")
    }
    fmt.Println("after: ", a)
}

// recursive permutation generator
func recurse(last int) bool {
    if last <= 0 {
        // bottom of recursion.  test if sorted.
        for i := len(a) - 1; a[i] >= a[i-1]; i-- {
            if i == 1 {
                return true
            }
        }
        return false
    }
    for i := 0; i <= last; i++ {
        a[i], a[last] = a[last], a[i]
        if recurse(last - 1) {
            return true
        }
        a[i], a[last] = a[last], a[i]
    }
    return false
}


def factorial = { (it > 1) ? (2..it).inject(1) { i, j -> i*j } : 1 }

def makePermutation;
makePermutation = { list, i ->
    def n = list.size()
    if (n < 2) return list
    def fact = factorial(n-1)
    assert i < fact*n

    def index = i.intdiv(fact)
    [list[index]] + makePermutation(list[0..<index] + list[(index+1)..<n], i % fact)
}

def sorted = { a -> (1..<(a.size())).every { a[it-1] <= a[it] } }

def permutationSort = { a ->
    def n = a.size()
    def fact = factorial(n)
    def permuteA = makePermutation.curry(a)
    def pIndex = (0..<fact).find { print "."; sorted(permuteA(it)) }
    permuteA(pIndex)
}


(defun selection-sort-vector (array predicate)
  (do ((length (length array))
       (i 0 (1+ i)))
      ((eql i length) array)
    (do ((mindex i)
         (min (aref array i))
         (j i (1+ j)))
        ((eql j length)
         (rotatef (aref array i) (aref array mindex)))
      (when (funcall predicate (aref array j) min)
        (setf min (aref array j)
              mindex j)))))

(defun selection-sort-list (list predicate)
  (flet ((min-first (list)
           (do ((before-min nil)
                (min (first list))
                (prev list (rest prev))
                (curr (rest list) (rest curr)))
               ((endp curr)
                (if (null before-min) list
                  (let ((min (cdr before-min)))
                    (rplacd before-min (cdr min))
                    (rplacd min list)
                    min)))
             (when (funcall predicate (first curr) min)
               (setf before-min prev
                     min (first curr))))))
    (let ((result (min-first list)))
      (do ((head result (rest head)))
          ((endp (rest head)) result)
        (rplacd head (min-first (rest head)))))))

(defun selection-sort (sequence predicate)
  (etypecase sequence
    (list (selection-sort-list sequence predicate))
    (vector (selection-sort-vector sequence predicate))))


import Control.Monad

permutationSort l = head [p | p <- permute l, sorted p]

sorted (e1 : e2 : r) = e1 <= e2 && sorted (e2 : r)
sorted _             = True

permute              = foldM (flip insert) []

insert e []          = return [e]
insert e l@(h : t)   = return (e : l) `mplus`
                       do { t' <- insert e t ; return (h : t') }


procedure do_permute(l, i, n)
    if i >= n then
        return l
    else
        suspend l[i to n] <-> l[i] & do_permute(l, i+1, n)
 end

 procedure permute(l)
    suspend do_permute(l, 1, *l)
 end

 procedure sorted(l)
    local i
    if (i := 2 to *l & l[i] >= l[i-1]) then return &fail else return 1
 end

 procedure main()
    local l
    l := [6,3,4,5,1]
    |( l := permute(l) & sorted(l)) \1 & every writes(" ",!l)
 end


def selectionSort(array : Array)
    (0...array.size-1).each do |i|
        nextMinIndex = i
        (i+1...array.size).each do |j|
            if array[j] < array[nextMinIndex]
                nextMinIndex = j
            end
        end
        if i != nextMinIndex
            array.swap(i, nextMinIndex)
        end
    end
end


import std.stdio, std.algorithm, std.array, std.traits;

enum AreSortableArrayItems(T) = isMutable!T &&
                                __traits(compiles, T.init < T.init) &&
                                !isNarrowString!(T[]);

void selectionSort(T)(T[] data) if (AreSortableArrayItems!T) {
    foreach (immutable i, ref d; data)
        data.drop(i).minPos[0].swap(d);
} unittest {
    int[] a0;
    a0.selectionSort;

    auto a1 = [1];
    a1.selectionSort;
    assert(a1 == [1]);

    auto a2 = ["a", "b"];
    a2.selectionSort;
    assert(a2 == ["a", "b"]);

    auto a3 = ["b", "a"];
    a3.selectionSort;
    assert(a3 == ["a", "b"]);

    auto a4 = ['a', 'b'];
    static assert(!__traits(compiles, a4.selectionSort));

    dchar[] a5 = ['b', 'a'];
    a5.selectionSort;
    assert(a5 == "ab"d);

    import std.typecons;
    alias Nullable!int N;
    auto a6 = [N(2), N(1)];
    a6.selectionSort; // Not nothrow.
    assert(a6 == [N(1), N(2)]);

    auto a7 = [1.0+0i, 2.0+0i]; // To be deprecated.
    static assert(!__traits(compiles, a7.selectionSort));

    import std.complex;
    auto a8 = [complex(1), complex(2)];
    static assert(!__traits(compiles, a8.selectionSort));

    static struct F {
        int x;
        int opCmp(F f) { // Not pure.
            return x < f.x ? -1 : (x > f.x ? 1 : 0);
        }
    }
    auto a9 = [F(2), F(1)];
    a9.selectionSort;
    assert(a9 == [F(1), F(2)]);
}

void main() {
    auto a = [3, 1, 4, 1, 5, 9, 2, 6, 5, 3, 5, 8, 9, 7, 9, 3, 2];
    a.selectionSort;
    a.writeln;
}


import java.util.List;
import java.util.ArrayList;
import java.util.Arrays;

public class PermutationSort
{
	public static void main(String[] args)
	{
		int[] a={3,2,1,8,9,4,6};
		System.out.println("Unsorted: " + Arrays.toString(a));
		a=pSort(a);
		System.out.println("Sorted: " + Arrays.toString(a));
	}
	public static int[] pSort(int[] a)
	{
		List<int[]> list=new ArrayList<int[]>();
		permute(a,a.length,list);
		for(int[] x : list)
			if(isSorted(x))
				return x;
		return a;
	}
	private static void permute(int[] a, int n, List<int[]> list)
	{
		if (n == 1)
		{
			int[] b=new int[a.length];
			System.arraycopy(a, 0, b, 0, a.length);
			list.add(b);
		    return;
		}
		for (int i = 0; i < n; i++)
		{
		        swap(a, i, n-1);
		        permute(a, n-1, list);
		        swap(a, i, n-1);
		 }
	}
	private static boolean isSorted(int[] a)
	{
		for(int i=1;i<a.length;i++)
			if(a[i-1]>a[i])
				return false;
		return true;
	}
	private static void swap(int[] arr,int i, int j)
	{
		int temp=arr[i];
		arr[i]=arr[j];
		arr[j]=temp;
	}
}


void main() {
    List<int> a = selectionSort([1100, 2, 56, 200, -52, 3, 99, 33, 177, -199]);
    print('$a');
}

selectionSort(List<int> array){
	for(int currentPlace = 0;currentPlace<array.length-1;currentPlace++){
		int smallest = 4294967296; //maxInt
		int smallestAt = currentPlace+1;
		for(int check = currentPlace; check<array.length;check++){
			if(array[check]<smallest){
				smallestAt = check;
				smallest = array[check];
			}
		}
		int temp = array[currentPlace];
		array[currentPlace] = array[smallestAt];
		array[smallestAt] = temp;
	}
  return array;
}


program TestSelectionSort;

{$APPTYPE CONSOLE}

{.$DEFINE DYNARRAY}  // remove '.' to compile with dynamic array

type
  TItem = Integer;   // declare ordinal type for array item
{$IFDEF DYNARRAY}
  TArray = array of TItem;          // dynamic array
{$ELSE}
  TArray = array[0..15] of TItem;   // static array
{$ENDIF}

procedure SelectionSort(var A: TArray);
var
  Item: TItem;
  I, J, M: Integer;

begin
  for I:= Low(A) to High(A) - 1 do begin
    M:= I;
    for J:= I + 1 to High(A) do
      if A[J] < A[M] then M:= J;
    Item:= A[M];
    A[M]:= A[I];
    A[I]:= Item;
  end;
end;

var
  A: TArray;
  I: Integer;

begin
{$IFDEF DYNARRAY}
  SetLength(A, 16);
{$ENDIF}
  for I:= Low(A) to High(A) do
    A[I]:= Random(100);
  for I:= Low(A) to High(A) do
    Write(A[I]:3);
  Writeln;
  SelectionSort(A);
  for I:= Low(A) to High(A) do
    Write(A[I]:3);
  Writeln;
  Readln;
end.


def permutations:
  if length == 0 then []
  else
    . as $in
    | range(0;length) as $i
    | ($in|del(.[$i])|permutations)
    | [$in[$i]] + .
  end ;


# v0.6

using Combinatorics

function permsort(x::Array)
    for perm in permutations(x)
        if issorted(perm)
            return perm
        end
    end
end

x = randn(10)
@show x permsort(x)


// version 1.1.2

fun <T : Comparable<T>> isSorted(list: List<T>): Boolean {
    val size = list.size
    if (size < 2) return true
    for (i in 1 until size) {
        if (list[i] < list[i - 1]) return false
    }
    return true
}

fun <T : Comparable<T>> permute(input: List<T>): List<List<T>> {
    if (input.size == 1) return listOf(input)
    val perms = mutableListOf<List<T>>()
    val toInsert = input[0]
    for (perm in permute(input.drop(1))) {
        for (i in 0..perm.size) {
            val newPerm = perm.toMutableList()
            newPerm.add(i, toInsert)
            perms.add(newPerm)
        }
    }
    return perms
}

fun <T : Comparable<T>> permutationSort(input: List<T>): List<T> {
    if (input.size == 1) return input
    val toInsert = input[0]
    for (perm in permute(input.drop(1))) {
        for (i in 0..perm.size) {
            val newPerm = perm.toMutableList()
            newPerm.add(i, toInsert)
            if (isSorted(newPerm)) return newPerm
        }
    }
    return input
}

fun main(args: Array<String>) {
    val input = listOf('d', 'b', 'e', 'a', 'f', 'c')
    println("Before sorting : $input")
    val output = permutationSort(input)
    println("After sorting  : $output")
    println()
    val input2 = listOf("first", "second", "third", "fourth", "fifth", "sixth")
    println("Before sorting : $input2")
    val output2 = permutationSort(input2)
    println("After sorting  : $output2")
}


def selectionSort := {
  def cswap(c, a, b) {
    def t := c[a]
    c[a]  := c[b]
    c[b]  := t
    println(c)
  }

  def indexOfMin(array, first, last) {
    var min := array[first]
    var mini := first
    for i in (first+1)..last {
      if (array[i] < min) {
        min := array[i]
        mini := i
      }
    }
    return mini
  }

  /** Selection sort (in-place). */
  def selectionSort(array) {
    def last := (array.size()-1)
    for i in 0..(last - 1) {
      cswap(array, i, indexOfMin(array, i + 1, last))
    }
  }
}


subr sort
  for i = 0 to len data[] - 2
    min_pos = i
    for j = i + 1 to len data[] - 1
      if data[j] < data[min_pos]
        min_pos = j
      .
    .
    swap data[i] data[min_pos]
  .
.
data[] = [ 29 4 72 44 55 26 27 77 92 5 ]
call sort
print data[]


-- Return an iterator to produce every permutation of list
function permute (list)
  local function perm (list, n)
    if n == 0 then coroutine.yield(list) end
    for i = 1, n do
      list[i], list[n] = list[n], list[i]
      perm(list, n - 1)
      list[i], list[n] = list[n], list[i]
    end
  end
  return coroutine.wrap(function() perm(list, #list) end)
end

-- Return true if table t is in ascending order or false if not
function inOrder (t)
  for pos = 2, #t do
    if t[pos] < t[pos - 1] then
      return false
    end
  end
  return true
end

-- Main procedure
local list = {2,3,1}                 --\   Written to match task pseudocode,
local nextPermutation = permute(list) --\  more idiomatic would be:
while not inOrder(list) do             --\
  list = nextPermutation()             --/   for p in permute(list) do
end                                   --/       stuffWith(p)
print(unpack(list))                  --/     end


arr := Array([17,0,-1,72,0]):
len := numelems(arr):
P := Iterator:-Permute(len):
for p in P do
	lst:= convert(arr[sort(convert(p,list),output=permutation)],list):
	if (ListTools:-Sorted(lst)) then
		print(lst):
		break:
	end if:
end do:


;; recursive version (adapted from Racket)
(lib 'list) ;; list-delete
(define (sel-sort xs  (x0))
	(cond
		[(null? xs) null]
		[else (set! x0 (apply min xs))
			  (cons x0 (sel-sort (list-delete xs x0)))]))

(sel-sort (shuffle (iota 13)))
    → (0 1 2 3 4 5 6 7 8 9 10 11 12)

;; straightforward and more efficient implementation using list-swap!
(define (sel-sort list)
		(maplist (lambda( L)
			(first (list-swap! L (first L) (apply min L )))) list))

(sel-sort (shuffle (iota 13)))
    → (0 1 2 3 4 5 6 7 8 9 10 11 12)


class
	SELECTION_SORT [G -> COMPARABLE]

feature {NONE}

	index_of_min (ar: ARRAY [G]; lower: INTEGER): INTEGER
			--Index of smallest element in 'ar' in the range of lower and the max index.
		require
			lower_positiv: lower >= 1
			lower_in_range: lower <= ar.count
			ar_not_void: ar /= Void
		local
			i: INTEGER
			min: G
		do
			from
				i := lower
				min := ar.item (i)
				Result := i
			until
				i + 1 > ar.count
			loop
				if ar.item (i + 1) < min then
					min := ar.item (i + 1)
					Result := i + 1
				end
				i := i + 1
			end
		ensure
			result_is_set: Result /= Void
		end

	sort (ar: ARRAY [G]): ARRAY [G]
			-- sort array ar with selectionsort
		require
			ar_not_void: ar /= Void
		local
			min_index: INTEGER
			ith: G
		do
			create Result.make_empty
			Result.deep_copy (ar)
			across
				Result as ic
			loop
				min_index := index_of_min (Result, ic.cursor_index)
				ith := Result [ic.cursor_index]
				Result [ic.cursor_index] := Result [min_index]
				Result [min_index] := ith
			end
		ensure
			Result_is_set: Result /= Void
			Result_sorted: is_sorted (Result) = True
		end

	is_sorted (ar: ARRAY [G]): BOOLEAN
			--- Is 'ar' sorted in ascending order?
		require
			ar_not_empty: ar.is_empty = False
		local
			i: INTEGER
		do
			Result := True
			from
				i := ar.lower
			until
				i = ar.upper
			loop
				if ar [i] > ar [i + 1] then
					Result := False
				end
				i := i + 1
			end
		end

feature

	selectionsort (ar: ARRAY [G]): ARRAY [G]
		do
			Result := sort (ar)
		end

end


PermutationSort[x_List] := NestWhile[RandomSample, x, Not[OrderedQ[#]] &]


function list = permutationSort(list)

    permutations = perms(1:numel(list)); %Generate all permutations of the item indicies

    %Test every permutation of the indicies of the original list
    for i = (1:size(permutations,1))
        if issorted( list(permutations(i,:)) )
            list = list(permutations(i,:));
            return %Once the correct permutation of the original list is found break out of the program
        end
    end

end


fn inOrder arr =
(
	if arr.count < 2 then return true
	else
	(
		local i = 1
		while i < arr.count do
		(
			if arr[i+1] < arr[i] do return false
			i += 1
		)
		return true
	)
)

fn permutations arr =
(
	if arr.count <= 1 then return arr
	else
	(
		for i = 1 to arr.count do
			(
				local rest = for r in 1 to arr.count where r != i collect arr[r]
				local permRest = permutations rest
				local new = join #(arr[i]) permRest
				if inOrder new do return new
			)
		)
)


/* NetRexx */
options replace format comments java crossref symbols nobinary

import java.util.List
import java.util.ArrayList

numeric digits 20

class RSortingPermutationsort public

  properties private static
    iterations
    maxIterations

  -- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  method permutationSort(vlist = List) public static returns List
    perm = RPermutationIterator(vlist)
    iterations = 0
    maxIterations = RPermutationIterator.factorial(vlist.size())
    loop while perm.hasNext()
      iterations = iterations + 1
      pl = List perm.next()
      if isSorted(pl) then leave
      else pl = null
      end
    return pl

  -- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  method isSorted(ss = List) private static returns boolean
    status = isTrue
    loop ix = 1 while ix < ss.size()
      vleft  = Rexx ss.get(ix - 1)
      vright = Rexx ss.get(ix)
      if vleft.datatype('N') & vright.datatype('N')
      then vtest = vleft > vright  -- For numeric types we must use regular comparison.
      else vtest = vleft >> vright -- For non-numeric/mixed types we must do strict comparison.
      if vtest then do
        status = isFalse
        leave ix
        end
      end ix
    return status

  -- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  method runSample(arg) private static
    placesList = -
        "UK  London,     US  New York,   US  Boston,     US  Washington" -
        "UK  Washington, US  Birmingham, UK  Birmingham, UK  Boston"
    anotherList = 'Alpha, Beta, Gamma, Beta'
    reversed = '7, 6, 5, 4, 3, 2, 1'
    unsorted = '734, 3, 1, 24, 324, -1024, -666, -1, 0, 324, 99999999'
    lists = [makeList(placesList), makeList(anotherList), makeList(reversed), makeList(unsorted)]
    loop il = 0 while il < lists.length
      vlist = lists[il]
      say vlist
      runtime = System.nanoTime()
      rlist = permutationSort(vlist)
      runtime = System.nanoTime() - runtime
      if rlist \= null then say rlist
      else say 'sort failed'
      say 'This permutation sort of' vlist.size() 'elements took' iterations 'passes (of' maxIterations') to complete. \-'
      say 'Elapsed time:' (runtime / 10 ** 9)'s.'
      say
      end il
    return

  -- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  method makeList(in) public static returns List
    lst = ArrayList()
    loop while in > ''
      parse in val ',' in
      lst.add(val.strip())
      end
    return lst
  -- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  method main(args = String[]) public static
    runSample(Rexx(args))
    return
  -- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  method isTrue() public static returns boolean
    return (1 == 1)
  -- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  method isFalse() public static returns boolean
    return (1 == 0)


import extensions;
import system'routines;

extension op
{
    selectionSort()
    {
        var copy := self.clone();

        for(int i := 0, i < copy.Length, i += 1)
        {
            int k := i;
            for(int j := i + 1, j < copy.Length, j += 1)
            {
                if (copy[j] < copy[k])
                {
                    k := j
                }
            };
            copy.exchange(i,k)
        };

        ^ copy
    }
}

public program()
{
    var list := new string[]{"this", "is", "a", "test", "of", "generic", "selection", "sort"};

    console.printLine("before:",list.asEnumerable());
    console.printLine("after:",list.selectionSort().asEnumerable())
}


defmodule Sort do
  def selection_sort(list) when is_list(list), do: selection_sort(list, [])

  defp selection_sort([], sorted), do: sorted
  defp selection_sort(list, sorted) do
    max = Enum.max(list)
    selection_sort(List.delete(list, max), [max | sorted])
  end
end


-module(solution).
-import(lists,[delete/2,max/1]).
-compile(export_all).
selection_sort([],Sort)-> Sort;
selection_sort(Ar,Sort)->
	M=max(Ar),
	Ad=delete(M,Ar),
	selection_sort(Ad,[M|Sort]).
print_array([])->ok;
print_array([H|T])->
	io:format("~p~n",[H]),
	print_array(T).

main()->
	Ans=selection_sort([1,5,7,8,4,10],[]),
	print_array(Ans).


iterator permutations[T](ys: openarray[T]): seq[T] =
  var
    d = 1
    c = newSeq[int](ys.len)
    xs = newSeq[T](ys.len)

  for i, y in ys: xs[i] = y
  yield xs

  block outter:
    while true:
      while d > 1:
        dec d
        c[d] = 0
      while c[d] >= d:
        inc d
        if d >= ys.len: break outter

      let i = if (d and 1) == 1: c[d] else: 0
      swap xs[i], xs[d]
      yield xs
      inc c[d]

proc isSorted[T](s: openarray[T]): bool =
  var last = low(T)
  for c in s:
    if c < last:
      return false
    last = c
  return true

proc permSort[T](a: openarray[T]): seq[T] =
  for p in a.permutations:
    if p.isSorted:
      return p

var a = @[4, 65, 2, -31, 0, 99, 2, 83, 782]
echo a.permSort


let rec sorted = function
 | e1 :: e2 :: r -> e1 <= e2 && sorted (e2 :: r)
 | _             -> true

let rec insert e = function
 | []          -> [[e]]
 | h :: t as l -> (e :: l) :: List.map (fun t' -> h :: t') (insert e t)

let permute xs = List.fold_right (fun h z -> List.concat (List.map (insert h) z))
                                 xs [[]]

let permutation_sort l = List.find sorted (permute l)


permutationSort(v)={
  my(u);
  for(k=1,(#v)!,
    u=vecextract(v, numtoperm(#v,k));
    for(i=2,#u,
      if(u[i]<u[i-1], next(2))
    );
    return(u)
  )
};


function selection_sort(sequence s)
    object tmp
    integer m
    for i = 1 to length(s) do
        m = i
        for j = i+1 to length(s) do
            if compare(s[j],s[m]) < 0 then
                m = j
            end if
        end for
        tmp = s[i]
        s[i] = s[m]
        s[m] = tmp
    end for
    return s
end function

include misc.e
constant s = {4, 15, "delta", 2, -31, 0, "alfa", 19, "gamma", 2, 13, "beta", 782, 1}

puts(1,"Before: ")
pretty_print(1,s,{2})
puts(1,"\nAfter: ")
pretty_print(1,selection_sort(s),{2})


sub psort {
        my ($x, $d) = @_;

        unless ($d //= $#$x) {
                $x->[$_] < $x->[$_ - 1] and return for 1 .. $#$x;
                return 1
        }

        for (0 .. $d) {
                unshift @$x, splice @$x, $d, 1;
                next if $x->[$d] < $x->[$d - 1];
                return 1 if psort($x, $d - 1);
        }
}

my @a = map+(int rand 100), 0 .. 10;
print "Before:\t@a\n";
psort(\@a);
print "After:\t@a\n"


with javascript_semantics

function inOrder(sequence s)
    for i=2 to length(s) do
        if s[i]<s[i-1] then return false end if
    end for
    return true
end function

function permutationSort(sequence s)
    for n=1 to factorial(length(s)) do
        sequence perm = permute(n,s)
        if inOrder(perm) then return perm end if
    end for
    ?9/0 -- should never happen
end function

?permutationSort({"dog",0,15.545,{"cat","pile","abcde",1},"cat"})


let rec ssort = function
    [] -> []
    | x::xs ->
        let min, rest =
            List.fold (fun (min,acc) x ->
                             if h<min then (h, min::acc)
                             else (min, h::acc))
              (x, []) xs
        in min::ssort rest


USING: kernel math sequences sequences.extras ;

: select ( m n seq -- )
    [ dup ] 2dip [ <slice> [ ] infimum-by* drop over + ]
    [ exchange ] bi ;

: selection-sort! ( seq -- seq' )
    [ ] [ length dup ] [ ] tri [ select ] 2curry each-integer ;


function inOrder($arr){
	for($i=0;$i<count($arr);$i++){
		if(isset($arr[$i+1])){
			if($arr[$i] > $arr[$i+1]){
				return false;
			}
		}
	}
	return true;
}

function permute($items, $perms = array( )) {
    if (empty($items)) {
		if(inOrder($perms)){
			return $perms;
		}
    }  else {
        for ($i = count($items) - 1; $i >= 0; --$i) {
             $newitems = $items;
             $newperms = $perms;
             list($foo) = array_splice($newitems, $i, 1);
             array_unshift($newperms, $foo);
             $res = permute($newitems, $newperms);
			 if($res){
				return $res;
			 }
         }
    }
}

$arr = array( 8, 3, 10, 6, 1, 9, 7, 2, 5, 4);
$arr = permute($arr);
echo implode(',',$arr);


(de permutationSort (Lst)
   (let L Lst
      (recur (L)  # Permute
         (if (cdr L)
            (do (length L)
               (T (recurse (cdr L)) Lst)
               (rot L)
               NIL )
            (apply <= Lst) ) ) ) )


defer less?   ' < is less?

: least ( start end -- least )
  over cell+ do
    i @ over @ less? if drop i then
  cell +loop ;
: selection ( array len -- )
  cells over + tuck ( end start end )
  cell- swap do   ( end )
    i over least ( end least )
    i @ over @ i ! swap !
  cell +loop drop ;

create array 8 , 1 , 4 , 2 , 10 , 3 , 7 , 9 , 6 , 5 ,

array 10 selection
array 10 cells dump


PROGRAM SELECTION

  IMPLICIT NONE

  INTEGER :: intArray(10) = (/ 4, 9, 3, -2, 0, 7, -5, 1, 6, 8 /)

  WRITE(*,"(A,10I5)") "Unsorted array:", intArray
  CALL Selection_sort(intArray)
  WRITE(*,"(A,10I5)") "Sorted array  :", intArray

CONTAINS

  SUBROUTINE Selection_sort(a)
    INTEGER, INTENT(IN OUT) :: a(:)
    INTEGER :: i, minIndex, temp

    DO i = 1, SIZE(a)-1
       minIndex = MINLOC(a(i:), 1) + i - 1
       IF (a(i) > a(minIndex)) THEN
          temp = a(i)
          a(i) = a(minIndex)
          a(minIndex) = temp
       END IF
    END DO
  END SUBROUTINE Selection_sort

END PROGRAM SELECTION


Function PermutationSort( [Object[]] $indata, $index = 0, $k = 0 )
{
	$data = $indata.Clone()
	$datal = $data.length - 1
	if( $datal -gt 0 ) {
		for( $j = $index; $j -lt $datal; $j++ )
		{
			$sorted = ( PermutationSort $data ( $index + 1 ) $j )[0]
			if( -not $sorted )
			{
				$temp = $data[ $index ]
				$data[ $index ] = $data[ $j + 1 ]
				$data[ $j + 1 ] = $temp
			}
		}
		if( $index -lt ( $datal - 1 ) )
		{
			PermutationSort $data ( $index + 1 ) $j
		} else {
			$sorted = $true
			for( $i = 0; ( $i -lt $datal ) -and $sorted; $i++ )
			{
				$sorted = ( $data[ $i ] -le $data[ $i + 1 ] )
			}
			$sorted
			$data
		}
	}
}

0..4 | ForEach-Object { $a = $_; 0..4 | Where-Object { -not ( $_ -match "$a" ) } |
	ForEach-Object { $b = $_; 0..4 | Where-Object { -not ( $_ -match "$a|$b" ) } |
		ForEach-Object { $c = $_; 0..4 | Where-Object { -not ( $_ -match "$a|$b|$c" ) } |
			ForEach-Object { $d = $_; 0..4 | Where-Object { -not ( $_ -match "$a|$b|$c|$d" ) } |
				ForEach-Object { $e=$_; "$( PermutationSort ( $a, $b, $c, $d, $e ) )" }
			}
		}
	}
}
$l = 8; PermutationSort ( 1..$l | ForEach-Object { $Rand = New-Object Random }{ $Rand.Next( 0, $l - 1 ) } )


' version 03-12-2016
' compile with: fbc -s console
' for boundry checks on array's compile with: fbc -s console -exx

Sub selectionsort(arr() As Long)

    ' sort from lower bound to the highter bound
    ' array's can have subscript range from -2147483648 to +2147483647

    Dim As Long i, j, x
    Dim As Long lb = LBound(arr)
    Dim As Long ub = UBound(arr)

    For i = lb To ub -1
        x = i
        For j = i +1 To ub
            If arr(j) < arr(x) Then x = j
        Next
        If x <> i Then
            Swap arr(i), arr(x)
        End If
    Next

End Sub

' ------=< MAIN >=------

Dim As Long i, array(-7 To 7)
Dim As Long a = LBound(array), b = UBound(array)

Randomize Timer
For i = a To b : array(i) = i  : Next
For i = a To b ' little shuffle
    Swap array(i), array(Int(Rnd * (b - a +1)) + a)
Next

Print "unsort ";
For i = a To b : Print Using "####"; array(i); : Next : Print
selectionsort(array())  ' sort the array
Print "  sort ";
For i = a To b : Print Using "####"; array(i); : Next : Print

' empty keyboard buffer
While InKey <> "" : Wend
Print : Print "hit any key to end program"
Sleep
End


permutation_sort(L,S) :- permutation(L,S), sorted(S).

sorted([]).
sorted([_]).
sorted([X,Y|ZS]) :- X =< Y, sorted([Y|ZS]).

permutation([],[]).
permutation([X|XS],YS) :- permutation(XS,ZS), select(X,YS,ZS).


Macro reverse(firstIndex, lastIndex)
  first = firstIndex
  last = lastIndex
  While first < last
    Swap cur(first), cur(last)
    first + 1
    last - 1
  Wend
EndMacro

Procedure nextPermutation(Array cur(1))
  Protected first, last, elementCount = ArraySize(cur())
  If elementCount < 2
    ProcedureReturn #False ;nothing to permute
  EndIf

  ;Find the lowest position pos such that [pos] < [pos+1]
  Protected pos = elementCount - 1
  While cur(pos) >= cur(pos + 1)
    pos - 1
    If pos < 0
      reverse(0, elementCount)
      ProcedureReturn #False ;no higher lexicographic permutations left, return lowest one instead
    EndIf
  Wend

  ;Swap [pos] with the highest positional value that is larger than [pos]
  last = elementCount
  While cur(last) <= cur(pos)
    last - 1
  Wend
  Swap cur(pos), cur(last)

  ;Reverse the order of the elements in the higher positions
  reverse(pos + 1, elementCount)
  ProcedureReturn #True ;next lexicographic permutation found
EndProcedure

Procedure display(Array a(1))
  Protected i, fin = ArraySize(a())
  For i = 0 To fin
    Print(Str(a(i)))
    If i = fin: Continue: EndIf
    Print(", ")
  Next
  PrintN("")
EndProcedure

If OpenConsole()
  Dim a(9)
  a(0) = 8: a(1) = 3: a(2) =  10: a(3) =  6: a(4) =  1: a(5) =  9: a(6) =  7: a(7) =  -4: a(8) =  5: a(9) =  3
  display(a())
  While nextPermutation(a()): Wend
  display(a())

  Print(#CRLF$ + #CRLF$ + "Press ENTER to exit"): Input()
  CloseConsole()
EndIf


siLow As Short = -99  'Set the lowest value number to create
siHigh As Short = 99  'Set the highest value number to create
siQty As Short = 20   'Set the quantity of numbers to create

Public Sub Main()
Dim siToSort As Short[] = CreateNumbersToSort()
Dim siPos, siLow, siChar, siCount As Short

PrintOut("To sort: ", siToSort)

For siCount = 0 To siToSort.Max
  siChar = siCount
  For siPos = siCount + 1 To siToSort.Max
    If siToSort[siChar] > siToSort[siPos] Then siChar = siPos
  Next
  siLow = siToSort[siChar]
  siToSort.Delete(siChar, 1)
  siToSort.Add(siLow, siCount)
Next

PrintOut(" Sorted: ", siToSort)

End
'---------------------------------------------------------
Public Sub PrintOut(sText As String, siToSort As String[])
Dim siCount As Short

Print sText;

For siCount = 0 To siToSort.Max
  Print siToSort[siCount];
  If siCount <> siToSort.max Then Print ", ";
Next

Print

End
'---------------------------------------------------------
Public Sub CreateNumbersToSort() As Short[]
Dim siCount As Short
Dim siList As New Short[]

For siCount = 0 To siQty
  siList.Add(Rand(siLow, siHigh))
Next

Return siList

End


from itertools import permutations

in_order = lambda s: all(x <= s[i+1] for i,x in enumerate(s[:-1]))
perm_sort = lambda s: (p for p in permutations(s) if in_order(p)).next()


  [ 1 swap times [ i 1+ * ] ] is !          (   n --> n )

  [ [] unrot 1 - times
      [ i 1+ ! /mod
        dip join ] drop ]     is factoradic ( n n --> [ )

  [ [] unrot witheach
      [ pluck
        rot swap nested join
        swap ]
    join ]                    is inversion  ( [ [ --> [ )

  [ over size
    factoradic inversion ]    is nperm      ( [ n --> [ )

 [ true swap
   behead swap
   witheach
     [ tuck > if
       [ dip not conclude ] ]
   drop ]                     is sorted     (   [ --> b )

 [ 0
   [ 2dup nperm
     dup sorted not while
     drop 1+ again ]
   unrot 2drop ]              is sort       (   [ --> [ )

  $ "beings" sort echo$


permutationsort <- function(x)
{
   if(!require(e1071) stop("the package e1071 is required")
   is.sorted <- function(x) all(diff(x) >= 0)

   perms <- permutations(length(x))
   i <- 1
   while(!is.sorted(x))
   {
      x <- x[perms[i,]]
      i <- i + 1
   }
   x
}
permutationsort(c(1, 10, 9, 7, 3, 0))


#lang racket
(define (sort l)
  (for/first ([p (in-permutations l)] #:when (apply <= p)) p))
(sort '(6 1 5 2 4 3)) ; => '(1 2 3 4 5 6)


SelectionSort := function(v)
   local i, j, k, n, m;
   n := Size(v);
   for i in [1 .. n] do
      k := i;
      m := v[i];
      for j in [i + 1 .. n] do
         if v[j] < m then
            k := j;
            m := v[j];
         fi;
      od;
      v[k] := v[i];
      v[i] := m;
   od;
end;

v := List([1 .. 100], n -> Random([1 .. 100]));
SelectionSort(v);
v;


package main

import "fmt"

var a = []int{170, 45, 75, -90, -802, 24, 2, 66}

func main() {
    fmt.Println("before:", a)
    selectionSort(a)
    fmt.Println("after: ", a)
}

func selectionSort(a []int) {
    last := len(a) - 1
    for i := 0; i < last; i++ {
        aMin := a[i]
        iMin := i
        for j := i + 1; j < len(a); j++ {
            if a[j] < aMin {
                aMin = a[j]
                iMin = j
            }
        }
        a[i], a[iMin] = aMin, a[i]
    }
}


# Lexicographic permuter from "Permutations" task.
sub next_perm ( @a ) {
    my $j = @a.end - 1;
    $j-- while $j >= 1 and [>] @a[ $j, $j+1 ];

    my $aj = @a[$j];
    my $k  = @a.end;
    $k-- while [>] $aj, @a[$k];

    @a[ $j, $k ] .= reverse;

    my Int $r = @a.end;
    my Int $s = $j + 1;
    while $r > $s {
        @a[ $r, $s ] .= reverse;
        $r--;
        $s++;
    }
}

sub permutation_sort ( @a ) {
    my @n = @a.keys;
    my $perm_count = [*] 1 .. +@n; # Factorial
    for ^$perm_count {
        my @permuted_a = @a[ @n ];
        return @permuted_a if [le] @permuted_a;
        next_perm(@n);
    }
}

my @data  = < c b e d a >; # Halfway between abcde and edcba
say 'Input  = ' ~ @data;
say 'Output = ' ~ @data.&permutation_sort;


/*REXX program  sorts and displays  an array  using the  permutation-sort  method.      */
call gen                                         /*generate the array elements.         */
call show     'before sort'                      /*show the  before  array elements.    */
                           say  copies('░', 75)  /*show separator line between displays.*/
call pSort  L                                    /*invoke the permutation sort.         */
call show     ' after sort'                      /*show the   after  array elements.    */
say; say 'Permutation sort took '      ?      " permutations to find the sorted list."
exit                                             /*stick a fork in it,  we're all done. */
/*──────────────────────────────────────────────────────────────────────────────────────*/
.pAdd: #=#+1; do j=1 for N;  #.#=#.#  !.j;  end;   return           /*add a permutation.*/
show:    do j=1  for L;  say @e right(j, wL) arg(1)":" translate(@.j, , '_'); end;  return
/*──────────────────────────────────────────────────────────────────────────────────────*/
gen:   @.=;                            @.1 = '---Four_horsemen_of_the_Apocalypse---'
                                       @.2 = '====================================='
                                       @.3 = 'Famine───black_horse'
                                       @.4 = 'Death───pale_horse'
                                       @.5 = 'Pestilence_[Slaughter]───red_horse'
                                       @.6 = 'Conquest_[War]───white_horse'
       @e= right('element', 15)                          /*literal used for the display.*/
         do L=1  while @.L\=='';  @@.[email protected].L;   end;    L= L-1;      wL=length(L);    return
/*──────────────────────────────────────────────────────────────────────────────────────*/
isOrd: parse arg q                                       /*see if  Q  list is in order. */
       _= word(q, 1);  do j=2  to words(q);  x= word(q, j);  if x<_  then return 0;   _= x
                       end   /*j*/                       /* [↑]  Out of order?   ¬sorted*/
         do k=1  for #;  _= word(#.?, k);  @.k= @@._;  end  /*k*/;  return 1  /*in order*/
/*──────────────────────────────────────────────────────────────────────────────────────*/
.pNxt: procedure expose !.;    parse arg n,i;         nm= n - 1
                            do k=nm  by -1  for nm;   kp= k + 1
                            if !.k<!.kp   then  do;    i= k;         leave;    end
                            end   /*k*/                  /* [↓]  swap two array elements*/
          do j=i+1  while j<n;  parse value  !.j !.n  with  !.n !.j;   n= n-1;  end  /*j*/
       if i==0  then return 0                            /*0:  indicates no more perms. */
          do j=i+1  while !.j<!.i;   end  /*j*/          /*search perm for a lower value*/
       parse value !.j !.i  with  !.i !.j;  return 1     /*swap two values in !.  array.*/
/*──────────────────────────────────────────────────────────────────────────────────────*/
pSort: parse arg n,#.;  #= 0                     /*generate  L  items (!)  permutations.*/
         do f=1  for n;                !.f= f;        end  /*f*/;            call .pAdd
         do while .pNxt(n, 0);         call .pAdd;    end  /*while*/
         do ?=1  until isOrd($);       $=                            /*find permutation.*/
           do m=1  for #; _= word(#.?, m); $= $ @._;  end  /*m*/     /*build the $ list.*/
         end   /*?*/;                  return


import Data.List (delete)

selSort :: (Ord a) => [a] -> [a]
selSort [] = []
selSort xs = selSort (delete x xs) ++ [x]
  where x = maximum xs


class SelectionSort {
  @:generic
  public static function sort<T>(arr:Array<T>) {
    var len = arr.length;
    for (index in 0...len) {
      var minIndex = index;
      for (remainingIndex in (index+1)...len) {
        if (Reflect.compare(arr[minIndex], arr[remainingIndex]) > 0)
          minIndex = remainingIndex;
      }
      if (index != minIndex) {
        var temp = arr[index];
        arr[index] = arr[minIndex];
        arr[minIndex] = temp;
      }
    }
  }
}

class Main {
  static function main() {
    var integerArray   = [1, 10, 2, 5, -1, 5, -19, 4, 23, 0];
    var floatArray = [1.0, -3.2, 5.2, 10.8, -5.7, 7.3,
                      3.5, 0.0, -4.1, -9.5];
    var stringArray = ['We', 'hold', 'these', 'truths', 'to',
                       'be', 'self-evident', 'that', 'all',
                       'men', 'are', 'created', 'equal'];
    Sys.println('Unsorted Integers:' + integerArray);
    SelectionSort.sort(integerArray);
    Sys.println('Sorted Integers:  ' + integerArray);
    Sys.println('Unsorted Floats:  ' + floatArray);
    SelectionSort.sort(floatArray);
    Sys.println('Sorted Floats:    ' + floatArray);
    Sys.println('Unsorted Strings: ' + stringArray);
    SelectionSort.sort(stringArray);
    Sys.println('Sorted Strings:   ' + stringArray);
  }
}


procedure main()                     #: demonstrate various ways to sort a list and string
   demosort(selectionsort,[3, 14, 1, 5, 9, 2, 6, 3],"qwerty")
end

procedure selectionsort(X,op)                           #: return sorted list ascending(or descending)
local i,m

   op := sortop(op,X)                                   # select how and what we sort
   every i := 1 to *X-1 do {
      m := i
      every j := i + 1 to *X do
         if op(X[j],X[m]) then m := j                   # find X that belongs @i low (or high)
      X[m ~= i] :=: X[m]
      }
   return X
end


# Project : Sorting algorithms/Permutation sort

a = [4, 65, 2, 31, 0, 99, 2, 83, 782]
result = []
permute(a,1)

for n = 1 to len(result)
     num = 0
     for m = 1 to len(result[n]) - 1
          if result[n][m] <= result[n][m+1]
             num = num + 1
          ok
     next
      if num = len(result[n]) - 1
         nr = n
         exit
      ok
next
see "" + nr + " permutations required to sort " + len(a) + " items." + nl

func permute(a,k)
       if k = len(a)
          add(result,a)
       else
          for i = k to len(a)
               temp=a[k]
               a[k]=a[i]
               a[i]=temp
               permute(a,k+1)
               temp=a[k]
               a[k]=a[i]
               a[i]=temp
          next
       ok
       return a


class Array
  def permutationsort
    permutation.each{|perm| return perm if perm.sorted?}
  end

  def sorted?
    each_cons(2).all? {|a, b| a <= b}
  end
end


(define (insertions e list)
  (if (null? list)
      (cons (cons e list) list)
      (cons (cons e list)
            (map (lambda (tail) (cons (car list) tail))
                 (insertions e (cdr list))))))

(define (permutations list)
  (if (null? list)
      (cons list list)
      (apply append (map (lambda (permutation)
                           (insertions (car list) permutation))
                         (permutations (cdr list))))))

(define (sorted? list)
  (cond ((null? list) #t)
        ((null? (cdr list)) #t)
        ((<= (car list) (cadr list)) (sorted? (cdr list)))
        (else #f)))

(define (permutation-sort list)
  (let loop ((permutations (permutations list)))
    (if (sorted? (car permutations))
        (car permutations)
        (loop (cdr permutations)))))


List do (
    selectionSortInPlace := method(
        size repeat(idx,
            swapIndices(idx, indexOf(slice(idx, size) min))
        )
    )
)

l := list(-1, 4, 2, -9)
l selectionSortInPlace println # ==> list(-9, -1, 2, 4)


100 PROGRAM "SelecSrt.bas"
110 RANDOMIZE
120 NUMERIC ARRAY(-5 TO 14)
130 CALL INIT(ARRAY)
140 CALL WRITE(ARRAY)
150 CALL SELECTIONSORT(ARRAY)
160 CALL WRITE(ARRAY)
170 DEF INIT(REF A)
180   FOR I=LBOUND(A) TO UBOUND(A)
190     LET A(I)=RND(98)+1
200   NEXT
210 END DEF
220 DEF WRITE(REF A)
230   FOR I=LBOUND(A) TO UBOUND(A)
240     PRINT A(I);
250   NEXT
260   PRINT
270 END DEF
280 DEF SELECTIONSORT(REF A)
290   FOR I=LBOUND(A) TO UBOUND(A)-1
300     LET MN=A(I):LET INDEX=I
310     FOR J=I+1 TO UBOUND(A)
320       IF MN>A(J) THEN LET MN=A(J):LET INDEX=J
330     NEXT
340     LET A(INDEX)=A(I):LET A(I)=MN
350   NEXT
360 END DEF


selectionSort=: verb define
  data=. y
  for_xyz. y do.
    temp=. xyz_index }. data
    nvidx=. xyz_index + temp i. <./ temp
    data=. ((xyz_index, nvidx) { data) (nvidx, xyz_index) } data
  end.
  data
)


func psort(x, d=x.end) {

    if (d.is_zero) {
        for i in (1 .. x.end) {
            (x[i] < x[i-1]) && return false;
        }
        return true;
    }

    (d+1).times {
        x.prepend(x.splice(d, 1)...);
        x[d] < x[d-1] && next;
        psort(x, d-1) && return true;
    }

    return false;
}

var a = 10.of { 100.irand };
say "Before:\t#{a}";
psort(a);
say "After:\t#{a}";


package require Tcl 8.5
package require struct::list

proc inorder {list} {::tcl::mathop::<= {*}$list}

proc permutationsort {list} {
    while { ! [inorder $list]} {
        set list [struct::list nextperm $list]
    }
    return $list
}


#import std

permsort "p" = ~&ihB+ ordered"p"*~+ permutations

#cast %sL

example = permsort(lleq) <'pmf','oao','ejw','hhp','oqh','ock','dwj'>


public static void sort(int[] nums){
	for(int currentPlace = 0;currentPlace<nums.length-1;currentPlace++){
		int smallest = Integer.MAX_VALUE;
		int smallestAt = currentPlace+1;
		for(int check = currentPlace; check<nums.length;check++){
			if(nums[check]<smallest){
				smallestAt = check;
				smallest = nums[check];
			}
		}
		int temp = nums[currentPlace];
		nums[currentPlace] = nums[smallestAt];
		nums[smallestAt] = temp;
	}
}


function selectionSort(nums) {
  var len = nums.length;
  for(var i = 0; i < len; i++) {
    var minAt = i;
    for(var j = i + 1; j < len; j++) {
      if(nums[j] < nums[minAt])
        minAt = j;
    }

    if(minAt != i) {
      var temp = nums[i];
      nums[i] = nums[minAt];
      nums[minAt] = temp;
    }
  }
  return nums;
}


import "/sort" for Sort

var a = [170, 45, 75, -90, -802, 24, 2, 66]

// recursive permutation generator
var recurse
recurse = Fn.new { |last|
    if (last <= 0) return Sort.isSorted(a)
    for (i in 0..last) {
        var t = a[i]
        a[i] = a[last]
        a[last] = t
        if (recurse.call(last - 1))  return true
        t = a[i]
        a[i] = a[last]
        a[last] = t
    }
    return false
}

System.print("Unsorted: %(a)")
var count = a.count
if (count > 1 && !recurse.call(count-1)) Fiber.abort("Sorted permutation not found!")
System.print("Sorted  : %(a)")


rns:=T(4, 65, 2, 31, 0, 99, 2, 83, 782, 1);
fcn psort(list){ len:=list.len(); cnt:=Ref(0);
   foreach ns in (Utils.Helpers.permuteW(list)){ // lasy permutations
      cnt.set(1);
      ns.reduce('wrap(p,n){ if(p>n)return(Void.Stop); cnt.inc(); n });
      if(cnt.value==len) return(ns);
   }
}(rns).println();


# Sort any array
def selection_sort:
  def swap(i;j): if i == j then . else .[i] as $tmp | .[i] = .[j] | .[j] = $tmp end;
  length as $length
  | reduce range(0; $length) as $currentPlace
      # state: $array
      ( .;
        . as $array
        | (reduce range( $currentPlace; $length) as $check
            # state: [ smallestAt, smallest] except initially [null]
            ( [$currentPlace+1] ;
               if length == 1 or $array[$check] < .[1]
               then [$check, $array[$check] ]
               else .
               end
             )) as $ans
          | swap( $currentPlace; $ans[0] )
          ) ;


function selectionsort!(arr::Vector{<:Real})
    len = length(arr)
    if len < 2 return arr end
    for i in 1:len-1
        lmin, j = findmin(arr[i+1:end])
        if lmin < arr[i]
            arr[i+j] = arr[i]
            arr[i] = lmin
        end
    end
    return arr
end

v = rand(-10:10, 10)
println("# unordered: $v\n -> ordered: ", selectionsort!(v))


fun <T : Comparable<T>> Array<T>.selection_sort() {
    for (i in 0..size - 2) {
        var k = i
        for (j in i + 1..size - 1)
            if (this[j] < this[k])
                k = j

        if (k != i) {
            val tmp = this[i]
            this[i] = this[k]
            this[k] = tmp
        }
    }
}

fun main(args: Array<String>) {
    val i = arrayOf(4, 9, 3, -2, 0, 7, -5, 1, 6, 8)
    i.selection_sort()
    println(i.joinToString())

    val s = Array(i.size, { -i[it].toShort() })
    s.selection_sort()
    println(s.joinToString())

    val c = arrayOf('z', 'h', 'd', 'c', 'a')
    c.selection_sort()
    println(c.joinToString())
}


    itemCount = 20
    dim A(itemCount)
    for i = 1 to itemCount
        A(i) = int(rnd(1) * 100)
    next i

    print "Before Sort"
    gosub [printArray]

'--- Selection sort algorithm
    for i = 1 to itemCount-1
        jMin = i
        for j = i+1 to itemCount
            if A(j) < A(jMin) then jMin = j
        next
        tmp = A(i)
        A(i) = A(jMin)
        A(jMin) = tmp
    next
'--- end of (Selection sort algorithm)

    print "After Sort"
    gosub [printArray]
end

[printArray]
    for i = 1 to itemCount
        print using("###", A(i));
    next i
    print
return


(*
** Tri par Sélection
** (LSE2000)
*)
PROCEDURE &Test(TABLEAU DE ENTIER pDonnees[], ENTIER pTaille) LOCAL pTaille
    ENTIER i, j, minimum, tmp
    POUR  i <- 0 JUSQUA pTaille-1 FAIRE
        minimum <- i
        POUR j <- i+1 JUSQUA pTaille FAIRE
            SI pDonnees[j] < pDonnees[minimum] ALORS
                minimum <- j
            FIN SI
        BOUCLER
        SI i # min ALORS
            tmp <- pDonnees[i]
            pDonnees[i] <- pDonnees[minimum]
            pDonnees[minimum] <- tmp
        FIN SI
    BOUCLER
FIN PROCEDURE


function SelectionSort( f )
    for k = 1, #f-1 do
        local idx = k
        for i = k+1, #f do
            if f[i] < f[idx] then
                idx = i
            end
        end
        f[k], f[idx] = f[idx], f[k]
    end
end

f = { 15, -3, 0, -1, 5, 4, 5, 20, -8 }

SelectionSort( f )

for i in next, f do
    print( f[i] )
end


arr:= Array([17,3,72,0,36,2,3,8,40,0]):
len := numelems(arr):
for i to len-1 do
	j_min := i:
	for j from i+1 to len do
		if arr[j] < arr[j_min] then
			j_min := j:
		end if:
	end do:
	if (not j_min = i) then
		temp := arr[i]:
		arr[i] := arr[j_min]:
		arr[j_min] := temp:
	end if:
end do:
arr;


SelectSort[x_List] := Module[{n = 1, temp, xi = x, j},
  While[n <= [email protected],
   temp = xi[[n]];
   For[j = n, j <= [email protected], j++,
    If[xi[[j]] < temp, temp = xi[[j]]];
    ];
   xi[[n ;;]] = {temp}~Join~
     Delete[xi[[n ;;]], [email protected][xi[[n ;;]], temp] ];
   n++;
   ];
  xi
  ]


function list = selectionSort(list)

    listSize = numel(list);

    for i = (1:listSize-1)

        minElem = list(i);
        minIndex = i;

        %This for loop can be vectorized, but there will be no significant
        %increase in sorting efficiency.
        for j = (i:listSize)
            if list(j) <= minElem
                minElem = list(j);
                minIndex = j;
            end
        end

        if i ~= minIndex
            list([minIndex i]) = list([i minIndex]); %Swap
        end

    end %for
end %selectionSort


fn selectionSort arr =
(
    local min = undefined
    for i in 1 to arr.count do
    (
        min = i
        for j in i+1 to arr.count do
        (
            if arr[j] < arr[min] then
            (
                min = j
            )
        )
        swap arr[i] arr[min]
    )
    arr
)

data = selectionSort #(4, 9, 3, -2, 0, 7, -5, 1, 6, 8)
print data


import math

def sort(nums)
	global math
	for currentPlace in range(0, len(nums) - 2)
		smallest   = math.maxint
		smallestAt = currentPlace + 1
		for check in range(currentPlace, len(nums) - 1)
			if nums[check] < smallest
				smallestAt = check
				smallest = nums[check]
			end
		end
		temp = nums[currentPlace]
		nums[currentPlace] = nums[smallestAt]
		nums[smallestAt] = temp
	end
	return nums
end


using System;
using System.Console;

module Selection
{
    public static Sort[T](this a : array[T]) : void
      where T : IComparable
    {
        mutable k = 0;
        def lastindex = a.Length - 1;

        foreach (i in [0 .. lastindex])
        {
            k = i;
            foreach (j in [i .. lastindex])
                when (a[j].CompareTo(a[k]) < 0) k = j;
            a[i] <-> a[k];
        }
    }

    Main() : void
    {
        def arr = array[6, 2, 8, 3, 9, 4, 7, 3, 9, 1];
        arr.Sort();
        foreach (i in arr) Write($"$i  ");
    }
}


/* NetRexx */
options replace format comments java crossref savelog symbols binary

import java.util.List

placesList = [String -
    "UK  London",     "US  New York",   "US  Boston",     "US  Washington" -
  , "UK  Washington", "US  Birmingham", "UK  Birmingham", "UK  Boston"     -
]

lists = [ -
    placesList -
  , selectionSort(String[] Arrays.copyOf(placesList, placesList.length)) -
]

loop ln = 0 to lists.length - 1
  cl = lists[ln]
  loop ct = 0 to cl.length - 1
    say cl[ct]
    end ct
    say
  end ln

return

method selectionSort(a = String[]) public constant binary returns String[]

  rl = String[a.length]
  al = List selectionSort(Arrays.asList(a))
  al.toArray(rl)

  return rl

method selectionSort(a = List) public constant binary returns ArrayList

  ra = ArrayList(a)
  n  = ra.size

  iPos = int
  iMin = int

  loop iPos = 0 to n - 1
    iMin = iPos
    loop i_ = iPos + 1 to n - 1
      if (Comparable ra.get(i_)).compareTo(Comparable ra.get(iMin)) < 0 then do
        iMin = i_
        end
      end i_
    if iMin \= iPos then do
      swap = ra.get(iPos)
      ra.set(iPos, ra.get(iMin))
      ra.set(iMin, swap)
      end
    end iPos

  return ra


proc selectionSort[T](a: var openarray[T]) =
  let n = a.len
  for i in 0 ..< n:
    var m = i
    for j in i ..< n:
      if a[j] < a[m]:
        m = j
    swap a[i], a[m]

var a = @[4, 65, 2, -31, 0, 99, 2, 83, 782]
selectionSort a
echo a


let rec selection_sort = function
    [] -> []
  | first::lst ->
      let rec select_r small output = function
          [] -> small :: selection_sort output
        | x::xs when x < small -> select_r x (small::output) xs
        | x::xs                -> select_r small (x::output) xs
      in
      select_r first [] lst


: selectSort(l)
| b j i k s |
   l size ->s
   l asListBuffer ->b

   s loop: i [
      i dup ->k b at
      i 1 + s for: j [ b at(j) 2dup <= ifTrue: [ drop ] else: [ nip j ->k ] ]
      k i b at b put i swap b put
      ]
   b dup freeze ;


/*REXX ****************************************************************
* program sorts an  array  using  the  selection-sort  method.
* derived from REXX solution
* Note that ooRexx can process Elements of the stem argument (Use Arg)
* 06.10.2010 Walter Pachl
**********************************************************************/
call generate                       /*generate the array elements.   */
call show 'before sort'             /*show the before array elements,*/
call selectionSort x.               /*invoke the selection sort.     */
call show 'after sort'              /*show the  after array elements.*/
exit                                /*stick a fork in it, we're done.*/

selectionSort: Procedure
  Use Arg s.                        /* gain access to the argument   */
  do j=1 To s.0-1
    t=s.j;
    p=j;
    do k=j+1 to s.0
      if s.k<t then do;
        t=s.k;
        p=k;
        end
      end
    if p=j then
      iterate
    t=s.j;
    s.j=s.p;
    s.p=t
    end
  return

show:
  Parse Arg heading
  Say heading
  Do i=1 To x.0
    Say i'  'x.i
    End
  say copies('-',79)
  Return
return

generate:
  x.1='---The seven hills of Rome:---'
  x.2='=============================='
  x.3='Caelian'
  x.4='Palatine'
  x.5='Capitoline'
  x.6='Virminal'
  x.7='Esquiline'
  x.8='Quirinal'
  x.9='Aventine'
  x.0=9
  return


declare
  proc {SelectionSort Arr}
     proc {Swap K L}
        Arr.K := (Arr.L := Arr.K)
     end
     Low = {Array.low Arr}
     High = {Array.high Arr}
  in
     %% for every index I of the array
     for I in Low..High do
	%% find the index of the minimum element
	%% with an index >= I
	Min = {NewCell Arr.I}
        MinIndex = {NewCell I}
     in
        for J in I..High do
  	 if Arr.J < @Min then
	    Min := Arr.J
	    MinIndex := J
  	 end
	end
	%% and put that minimum element to the left
	{Swap @MinIndex I}
     end
  end

  A = {Tuple.toArray unit(3 1 4 1 5 9 2 6 5)}
in
  {SelectionSort A}
  {Show {Array.toRecord unit A}}


selectionSort(v)={
  for(i=1,#v-1,
    my(mn=i,t);
    for(j=i+1,#v,
      if(v[j]<v[mn],mn=j)
    );
    t=v[mn];
    v[mn]=v[i];
    v[i]=t
  );
  v
};


sub selection_sort
  {my @a = @_;
   foreach my $i (0 .. $#a - 1)
      {my $min = $i + 1;
       $a[$_] < $a[$min] and $min = $_ foreach $min .. $#a;
       $a[$i] > $a[$min] and @a[$i, $min] = @a[$min, $i];}
   return @a;}


with javascript_semantics

function selection_sort(sequence s)
    for i=1 to length(s) do
        integer m = i
        object si = s[i],
               sm = s[m]
        for j=i+1 to length(s) do
            object sj = s[j]
            if sj<sm then
                {sm,m} = {sj,j}
            end if
        end for
        if sm<si then -- (or equivalently m!=i)
            s[i] = sm
            s[m] = si
        end if
    end for
    return s
end function

?selection_sort(shuffle(tagset(10)))


function selection_sort(&$arr) {
    $n = count($arr);
    for($i = 0; $i < count($arr); $i++) {
        $min = $i;
        for($j = $i + 1; $j < $n; $j++){
            if($arr[$j] < $arr[$min]){
                $min = $j;
            }
        }
        list($arr[$i],$arr[$min]) = array($arr[$min],$arr[$i]);
    }
}


(de selectionSort (Lst)
   (map
      '((L) (and (cdr L) (xchg L (member (apply min @) L))))
      Lst )
   Lst )


Selection: procedure options (main);         /* 2 November 2013 */

   declare a(10) fixed binary initial (
      5, 7, 3, 98, 4, -3, 25, 20, 60, 17);

   put edit (trim(a)) (a, x(1));

   call Selection_Sort (a);

   put skip edit (trim(a)) (a, x(1));

Selection_sort: procedure (a);
   declare a(*) fixed binary;
   declare t fixed binary;
   declare n fixed binary;
   declare (i, j, k) fixed binary;

   n = hbound(a,1);
   do j = 1 to n;
      k = j; t = a(j);
      do i = j+1 to n;
         if t > a(i) then do; t = a(i); k = i; end;
      end;
      a(k) = a(j); a(j) = t;
   end;
end Selection_Sort;

end Selection;


Function SelectionSort( [Array] $data )
{
	$datal=$data.length-1
	0..( $datal - 1 ) | ForEach-Object {
		$min = $data[ $_ ]
		$mini = $_
		( $_ + 1 )..$datal | ForEach-Object {
			if( $data[ $_ ] -lt $min ) {
				$min = $data[ $_ ]
				$mini = $_
			}
		}
		$temp = $data[ $_ ]
		$data[ $_ ] = $min
		$data[ $mini ] = $temp
	}
	$data
}

$l = 100; SelectionSort( ( 1..$l | ForEach-Object { $Rand = New-Object Random }{ $Rand.Next( 0, $l - 1 ) } ) )


selection_sort([], []).
selection_sort([H | L], [H1 | L2]) :-
	exchange(H, L, H1, L1),
	selection_sort(L1, L2).

exchange(H, [], H, []).

exchange(H, L, H1, L1) :-
	min_list(L, H2),
	(   H < H2
	->  H1 = H, L1 = L
	;   H1 = H2,
	    % does the exchange of the number H
	    % and the min of the list
	    nth0(Ind, L, H1, L2),
	    nth0(Ind, L1, H, L2)).


Procedure selectionSort(Array a(1))
  Protected i, j, lastIndex, minIndex

  lastIndex = ArraySize(a())
  For i = 0 To lastIndex - 1
    minIndex = i
    For j = i + 1 To lastIndex
      If a(minIndex) > a(j)
        minIndex = j
      EndIf
    Next
    Swap a(minIndex), a(i)
  Next
EndProcedure


def selection_sort(lst):
    for i, e in enumerate(lst):
        mn = min(range(i,len(lst)), key=lst.__getitem__)
        lst[i], lst[mn] = lst[mn], e
    return lst


(define select-r
  Small []     Output -> [Small | (selection-sort Output)]
  Small [X|Xs] Output -> (select-r X Xs [Small|Output]) where (< X Small)
  Small [X|Xs] Output -> (select-r Small Xs [X|Output]))

(define selection-sort
  []          -> []
  [First|Lst] -> (select-r First Lst []))

(selection-sort [8 7 4 3 2 0 9 1 5 6])


  [ 0 swap
    behead swap
    witheach
      [ 2dup > iff
          [ nip nip
            i^ 1+ swap ]
        else drop ]
    drop ]               is least ( [ --> n )

  [ [] swap
    dup size times
      [ dup least pluck
        swap dip join ]
    drop ]               is ssort ( [ --> [ )

  [] 20 times [ 10 random join ]
  dup echo cr
  ssort echo cr


selectionsort.loop <- function(x)
{
   lenx <- length(x)
   for(i in seq_along(x))
   {
      mini <- (i - 1) + which.min(x[i:lenx])
      start_ <- seq_len(i-1)
      x <- c(x[start_], x[mini], x[-c(start_, mini)])
   }
   x
}


class SelectionSort
	**Sort a list with the Selection Sort algorithm**

	on start

		args := program arguments
		.sort(args)
		print args

	define sort(list) is shared
		**Sort the list**

		test
			list := [4, 2, 7, 3]
			.sort(list)
			assert list = [2, 3, 4, 7]

		body
			count := list.count
			last := count - 1

			for i in last

				minCandidate := i
				j := i + 1

				while j < count
					if list[j] < list[minCandidate], minCandidate := j
					j :+ 1

				temp := list[i]
				list[i] := list[minCandidate]
				list[minCandidate] := temp


#lang racket
(define (selection-sort xs)
  (cond [(empty? xs) '()]
        [else (define x0 (apply min xs))
              (cons x0 (selection-sort (remove x0 xs)))]))


sub selection_sort ( @a is copy ) {
    for 0 ..^ @a.end -> $i {
        my $min = [ $i+1 .. @a.end ].min: { @a[$_] };
        @a[$i, $min] = @a[$min, $i] if @a[$i] > @a[$min];
    }
    return @a;
}

my @data = 22, 7, 2, -5, 8, 4;
say 'input  = ' ~ @data;
say 'output = ' ~ @data.&selection_sort;


/*REXX program  sorts  a  stemmed array  using the   selection─sort   algorithm.        */
call init                                        /*assign some values to an array:   @. */
call show   'before sort'                        /*show the   before   array elements.  */
     say  copies('▒', 65)                        /*show a nice separator line  (fence). */
call selectionSort   #                           /*invoke selection sort (and # items). */
call show   ' after sort'                        /*show the    after   array elements.  */
exit 0                                           /*stick a fork in it,  we're all done. */
/*──────────────────────────────────────────────────────────────────────────────────────*/
init: @.=;                  @.1 = '---The seven hills of Rome:---'
                            @.2 = '==============================';      @.6 = 'Virminal'
                            @.3 = 'Caelian'                       ;      @.7 = 'Esquiline'
                            @.4 = 'Palatine'                      ;      @.8 = 'Quirinal'
                            @.5 = 'Capitoline'                    ;      @.9 = 'Aventine'
              do #=1  until @.#=='';   end       /*find the number of items in the array*/
      #= #-1;         return                     /*adjust  #  (because of  DO  index).  */
/*──────────────────────────────────────────────────────────────────────────────────────*/
selectionSort: procedure expose @.;  parse arg n
                      do j=1  for n-1;                 _= @.j;             p= j
                          do k=j+1  to n;      if @.k>=_  then iterate
                          _= @.k;      p= k      /*this item is out─of─order, swap later*/
                          end   /*k*/
                      if p==j  then iterate      /*if the same, the order of items is OK*/
                      _= @.j;  @.j= @.p;  @.p= _ /*swap 2 items that're out─of─sequence.*/
                      end       /*j*/
               return
/*──────────────────────────────────────────────────────────────────────────────────────*/
show:  do i=1  for #;  say '       element' right(i,length(#)) arg(1)":" @.i; end;  return


aList = [7,6,5,9,8,4,3,1,2,0]
see sortList(aList)

func sortList list
     count = len(list) + 1
     last = count - 1

     for i = 1 to last
          minCandidate = i
          j = i + 1
          while j < count
	        if list[j] < list[minCandidate] minCandidate = j ok
	        j = j + 1
          end
          temp = list[i]
          list[i] = list[minCandidate]
          list[minCandidate] = temp
      next
      return list


# a relatively readable version - creates a distinct array

def sequential_sort(array)
  sorted = []

  while array.any?
    index_of_smallest_element = find_smallest_index(array) # defined below
    sorted << array.delete_at(index_of_smallest_element)
  end

  sorted
end

def find_smallest_index(array)
  smallest_element = array[0]
  smallest_index = 0

  array.each_with_index do |ele, idx|
    if ele < smallest_element
      smallest_element = ele
      smallest_index = idx
    end
  end

  smallest_index
end

puts "sequential_sort([9, 6, 8, 7, 5]): #{sequential_sort([9, 6, 8, 7, 5])}"
# prints: sequential_sort([9, 6, 8, 7, 5]): [5, 6, 7, 8, 9]

# more efficient version - swaps the array's elements in place

def sequential_sort_with_swapping(array)
  array.each_with_index do |element, index|
    smallest_unsorted_element_so_far = element
    smallest_unsorted_index_so_far = index

    (index+1...array.length).each do |index_value|
      if array[index_value] < smallest_unsorted_element_so_far
        smallest_unsorted_element_so_far = array[index_value]
        smallest_unsorted_index_so_far = index_value
      end
    end

    # swap index_value-th smallest element for index_value-th element
    array[index], array[smallest_unsorted_index_so_far] = array[smallest_unsorted_index_so_far], array[index]
  end

  array
end

puts "sequential_sort_with_swapping([7,6,5,9,8,4,3,1,2,0]): #{sequential_sort_with_swapping([7,6,5,9,8,4,3,1,2,0])}"
# prints: sequential_sort_with_swapping([7,6,5,9,8,4,3,1,2,0]): [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]


siz = 10
dim srdData(siz)
for i = 1 to siz
srtData(i) = rnd(0) * 100
next i

FOR i = 1 TO siz-1
   lo = i
   FOR j = (i + 1) TO siz
      IF srtData(j) < srtData(lo) lo = j
   NEXT j
   if i <> lo then
   temp        = srtData(i)
   srtData(i)  = srtData(lo)
   srtData(lo) = temp
   end if
NEXT i

for i = 1 to siz
print i;chr$(9);srtData(i)
next i


fn selection_sort(array: &mut [i32]) {

    let mut min;

    for i in 0..array.len() {

        min = i;

        for j in (i+1)..array.len() {

            if array[j] < array[min] {
                min = j;
            }
        }

        let tmp = array[i];
        array[i] = array[min];
        array[min] = tmp;
    }
}

fn main() {

    let mut array = [ 9, 4, 8, 3, -5, 2, 1, 6 ];
    println!("The initial array is {:?}", array);

    selection_sort(&mut array);
    println!(" The sorted array is {:?}", array);
}


def swap(a: Array[Int], i1: Int, i2: Int) = { val tmp = a(i1); a(i1) = a(i2); a(i2) = tmp }

def selectionSort(a: Array[Int]) =
  for (i <- 0 until a.size - 1)
    swap(a, i, (i + 1 until a.size).foldLeft(i)((currMin, index) =>
      if (a(index) < a(currMin)) index else currMin))


const proc: selectionSort (inout array elemType: arr) is func
  local
    var integer: i is 0;
    var integer: j is 0;
    var integer: min is 0;
    var elemType: help is elemType.value;
  begin
    for i range 1 to length(arr) - 1 do
      min := i;
      for j range i + 1 to length(arr) do
        if arr[j] < arr[min] then
          min := j;
        end if;
      end for;
      help := arr[min];
      arr[min] := arr[i];
      arr[i] := help;
    end for;
  end func;


class Array {
    method selectionsort {
        for i in ^(self.end) {
            var min_idx = i
            for j in (i+1 .. self.end) {
                if (self[j] < self[min_idx]) {
                    min_idx = j
                }
            }
            self.swap(i, min_idx)
        }
        return self
    }
}

var nums = [7,6,5,9,8,4,3,1,2,0];
say nums.selectionsort;

var strs = ["John", "Kate", "Zerg", "Alice", "Joe", "Jane"];
say strs.selectionsort;


fun selection_sort [] = []
  | selection_sort (first::lst) =
    let
      val (small, output) = foldl
        (fn (x, (small, output)) =>
            if x < small then
              (x, small::output)
            else
              (small, x::output)
        ) (first, []) lst
    in
      small :: selection_sort output
    end


mata
function selection_sort(real vector a) {
	real scalar i, j, k, n
	n = length(a)
	for (i = 1; i < n; i++) {
		k = i
		for (j = i+1; j <= n; j++) {
			if (a[j] < a[k]) k = j
		}
		if (k != i) a[(i, k)] = a[(k, i)]
	}
}
end


func selectionSort(inout arr:[Int]) {
    var min:Int

    for n in 0..<arr.count {
        min = n

        for x in n+1..<arr.count {
            if (arr[x] < arr[min]) {
                min = x
            }
        }

        if min != n {
            let temp = arr[min]
            arr[min] = arr[n]
            arr[n] = temp
        }
    }
}


package require Tcl 8.5
package require struct::list

proc selectionsort {A} {
    set len [llength $A]
    for {set i 0} {$i < $len - 1} {incr i} {
        set min_idx [expr {$i + 1}]
        for {set j $min_idx} {$j < $len} {incr j} {
            if {[lindex $A $j] < [lindex $A $min_idx]} {
                set min_idx $j
            }
        }
        if {[lindex $A $i] > [lindex $A $min_idx]} {
            struct::list swap A $i $min_idx
        }
    }
    return $A
}

puts [selectionsort {8 6 4 2 1 3 5 7 9}] ;# => 1 2 3 4 5 6 7 8 9


:L1→L2
:dim(L2)→I
:For(A,1,I)
:A→C
:0→X
:For(B,A,I)
:If L2(B)<L2(C)
:Then
:B→C
:1→X
:End
:End
:If X=1
:Then
:L2(C)→B
:L2(A)→L2(C)
:B→L2(A)
:End
:End
:DelVar A
:DelVar B
:DelVar C
:DelVar I
:DelVar X
:Return


PRINT "Selection sort:"
  n = FUNC (_InitArray)
  PROC _ShowArray (n)
  PROC _Selectionsort (n)
  PROC _ShowArray (n)
PRINT

END

_Selectionsort PARAM (1)               ' Selection sort
  LOCAL (3)

  FOR [email protected] = 0 TO [email protected]
    [email protected] = [email protected]

    FOR [email protected] = [email protected] TO [email protected]
      IF @([email protected]) < @([email protected]) THEN [email protected] = [email protected]
    NEXT

    IF [email protected] # [email protected] THEN PROC _Swap ([email protected], [email protected])
  NEXT
RETURN

_Swap PARAM(2)                         ' Swap two array elements
  PUSH @([email protected])
  @([email protected]) = @([email protected])
  @([email protected]) = POP()
RETURN

_InitArray                             ' Init example array
  PUSH 4, 65, 2, -31, 0, 99, 2, 83, 782, 1

  FOR i = 0 TO 9
    @(i) = POP()
  NEXT

RETURN (i)

_ShowArray PARAM (1)                   ' Show array subroutine
  FOR i = 0 TO [email protected]
    PRINT @(i),
  NEXT

  PRINT
RETURN


#import std

selection_sort "p" = @iNX ~&l->rx ^(gldif ==,~&r)^/~&l ^|C/"p"$- ~&


sub swap( byref a, byref b)
	dim tmp
	tmp = a
	a = b
	b = tmp
end sub

function selectionSort (a)
	for i = 0 to ubound(a)
	k = i
		for j=i+1 to ubound(a)
			if a(j) < a(i) then
				swap a(i), a(j)
			end if
		next
	next
	selectionSort = a
end function


Function Selection_Sort(s)
	arr = Split(s,",")
	For i = 0 To UBound(arr)
		For j = i To UBound(arr)
			temp = arr(i)
			If arr(j) < arr(i) Then
				arr(i) = arr(j)
				arr(j) = temp
			End If
		Next
	Next
	Selection_Sort = (Join(arr,","))
End Function

WScript.StdOut.Write "Pre-Sort" & vbTab & "Sorted"
WScript.StdOut.WriteLine
WScript.StdOut.Write "3,2,5,4,1" & vbTab & Selection_Sort("3,2,5,4,1")
WScript.StdOut.WriteLine
WScript.StdOut.Write "c,e,b,a,d" & vbTab & Selection_Sort("c,e,b,a,d")


var selectionSort = Fn.new { |a|
    var last = a.count - 1
    for (i in 0...last) {
        var aMin = a[i]
        var iMin = i
        for (j in i+1..last) {
            if (a[j] < aMin) {
                aMin = a[j]
                iMin = j
            }
        }
        var t = a[i]
        a[i] = aMin
        a[iMin] = t
    }
}

var as = [ [4, 65, 2, -31, 0, 99, 2, 83, 782, 1], [7, 5, 2, 6, 1, 4, 2, 6, 3] ]
for (a in as) {
    System.print("Before: %(a)")
    selectionSort.call(a)
    System.print("After : %(a)")
    System.print()
}


include c:\cxpl\codes;          \intrinsic 'code' declarations
string 0;                       \use zero-terminated strings

proc    SelSort(A, N);          \Selection sort
char    A;                      \address of array
int     N;                      \number of elements in array (size)
int     I, J, S, JS, T;
[for I:= 0 to N-2 do
        [S:= (~0)>>1;
        for J:= I to N-1 do     \find smallest element
                if A(J) < S then [S:= A(J);  JS:= J];
        T:= A(I);  A(I):= A(JS);  A(JS):= T;
        ];
];

func    StrLen(Str);            \Return number of characters in an ASCIIZ string
char    Str;
int     I;
for I:= 0 to -1>>1-1 do
        if Str(I) = 0 then return I;

char    Str;
[Str:= "Pack my box with five dozen liquor jugs.";
SelSort(Str, StrLen(Str));
Text(0, Str);  CrLf(0);
]


fcn selectionSort(list){  // sort a list of ints
   copy,r:=list.copy(),List();
   while(copy){
      min,idx:=(0).min(copy), copy.find(min);
      r.append(min);
      copy.del(idx);
   }
   r
}


F flatten(some_list)
   [Int] new_list
   L(sub_list) some_list
      new_list [+]= sub_list
   R new_list

F radix_sort(l, =p = -1, =s = -1)
   I s == -1
      s = String(max(l)).len
   I p == -1
      p = s

   V i = s - p
   I i >= s
      R l

   V bins = [[Int]()] * 10

   L(e) l
      bins[Int(String(e).zfill(s)[i])] [+]= e

   R flatten(bins.map(b -> radix_sort(b, @p - 1, @s)))

V arr = [7, 6, 5, 9, 8, 4, 3, 1, 2, 0]
print(radix_sort(arr))


/* ARM assembly AARCH64 Raspberry PI 3B */
/*  program radixSort64.s  */

/*******************************************/
/* Constantes file                         */
/*******************************************/
/* for this file see task include a file in language AArch64 assembly */
.include "../includeConstantesARM64.inc"

/*********************************/
/* Initialized data              */
/*********************************/
.data
szMessSortOk:       .asciz "Table sorted.\n"
szMessSortNok:      .asciz "Table not sorted !!!!!.\n"
sMessResult:        .asciz "Value  : @ \n"
szCarriageReturn:   .asciz "\n"

.align 4
TableNumber:      .quad   12485,301,16,25,5006,9,-154389710,26,4400,71,115
#TableNumber:     .quad   10,9,8,7,6,-5,4,3,2,1
                 .equ NBELEMENTS, (. - TableNumber) / 8
/*********************************/
/* UnInitialized data            */
/*********************************/
.bss
sZoneConv:       .skip 24
/*********************************/
/*  code section                 */
/*********************************/
.text
.global main
main:                                              // entry of program
    ldr x0,qAdrTableNumber                         // address number table
    mov x1,0                                       // first element
    mov x2,NBELEMENTS                              // number of élements
    bl radixSort
    ldr x0,qAdrTableNumber                         // address number table
    bl displayTable

    ldr x0,qAdrTableNumber                         // address number table
    mov x1,NBELEMENTS                              // number of élements
    bl isSorted                                    // control sort
    cmp x0,1                                       // sorted ?
    beq 1f
    ldr x0,qAdrszMessSortNok                       // no !! error sort
    bl affichageMess
    b 100f
1:                                                 // yes
    ldr x0,qAdrszMessSortOk
    bl affichageMess
100:                                               // standard end of the program
    mov x0,0                                       // return code
    mov x8,EXIT                                    // request to exit program
    svc 0                                          // perform the system call

qAdrsZoneConv:            .quad sZoneConv
qAdrszCarriageReturn:     .quad szCarriageReturn
qAdrsMessResult:          .quad sMessResult
qAdrTableNumber:          .quad TableNumber
qAdrszMessSortOk:         .quad szMessSortOk
qAdrszMessSortNok:        .quad szMessSortNok
/******************************************************************/
/*     control sorted table                                   */
/******************************************************************/
/* x0 contains the address of table */
/* x1 contains the number of elements  > 0  */
/* x0 return 0  if not sorted   1  if sorted */
isSorted:
    stp x2,lr,[sp,-16]!             // save  registers
    stp x3,x4,[sp,-16]!             // save  registers
    mov x2,0
    ldr x4,[x0,x2,lsl 3]
1:
    add x2,x2,1
    cmp x2,x1
    bge 99f
    ldr x3,[x0,x2, lsl 3]
    cmp x3,x4
    blt 98f
    mov x4,x3
    b 1b
98:
    mov x0,0                       // not sorted
    b 100f
99:
    mov x0,1                       // sorted
100:
    ldp x3,x4,[sp],16              // restaur  2 registers
    ldp x2,lr,[sp],16              // restaur  2 registers
    ret                            // return to address lr x30

/******************************************************************/
/*         radix sort                                             */
/******************************************************************/
/* r0 contains the address of table */
/* r1 contains the first element    */
/* r2 contains the number of element */
/* no registers save                 */
radixSort:
    str lr,[sp,-16]!                      // save  1 register
    mov x7,0b1111                         // mask one digit hexa
    mov x10,0                             // digit counter
1:
    add x3,x1,1                           // start index i
2:                                        // start loop
    ldr x4,[x0,x3,lsl 3]                  // load value A[i]
    and x8,x4,x7                          // and mask
    sub x5,x3,1                           // index j
3:
    ldr x6,[x0,x5,lsl 3]                  // load value A[j]
    and x9,x6,x7                          // and mask
    cmp x9,x8                             // compare one digit hexa
    ble 4f
    add x5,x5,1                           // increment index j
    str x6,[x0,x5,lsl 3]                  // store value A[j+1]
    sub x5,x5,2                           // j = j - 1
    cmp x5,x1
    bge 3b                                // loop if j >= first item
4:
    add x5,x5,1                           // increment index j
    str x4,[x0,x5,lsl 3]                  // store value A[i] in A[j+1]
    add x3,x3,1                           // increment index i
    cmp x3,x2                             // end ?
    blt 2b                                // no -> loop

    //bl displayTable
    lsl x7,x7,4                           // shift mask 4 bits left
    add x10,x10,1                         // increment counter
    cmp x10,16                            // 16 digits ?
    blt 1b                                // no loop
100:

    ldr lr,[sp],16                        // restaur  1 registers
    ret                                   // return to address lr x30

/******************************************************************/
/*      Display table elements                                */
/******************************************************************/
/* x0 contains the address of table */
displayTable:
    stp x1,lr,[sp,-16]!              // save  registers
    stp x2,x3,[sp,-16]!              // save  registers
    mov x2,x0                        // table address
    mov x3,0
1:                                   // loop display table
    ldr x0,[x2,x3,lsl 3]
    ldr x1,qAdrsZoneConv
    bl conversion10S                  // décimal conversion
    ldr x0,qAdrsMessResult
    ldr x1,qAdrsZoneConv
    bl strInsertAtCharInc            // insert result at // character
    bl affichageMess                 // display message
    add x3,x3,1
    cmp x3,NBELEMENTS - 1
    ble 1b
    ldr x0,qAdrszCarriageReturn
    bl affichageMess
    mov x0,x2
100:
    ldp x2,x3,[sp],16               // restaur  2 registers
    ldp x1,lr,[sp],16               // restaur  2 registers
    ret                             // return to address lr x30
/********************************************************/
/*        File Include fonctions                        */
/********************************************************/
/* for this file see task include a file in language AArch64 assembly */
.include "../includeARM64.inc"


with Ada.Text_IO;
procedure Radix_Sort is
   type Integer_Array is array (Positive range <>) of Integer;

   procedure Least_Significant_Radix_Sort (Data : in out Integer_Array; Base : Positive := 10) is
      type Bucket is record
         Count   : Natural := 0;
         Content : Integer_Array (Data'Range);
      end record;

      subtype Bucket_Index is Integer range -Base + 1 .. Base - 1;
      type Bucket_Array is array (Bucket_Index) of Bucket;

      procedure Append (To : in out Bucket; Item : Integer) is
      begin
         To.Count := To.Count + 1;
         To.Content (To.Count) := Item;
      end Append;

      function Get_Nth_Digit (Value : Integer; N : Positive) return Integer is
         Result : Integer := (Value / (Base ** (N - 1))) mod Base;
      begin
         if Value < 0 then
            Result := -Result;
         end if;
         return Result;
      end Get_Nth_Digit;

      function Get_Maximum return Natural is
         Result : Natural := 0;
      begin
         for I in Data'Range loop
            if abs (Data (I)) > Result then
               Result := abs (Data (I));
            end if;
         end loop;
         return Result;
      end Get_Maximum;

      function Split (Pass : Positive) return Bucket_Array is
         Buckets : Bucket_Array;
      begin
         for I in Data'Range loop
            Append (To   => Buckets (Get_Nth_Digit (Data (I), Pass)),
                    Item => Data (I));
         end loop;
         return Buckets;
      end Split;

      function Merge (Buckets : Bucket_Array) return Integer_Array is
         Result        : Integer_Array (Data'Range);
         Current_Index : Positive := 1;
      begin
         for Sublist in Buckets'Range loop
            for Item in 1 .. Buckets (Sublist).Count loop
               Result (Current_Index) := Buckets (Sublist).Content (Item);
               Current_Index := Current_Index + 1;
            end loop;
         end loop;
         return Result;
      end Merge;

      Max_Number  : Natural := Get_Maximum;
      Digit_Count : Positive := 1;
   begin
      -- count digits of biggest number
      while Max_Number > Base loop
         Digit_Count := Digit_Count + 1;
         Max_Number := Max_Number / Base;
      end loop;
      for Pass in 1 .. Digit_Count loop
         Data := Merge (Split (Pass));
      end loop;
   end Least_Significant_Radix_Sort;

   Test_Array : Integer_Array := (170, 45, 75, -90, -802, 24, 2, 66);
begin
   Least_Significant_Radix_Sort (Test_Array, 4);
   for I in Test_Array'Range loop
      Ada.Text_IO.Put (Integer'Image (Test_Array (I)));
   end loop;
   Ada.Text_IO.New_Line;
end Radix_Sort;


PROC radixsort = (REF []INT array) VOID:
(
    [UPB array]INT zero;
    [UPB array]INT one;
    BITS mask := 16r01;
    INT zero_index  := 0,
        one_index   := 0,
        array_index := 1;

    WHILE ABS(mask) > 0 DO
        WHILE array_index <= UPB array DO
            IF (BIN(array[array_index]) AND mask) = 16r0 THEN
                zero_index +:= 1;
                zero[zero_index] := array[array_index]
            ELSE
                one_index +:= 1;
                one[one_index] := array[array_index]
            FI;
            array_index +:= 1
        OD;

        array_index := 1;
        FOR i FROM 1 TO zero_index DO
            array[array_index] := zero[i];
            array_index +:= 1
        OD;

        FOR i FROM 1 TO one_index DO
            array[array_index] := one[i];
            array_index +:=1
        OD;

        array_index := 1;
        zero_index := one_index := 0;
        mask := mask SHL 1
    OD
);

main:
(
    [10]INT a;
    FOR i FROM 1 TO UPB a DO
        a[i] := ROUND(random*1000)
    OD;

    print(("Before:", a));
    print((newline, newline));
    radixsort(a);
    print(("After: ", a))
)


/* ARM assembly Raspberry PI  */
/*  program radixSort1.s  */

 /* REMARK 1 : this program use routines in a include file
   see task Include a file language arm assembly
   for the routine affichageMess conversion10
   see at end of this program the instruction include */
/* for constantes see task include a file in arm assembly */
/************************************/
/* Constantes                       */
/************************************/
.include "../constantes.inc"

/*********************************/
/* Initialized data              */
/*********************************/
.data
szMessSortOk:       .asciz "Table sorted.\n"
szMessSortNok:      .asciz "Table not sorted !!!!!.\n"
sMessResult:        .asciz "Value  : @ \n"
szCarriageReturn:   .asciz "\n"

.align 4
TableNumber:      .int   1,110,30,6,201,5004,29,10,1008,4,7,-25000
#TableNumber:       .int   10,9,8,7,6,5,4,3,2,1
                   .equ NBELEMENTS, (. - TableNumber) / 4
/*********************************/
/* UnInitialized data            */
/*********************************/
.bss
sZoneConv:            .skip 24
/*********************************/
/*  code section                 */
/*********************************/
.text
.global main
main:                               @ entry of program

    ldr r0,iAdrTableNumber          @ address number table
    mov r1,#0                       @ first element
    mov r2,#NBELEMENTS              @ number of élements
    bl radixSort
    ldr r0,iAdrTableNumber          @ address number table
    bl displayTable

    ldr r0,iAdrTableNumber          @ address number table
    mov r1,#NBELEMENTS              @ number of élements
    bl isSorted                     @ control sort
    cmp r0,#1                       @ sorted ?
    beq 1f
    ldr r0,iAdrszMessSortNok        @ no !! error sort
    bl affichageMess
    b 100f
1:                                  @ yes
    ldr r0,iAdrszMessSortOk
    bl affichageMess
100:                                @ standard end of the program
    mov r0, #0                      @ return code
    mov r7, #EXIT                   @ request to exit program
    svc #0                          @ perform the system call

iAdrszCarriageReturn:     .int szCarriageReturn
iAdrsMessResult:          .int sMessResult
iAdrTableNumber:          .int TableNumber
iAdrszMessSortOk:         .int szMessSortOk
iAdrszMessSortNok:        .int szMessSortNok
/******************************************************************/
/*     control sorted table                                   */
/******************************************************************/
/* r0 contains the address of table */
/* r1 contains the number of elements  > 0  */
/* r0 return 0  if not sorted   1  if sorted */
isSorted:
    push {r2-r4,lr}          @ save registers
    mov r2,#0
    ldr r4,[r0,r2,lsl #2]
1:
    add r2,#1
    cmp r2,r1
    movge r0,#1
    bge 100f
    ldr r3,[r0,r2, lsl #2]
    cmp r3,r4
    movlt r0,#0
    blt 100f
    mov r4,r3
    b 1b
100:
    pop {r2-r4,lr}
    bx lr                    @ return
/******************************************************************/
/*         radix sort                                             */
/******************************************************************/
/* r0 contains the address of table */
/* r1 contains the first element    */
/* r2 contains the number of element */
radixSort:
    push {r3-r10,lr}                      @ save registers
    mov r7,#0b1111                        @ mask one digit hexa
    mov r10,#0                            @ digit counter
1:
    add r3,r1,#1                          @ start index i
2:                                        @ start loop
    ldr r4,[r0,r3,lsl #2]                 @ load value A[i]
    and r8,r4,r7                          @ and mask
    sub r5,r3,#1                          @ index j
3:
    ldr r6,[r0,r5,lsl #2]                 @ load value A[j]
    and r9,r6,r7                          @ and mask
    cmp r9,r8                             @ compare one digit hexa
    ble 4f
    add r5,#1                             @ increment index j
    str r6,[r0,r5,lsl #2]                 @ store value A[j+1]
    sub r5,#2                             @ j = j - 1
    cmp r5,r1
    bge 3b                                @ loop if j >= first item
4:
    add r5,#1                             @ increment index j
    str r4,[r0,r5,lsl #2]                 @ store value A[i] in A[j+1]
    add r3,#1                             @ increment index i
    cmp r3,r2                             @ end ?
    blt 2b                                @ no -> loop

    //bl displayTable
    lsl r7,#4                             @ shift mask 4 bits left
    add r10,r10,#1                        @ increment counter
    cmp r10,#8                            @ 8 digits ?
    blt 1b                                @ no loop
100:
    pop {r3-r10,lr}
    bx lr                                 @ return

/******************************************************************/
/*      Display table elements                                */
/******************************************************************/
/* r0 contains the address of table */
displayTable:
    push {r0-r3,lr}                                    @ save registers
    mov r2,r0                                          @ table address
    mov r3,#0
1:                                                     @ loop display table
    ldr r0,[r2,r3,lsl #2]
    ldr r1,iAdrsZoneConv                               @
    bl conversion10S                                   @ décimal conversion
    ldr r0,iAdrsMessResult
    ldr r1,iAdrsZoneConv                               @ insert conversion
    bl strInsertAtCharInc
    bl affichageMess                                   @ display message
    add r3,#1
    cmp r3,#NBELEMENTS - 1
    ble 1b
    ldr r0,iAdrszCarriageReturn
    bl affichageMess
    mov r0,r2
100:
    pop {r0-r3,lr}
    bx lr
iAdrsZoneConv:           .int sZoneConv
/***************************************************/
/*      ROUTINES INCLUDE                           */
/***************************************************/
.include "../affichage.inc"


radixSort: function [items][
    base: 10
    a: new items

    rounds: inc floor (ln max a)/ln base
    loop rounds 'i [
        buckets: array.of: 2*base []
        baseI: base ^ i
        loop a 'n [
            digit: last digits n
            if n >= 0 -> digit: digit + base
            buckets\[digit]: buckets\[digit] ++ n
        ]
        a: new flatten buckets
    ]
    return a
]

print radixSort [3 1 2 8 5 7 9 4 6]