/* ARM assembly AARCH64 Raspberry PI 3B */
/*  program insertionSort64.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   1,3,6,2,5,9,10,8,4,7
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 insertionSort
    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
/******************************************************************/
/*         insertion sort                                              */
/******************************************************************/
/* x0 contains the address of table */
/* x1 contains the first element    */
/* x2 contains the number of element */
insertionSort:
    stp x1,lr,[sp,-16]!        // save  registers
    stp x2,x3,[sp,-16]!        // save  registers
    stp x4,x5,[sp,-16]!        // save  registers
    stp x6,x7,[sp,-16]!        // save  registers
    add x3,x1,1                // index i
1:                             // start loop 1
    ldr x4,[x0,x3,lsl 3]       // load value A[i]
    sub x5,x3,1                // index j
2:                             // start loop 2
    ldr x6,[x0,x5,lsl 3]       // load value A[j]
    cmp x6,x4                  // compare value
    ble 3f
    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                  // compare first element
    bge 2b                     // loop 2
3:
    add x5,x5,1                // increment index j
    str x4,[x0,x5,lsl 3]       // store value A[i}
    add x3,x3,1                // increment index i
    cmp x3,x2                  // end ?
    blt 1b                     // loop 1

100:
    ldp x6,x7,[sp],16          // restaur  2 registers
    ldp x4,x5,[sp],16          // restaur  2 registers
    ldp x2,x3,[sp],16          // restaur  2 registers
    ldp x1,lr,[sp],16          // restaur  2 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"


(defun insert (x xs)
   (cond ((endp xs) (list x))
         ((< x (first xs))
          (cons x xs))
         (t (cons (first xs)
                  (insert x (rest xs))))))

(defun isort (xs)
   (if (endp xs)
       nil
       (insert (first xs)
               (isort (rest xs)))))


# (sort xs) is the ordered list of all elements in list xs.
# This version preserves duplicates.
\sort==
    (\xs
    xs [] \x\xs
    append (sort; filter (gt x) xs);   # all the items less than x
    cons x; append (filter (eq x) xs); # all the items equal to x
    sort; filter (lt x) xs             # all the items greater than x
    )

# (unique xs) is the ordered list of unique elements in list xs.
\unique==
    (\xs
    xs [] \x\xs
    append (unique; filter (gt x) xs); # all the items less than x
    cons x;                            # x itself
    unique; filter (lt x) xs           # all the items greater than x
    )


PROC PrintArray(INT ARRAY a INT size)
  INT i

  Put('[)
  FOR i=0 TO size-1
  DO
    IF i>0 THEN Put(' ) FI
    PrintI(a(i))
  OD
  Put(']) PutE()
RETURN

PROC InsertionSort(INT ARRAY a INT size)
  INT i,j,value

  FOR i=1 TO size-1
  DO
    value=a(i)
    j=i-1
    WHILE j>=0 AND a(j)>value
    DO
      a(j+1)=a(j)
      j==-1
    OD
    a(j+1)=value
  OD
RETURN

PROC Test(INT ARRAY a INT size)
  PrintE("Array before sort:")
  PrintArray(a,size)
  InsertionSort(a,size)
  PrintE("Array after sort:")
  PrintArray(a,size)
  PutE()
RETURN

PROC Main()
  INT ARRAY
    a(10)=[1 4 65535 0 3 7 4 8 20 65530],
    b(21)=[10 9 8 7 6 5 4 3 2 1 0
      65535 65534 65533 65532 65531
      65530 65529 65528 65527 65526],
    c(8)=[101 102 103 104 105 106 107 108],
    d(12)=[1 65535 1 65535 1 65535 1
      65535 1 65535 1 65535]

  Test(a,10)
  Test(b,21)
  Test(c,8)
  Test(d,12)
RETURN


function insertionSort(array:Array)
{
	for(var i:int = 1; i < array.length;i++)
	{
		var value = array[i];
		var j:int = i-1;
		while(j >= 0 && array[j] > value)
		{
			array[j+1] = array[j];
			j--;
		}
		array[j+1] = value;
	}
	return array;
}


: mid ( l r -- mid ) over - 2/ -cell and + ;

: exch ( addr1 addr2 -- ) dup @ >r over @ swap ! r> swap ! ;

: partition ( l r -- l r r2 l2 )
  2dup mid @ >r ( r: pivot )
  2dup begin
    swap begin dup @  [email protected] < while cell+ repeat
    swap begin [email protected] over @ < while cell- repeat
    2dup <= if 2dup exch >r cell+ r> cell- then
  2dup > until  r> drop ;

: qsort ( l r -- )
  partition  swap rot
  \ 2over 2over - + < if 2swap then
  2dup < if recurse else 2drop then
  2dup < if recurse else 2drop then ;

: sort ( array len -- )
  dup 2 < if 2drop exit then
  1- cells over + qsort ;


type Data_Array is array(Natural range <>) of Integer;

procedure Insertion_Sort(Item : in out Data_Array) is
   First : Natural := Item'First;
   Last  : Natural := Item'Last;
   Value : Integer;
   J     : Integer;
begin
   for I in (First + 1)..Last loop
      Value := Item(I);
      J := I - 1;
      while J in Item'range and then Item(J) > Value loop
         Item(J + 1) := Item(J);
         J := J - 1;
      end loop;
      Item(J + 1) := Value;
   end loop;
end Insertion_Sort;


MODE DATA = REF CHAR;

PROC in place insertion sort = (REF[]DATA item)VOID:
BEGIN
   INT first := LWB item;
   INT last  := UPB item;
   INT j;
   DATA value;
   FOR i FROM first + 1 TO last DO
      value := item[i];
      j := i - 1;
   #  WHILE j >= LWB item AND j <= UPB item ANDF item[j] > value DO // example of ANDF extension #
      WHILE ( j >= LWB item AND j <= UPB item | item[j]>value | FALSE ) DO # no extension! #
         item[j + 1] := item[j];
         j -:=  1
      OD;
      item[j + 1] := value
   OD
END # in place insertion sort #;

[32]CHAR data := "big fjords vex quick waltz nymph";
[UPB data]DATA ref data;  FOR i TO UPB data DO ref data[i] := data[i] OD;
in place insertion sort(ref data);
FOR i TO UPB ref data DO print(ref data[i]) OD; print(new line);
print((data))


MODULE qsort_mod

  IMPLICIT NONE

  TYPE group
     INTEGER :: order    ! original order of unsorted data
     REAL    :: VALUE    ! values to be sorted by
  END TYPE group

CONTAINS

  RECURSIVE SUBROUTINE QSort(a,na)

    ! DUMMY ARGUMENTS
    INTEGER, INTENT(in) :: nA
    TYPE (group), DIMENSION(nA), INTENT(in out) :: A

    ! LOCAL VARIABLES
    INTEGER :: left, right
    REAL :: random
    REAL :: pivot
    TYPE (group) :: temp
    INTEGER :: marker

    IF (nA > 1) THEN

       CALL random_NUMBER(random)
       pivot = A(INT(random*REAL(nA-1))+1)%VALUE   ! Choice a random pivot (not best performance, but avoids worst-case)
       left = 1
       right = nA
       ! Partition loop
       DO
          IF (left >= right) EXIT
          DO
             IF (A(right)%VALUE <= pivot) EXIT
             right = right - 1
          END DO
          DO
             IF (A(left)%VALUE >= pivot) EXIT
             left = left + 1
          END DO
          IF (left < right) THEN
             temp = A(left)
             A(left) = A(right)
             A(right) = temp
          END IF
       END DO

       IF (left == right) THEN
          marker = left + 1
       ELSE
          marker = left
       END IF

       CALL QSort(A(:marker-1),marker-1)
       CALL QSort(A(marker:),nA-marker+1)

    END IF

  END SUBROUTINE QSort

END MODULE qsort_mod

! Test Qsort Module
PROGRAM qsort_test
  USE qsort_mod
  IMPLICIT NONE

  INTEGER, PARAMETER :: nl = 10, nc = 5, l = nc*nl, ns=33
  TYPE (group), DIMENSION(l) :: A
  INTEGER, DIMENSION(ns) :: seed
  INTEGER :: i
  REAL :: random
  CHARACTER(LEN=80) :: fmt1, fmt2
  ! Using the Fibonacci sequence to initialize seed:
  seed(1) = 1 ; seed(2) = 1
  DO i = 3,ns
     seed(i) = seed(i-1)+seed(i-2)
  END DO
  ! Formats of the outputs
  WRITE(fmt1,'(A,I2,A)') '(', nc, '(I5,2X,F6.2))'
  WRITE(fmt2,'(A,I2,A)') '(3x', nc, '("Ord.  Num.",3x))'
  PRINT *, "Unsorted Values:"
  PRINT fmt2,
  CALL random_SEED(put = seed)
  DO i = 1, l
     CALL random_NUMBER(random)
     A(i)%VALUE = NINT(1000*random)/10.0
     A(i)%order = i
     IF (MOD(i,nc) == 0) WRITE (*,fmt1) A(i-nc+1:i)
  END DO
  PRINT *
  CALL QSort(A,l)
  PRINT *, "Sorted Values:"
  PRINT fmt2,
  DO i = nc, l, nc
     IF (MOD(i,nc) == 0) WRITE (*,fmt1) A(i-nc+1:i)
  END DO
  STOP
END PROGRAM qsort_test


% insertion sorts in-place the array A. As Algol W procedures can't find the bounds %
% of an array parameter, the lower and upper bounds must be specified in lb and ub  %
procedure insertionSortI ( integer array A ( * ); integer value lb, ub ) ;
    for i := lb + 1 until ub do begin
        integer v, j;
        v := A( i );
        j := i - 1;
        while j >= lb and A( j ) > v do begin
            A( j + 1 ) := A( j );
            j := j - 1
        end while_j_ge_0_and_Aj_gt_v ;
        A( j + 1 ) := v
    end insertionSortI ;


-- In-place insertion sort
on insertionSort(theList, l, r) -- Sort items l thru r of theList.
    set listLength to (count theList)
    if (listLength < 2) then return
    -- Convert negative and/or transposed range indices.
    if (l < 0) then set l to listLength + l + 1
    if (r < 0) then set r to listLength + r + 1
    if (l > r) then set {l, r} to {r, l}

    -- The list as a script property to allow faster references to its items.
    script o
        property lst : theList
    end script

    -- Set up a minor optimisation whereby the latest instance of the highest value so far isn't
    -- put back into the list until either it's superseded or the end of the sort is reached.
    set highestSoFar to o's lst's item l
    set rv to o's lst's item (l + 1)
    if (highestSoFar > rv) then
        set o's lst's item l to rv
    else
        set highestSoFar to rv
    end if
    -- Work through the rest of the range, rotating values back into the sorted group as necessary.
    repeat with j from (l + 2) to r
        set rv to o's lst's item j
        if (highestSoFar > rv) then
            repeat with i from (j - 2) to l by -1
                set lv to o's lst's item i
                if (lv > rv) then
                    set o's lst's item (i + 1) to lv
                else
                    set i to i + 1
                    exit repeat
                end if
            end repeat
            set o's lst's item i to rv
        else
            set o's lst's item (j - 1) to highestSoFar
            set highestSoFar to rv
        end if
    end repeat
    set o's lst's item r to highestSoFar

    return -- nothing.
end insertionSort
property sort : insertionSort

-- Demo:
local aList
set aList to {60, 73, 11, 66, 6, 77, 41, 97, 59, 45, 64, 15, 91, 100, 22, 89, 77, 59, 54, 61}
sort(aList, 1, -1) -- Sort items 1 thru -1 of aList.
return aList


' version 23-10-2016
' compile with: fbc -s console

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

Sub quicksort(qs() As Long, l As Long, r As Long)

    Dim As ULong size = r - l +1
    If size < 2 Then Exit Sub

    Dim As Long i = l, j = r
    Dim As Long pivot = qs(l + size \ 2)

    Do
        While qs(i) < pivot
            i += 1
        Wend
        While pivot < qs(j)
            j -= 1
        Wend
        If i <= j Then
            Swap qs(i), qs(j)
            i += 1
            j -= 1
        End If
    Loop Until i > j

    If l < j Then quicksort(qs(), l, j)
    If i < r Then quicksort(qs(), i, r)

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 "unsorted ";
For i = a To b : Print Using "####"; array(i); : Next : Print

quicksort(array(), LBound(array), UBound(array))

Print "  sorted ";
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


/* ARM assembly Raspberry PI  */
/*  program insertionSort.s   */
/* look Pseudocode begin this task  */

/************************************/
/* Constantes                       */
/************************************/
.equ STDOUT, 1     @ Linux output console
.equ EXIT,   1     @ Linux syscall
.equ WRITE,  4     @ Linux syscall
/*********************************/
/* Initialized data              */
/*********************************/
.data
szMessSortOk:       .asciz "Table sorted.\n"
szMessSortNok:      .asciz "Table not sorted !!!!!.\n"
sMessResult:        .ascii "Value  : "
sMessValeur:        .fill 11, 1, ' '            @ size => 11
szCarriageReturn:  .asciz "\n"

.align 4
iGraine:  .int 123456
.equ NBELEMENTS,      10
#TableNumber:      .int   1,3,6,2,5,9,10,8,4,7
TableNumber:     .int   10,9,8,7,6,5,4,3,2,1
/*********************************/
/* UnInitialized data            */
/*********************************/
.bss
/*********************************/
/*  code section                 */
/*********************************/
.text
.global main
main:                                              @ entry of program

1:
    ldr r0,iAdrTableNumber                         @ address number table
    mov r1,#0
    mov r2,#NBELEMENTS                             @ number of élements
    bl insertionSort
    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 2f
    ldr r0,iAdrszMessSortNok                       @ no !! error sort
    bl affichageMess
    b 100f
2:                                                 @ 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

iAdrsMessValeur:          .int sMessValeur
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
/******************************************************************/
/*         insertion sort                                              */
/******************************************************************/
/* r0 contains the address of table */
/* r1 contains the first element    */
/* r2 contains the number of element */
insertionSort:
    push {r2,r3,r4,lr}                                     @ save registers
    add r3,r1,#1                                           @ start index i
1:                                                         @ start loop
    ldr r4,[r0,r3,lsl #2]                                  @ load value A[i]
    sub r5,r3,#1                                           @ index j
2:
    ldr r6,[r0,r5,lsl #2]                                  @ load value A[j]
    cmp r6,r4                                              @ compare value
    ble 3f
    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 2b                                                 @ loop if j >= first item
3:
    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 1b                                                 @ no -> loop

100:
    pop {r2,r3,r4,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,iAdrsMessValeur                             @ display value
    bl conversion10                                    @ call function
    ldr r0,iAdrsMessResult
    bl affichageMess                                   @ display message
    add r3,#1
    cmp r3,#NBELEMENTS - 1
    ble 1b
    ldr r0,iAdrszCarriageReturn
    bl affichageMess
100:
    pop {r0-r3,lr}
    bx lr
/******************************************************************/
/*     display text with size calculation                         */
/******************************************************************/
/* r0 contains the address of the message */
affichageMess:
    push {r0,r1,r2,r7,lr}                          @ save  registres
    mov r2,#0                                      @ counter length
1:                                                 @ loop length calculation
    ldrb r1,[r0,r2]                                @ read octet start position + index
    cmp r1,#0                                      @ if 0 its over
    addne r2,r2,#1                                 @ else add 1 in the length
    bne 1b                                         @ and loop
                                                   @ so here r2 contains the length of the message
    mov r1,r0                                      @ address message in r1
    mov r0,#STDOUT                                 @ code to write to the standard output Linux
    mov r7, #WRITE                                 @ code call system "write"
    svc #0                                         @ call systeme
    pop {r0,r1,r2,r7,lr}                           @ restaur des  2 registres */
    bx lr                                          @ return
/******************************************************************/
/*     Converting a register to a decimal unsigned                */
/******************************************************************/
/* r0 contains value and r1 address area   */
/* r0 return size of result (no zero final in area) */
/* area size => 11 bytes          */
.equ LGZONECAL,   10
conversion10:
    push {r1-r4,lr}                                 @ save registers
    mov r3,r1
    mov r2,#LGZONECAL

1:	                                            @ start loop
    bl divisionpar10U                               @ unsigned  r0 <- dividende. quotient ->r0 reste -> r1
    add r1,#48                                      @ digit
    strb r1,[r3,r2]                                 @ store digit on area
    cmp r0,#0                                       @ stop if quotient = 0
    subne r2,#1                                     @ else previous position
    bne 1b	                                    @ and loop
                                                    @ and move digit from left of area
    mov r4,#0
2:
    ldrb r1,[r3,r2]
    strb r1,[r3,r4]
    add r2,#1
    add r4,#1
    cmp r2,#LGZONECAL
    ble 2b
                                                      @ and move spaces in end on area
    mov r0,r4                                         @ result length
    mov r1,#' '                                       @ space
3:
    strb r1,[r3,r4]                                   @ store space in area
    add r4,#1                                         @ next position
    cmp r4,#LGZONECAL
    ble 3b                                            @ loop if r4 <= area size

100:
    pop {r1-r4,lr}                                    @ restaur registres
    bx lr                                             @return

/***************************************************/
/*   division par 10   unsigned                    */
/***************************************************/
/* r0 dividende   */
/* r0 quotient */
/* r1 remainder  */
divisionpar10U:
    push {r2,r3,r4, lr}
    mov r4,r0                                          @ save value
    //mov r3,#0xCCCD                                   @ r3 <- magic_number lower  raspberry 3
    //movt r3,#0xCCCC                                  @ r3 <- magic_number higter raspberry 3
    ldr r3,iMagicNumber                                @ r3 <- magic_number    raspberry 1 2
    umull r1, r2, r3, r0                               @ r1<- Lower32Bits(r1*r0) r2<- Upper32Bits(r1*r0)
    mov r0, r2, LSR #3                                 @ r2 <- r2 >> shift 3
    add r2,r0,r0, lsl #2                               @ r2 <- r0 * 5
    sub r1,r4,r2, lsl #1                               @ r1 <- r4 - (r2 * 2)  = r4 - (r0 * 10)
    pop {r2,r3,r4,lr}
    bx lr                                              @ leave function
iMagicNumber:  	.int 0xCCCCCCCD


def
  qsort( [] )    =  []
  qsort( p:xs )  =  qsort( xs.filter((< p)) ) + [p] + qsort( xs.filter((>= p)) )


insertionSort: function [items][
    arr: new items
    loop 1..(size items)-1 'i [
        value: arr\[i]
        j: i - 1

        while [and? -> j >= 0
                    -> value < arr\[j]]
        [
            arr\[j+1]: arr\[j]
            j: j - 1
        ]
        arr\[j+1]: value
    ]
    return arr
]

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


MsgBox % InsertionSort("")
MsgBox % InsertionSort("xxx")
MsgBox % InsertionSort("3,2,1")
MsgBox % InsertionSort("dog,000000,xx,cat,pile,abcde,1,cat,zz,xx,z")

InsertionSort(var) {                     ; SORT COMMA SEPARATED LIST
   StringSplit a, var, `,                ; make array, size = a0
   Loop % a0-1 {
      i := A_Index+1, v := a%i%, j := i-1
      While j>0 and a%j%>v
         u := j+1, a%u% := a%j%, j--
      u := j+1, a%u% := v
   }
   Loop % a0                             ; construct string from sorted array
      sorted .= "," . a%A_Index%
   Return SubStr(sorted,2)               ; drop leading comma
}


package main

import "fmt"

func main() {
    list := []int{31, 41, 59, 26, 53, 58, 97, 93, 23, 84}
    fmt.Println("unsorted:", list)

    quicksort(list)
    fmt.Println("sorted!  ", list)
}

func quicksort(a []int) {
    var pex func(int, int)
    pex = func(lower, upper int) {
        for {
            switch upper - lower {
            case -1, 0: // 0 or 1 item in segment.  nothing to do here!
                return
            case 1: // 2 items in segment
                // < operator respects strict weak order
                if a[upper] < a[lower] {
                    // a quick exchange and we're done.
                    a[upper], a[lower] = a[lower], a[upper]
                }
                return
            // Hoare suggests optimized sort-3 or sort-4 algorithms here,
            // but does not provide an algorithm.
            }

            // Hoare stresses picking a bound in a way to avoid worst case
            // behavior, but offers no suggestions other than picking a
            // random element.  A function call to get a random number is
            // relatively expensive, so the method used here is to simply
            // choose the middle element.  This at least avoids worst case
            // behavior for the obvious common case of an already sorted list.
            bx := (upper + lower) / 2
            b := a[bx]  // b = Hoare's "bound" (aka "pivot")
            lp := lower // lp = Hoare's "lower pointer"
            up := upper // up = Hoare's "upper pointer"
        outer:
            for {
                // use < operator to respect strict weak order
                for lp < upper && !(b < a[lp]) {
                    lp++
                }
                for {
                    if lp > up {
                        // "pointers crossed!"
                        break outer
                    }
                    // < operator for strict weak order
                    if a[up] < b {
                        break // inner
                    }
                    up--
                }
                // exchange
                a[lp], a[up] = a[up], a[lp]
                lp++
                up--
            }
            // segment boundary is between up and lp, but lp-up might be
            // 1 or 2, so just call segment boundary between lp-1 and lp.
            if bx < lp {
                // bound was in lower segment
                if bx < lp-1 {
                    // exchange bx with lp-1
                    a[bx], a[lp-1] = a[lp-1], b
                }
                up = lp - 2
            } else {
                // bound was in upper segment
                if bx > lp {
                    // exchange
                    a[bx], a[lp] = a[lp], b
                }
                up = lp - 1
                lp++
            }
            // "postpone the larger of the two segments" = recurse on
            // the smaller segment, then iterate on the remaining one.
            if up-lower < upper-lp {
                pex(lower, up)
                lower = lp
            } else {
                pex(lp, upper)
                upper = up
            }
        }
    }
    pex(0, len(a)-1)
}


{
  line[NR] = $0
}
END { # sort it with insertion sort
  for(i=1; i <= NR; i++) {
    value = line[i]
    j = i - 1
    while( ( j > 0) && ( line[j] > value ) ) {
      line[j+1] = line[j]
      j--
    }
    line[j+1] = value
  }
  #print it
  for(i=1; i <= NR; i++) {
    print line[i]
  }
}


#!/bin/bash

# Sorting integers with insertion sort

function  insertion_sort ()
{
    # input: unsorted integer array
    # output:  sorted integer array (ascending)

    # local variables
    local -a arr         # array
    local -i i           # integers
    local -i j
    local -i key
    local -i prev
    local -i leftval
    local -i N          # size of array

    arr=( $@ )    # copy args into array

    N=${#arr[*]}  # arr extent
    readonly N    # make const

    # insertion sort
    for (( i=1; i<$N; i++ ))  # c-style for loop
    do
	key=$((arr[$i]))      # current value
	prev=$((arr[$i-1]))   # previous value
	j=$i                  # current index

	while [ $j -gt 0 ]  && [ $key -lt $prev ]  # inner loop
	do
	    arr[$j]=$((arr[$j-1])) # shift

	    j=$(($j-1))            # decrement

	    prev=$((arr[$j-1]))    # last value

	done

	arr[$j]=$(($key))          # insert key in proper order

    done

    echo ${arr[*]}                   # output sorted array
}

################
function main ()
{
    # main script
    declare -a sorted

    # use a default if no cmdline list
    if [ $# -eq 0 ]; then
	arr=(10 8 20 100 -3 12 4 -5 32 0 1)
    else
	arr=($@) #cmdline list of ints
    fi

    echo
    echo "original"
    echo -e "\t ${arr[*]} \n"

    sorted=($(insertion_sort ${arr[*]}))  # call function

    echo
    echo "sorted:"
    echo -e "\t ${sorted[*]} \n"
 }

#script starts here
# source or run
if [[ "$0" == "bash" ]]; then # script is sourced
    unset main
else
    main "[email protected]"                 # call with cmdline args
fi

#END


qsort [] = []
qsort (x:xs) = qsort [y | y <- xs, y < x] ++ [x] ++ qsort [y | y <- xs, y >= x]


Sub InsertionSort (A() As Int)
	For i = 1 To A.Length - 1
		Dim value As Int = A(i)
		Dim j As Int = i - 1
		Do While j >= 0 And A(j) > value
			A(j + 1) = A(j)
			j = j - 1
		Loop
		A(j + 1) = value
	Next
End Sub

Sub Test
	Dim arr() As Int = Array As Int(34, 23, 54, 123, 543, 123)
	InsertionSort(arr)
	For Each i As Int In arr
		Log(i)
	Next
End Sub


DECLARE SUB InsertionSort (theList() AS INTEGER)

DIM n(10) AS INTEGER, L AS INTEGER, o AS STRING
FOR L = 0 TO 10
    n(L) = INT(RND * 32768)
NEXT
InsertionSort n()
FOR L = 1 TO 10
    PRINT n(L); ";";
NEXT

SUB InsertionSort (theList() AS INTEGER)
    DIM insertionElementIndex AS INTEGER
    FOR insertionElementIndex = 1 TO UBOUND(theList)
        DIM insertionElement AS INTEGER
        insertionElement = theList(insertionElementIndex)
        DIM j AS INTEGER
        j = insertionElementIndex - 1
        DO WHILE (j >= 0)
            'necessary for BASICs without short-circuit evaluation
            IF (insertionElement < theList(j)) THEN
                theList(j + 1) = theList(j)
                j = j - 1
            ELSE
                EXIT DO
            END IF
        LOOP
        theList(j + 1) = insertionElement
    NEXT
END SUB


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

procedure quicksort(X,op,lower,upper)                      #: return sorted list
local pivot,x

   if /lower := 1 then {                                   # top level call setup
      upper := *X
      op := sortop(op,X)                                   # select how and what we sort
      }

   if upper - lower > 0 then {
      every x := quickpartition(X,op,lower,upper) do       # find a pivot and sort ...
          /pivot | X := x                                  # ... how to return 2 values w/o a structure
      X := quicksort(X,op,lower,pivot-1)                   # ... left
      X := quicksort(X,op,pivot,upper)                     # ... right
      }

   return X
end

procedure quickpartition(X,op,lower,upper)                 #: quicksort partitioner helper
local   pivot
static  pivotL
initial pivotL := list(3)

   pivotL[1] := X[lower]                                   # endpoints
   pivotL[2] := X[upper]                                   # ... and
   pivotL[3] := X[lower+?(upper-lower)]                    # ... random midpoint
   if op(pivotL[2],pivotL[1]) then pivotL[2] :=: pivotL[1] # mini-
   if op(pivotL[3],pivotL[2]) then pivotL[3] :=: pivotL[2] # ... sort
   pivot := pivotL[2]                                      # median is pivot

   lower -:= 1
   upper +:= 1
   while lower < upper do {                                # find values on wrong side of pivot ...
      while op(pivot,X[upper -:= 1])                       # ... rightmost
      while op(X[lower +:=1],pivot)                        # ... leftmost
      if lower < upper then                                # not crossed yet
         X[lower] :=: X[upper]                             # ... swap
      }

   suspend lower                                           # 1st return pivot point
   suspend X                                               # 2nd return modified X (in case immutable)
end


get "libhdr"

let insertionSort(A, len) be
    for i = 1 to len-1 do
    $(  let value = A!i
        let j = i-1
        while j >= 0 & A!j > value do
        $(  A!(j+1) := A!j
            j := j-1
        $)
        A!(j+1) := value
    $)

let write(s, A, len) be
$(  writes(s)
    for i=0 to len-1 do writed(A!i, 4)
    wrch('*N')
$)

let start() be
$(  let array = table 4,65,2,-31,0,99,2,83,782,1
    let length = 10
    write("Before: ", array, length)
    insertionSort(array, length)
    write("After:  ", array, length)
$)


#include <stdio.h>

void insertion_sort(int*, const size_t);

void insertion_sort(int *a, const size_t n) {
	for(size_t i = 1; i < n; ++i) {
		int key = a[i];
		size_t j = i;
		while( (j > 0) && (key < a[j - 1]) ) {
			a[j] = a[j - 1];
			--j;
		}
		a[j] = key;
	}
}

int main (int argc, char** argv) {

    int a[] = {4, 65, 2, -31, 0, 99, 2, 83, 782, 1};

    const size_t n = sizeof(a) / sizeof(a[0]) ;   // array extent

    for (size_t i = 0; i < n; i++)
        printf("%d%s", a[i], (i == (n - 1))? "\n" : " ");

    insertion_sort(a, n);

    for (size_t i = 0; i < n; i++)
        printf("%d%s", a[i], (i == (n - 1))? "\n" : " ");

    return 0;
}


function qs, arr
  if (count = n_elements(arr)) lt 2 then return,arr
  pivot = total(arr) / count ; use the average for want of a better choice
  return,[qs(arr[where(arr le pivot)]),qs(arr[where(arr gt pivot)])]
 end


namespace Sort {
  using System;

  static class InsertionSort<T> where T : IComparable {
    public static void Sort(T[] entries) {
      Sort(entries, 0, entries.Length - 1);
    }

    public static void Sort(T[] entries, Int32 first, Int32 last) {
      for (var i = first + 1; i <= last; i++) {
        var entry = entries[i];
        var j = i;

        while (j > first && entries[j - 1].CompareTo(entry) > 0)
          entries[j] = entries[--j];

        entries[j] = entry;
      }
    }
  }
}


quicksort : Ord elem => List elem -> List elem
quicksort [] = []
quicksort (x :: xs) =
  let lesser = filter (< x) xs
      greater = filter(>= x) xs in
        (quicksort lesser) ++ [x] ++ (quicksort greater)


(defn insertion-sort [coll]
   (reduce (fn [result input]
             (let [[less more] (split-with #(< % input) result)]
               (concat less [input] more)))
           []
           coll))


% Insertion-sort an array in place.
insertion_sort = proc [T: type] (a: array[T])
              where T has lt: proctype (T,T) returns (bool)

    bound_lo: int := array[T]$low(a)
    bound_hi: int := array[T]$high(a)

    for i: int in int$from_to(bound_lo, bound_hi) do
        value: T := a[i]
        j: int := i - 1
        while j >= bound_lo cand value < a[j] do
            a[j+1] := a[j]
            j := j-1
        end
        a[j+1] := value
    end
end insertion_sort

% Print an array
print_arr = proc [T: type] (a: array[T], w: int, s: stream)
            where T has unparse: proctype (T) returns (string)
    for el: T in array[T]$elements(a) do
        stream$putright(s, T$unparse(el), w)
    end
    stream$putc(s, '\n')
end print_arr

start_up = proc ()
    ai = array[int]
    po: stream := stream$primary_output()
    test: ai := ai$[7, -5, 0, 2, 99, 16, 4, 20, 47, 19]

    stream$puts(po, "Before: ") print_arr[int](test, 3, po)
    insertion_sort[int](test)
    stream$puts(po, "After:  ") print_arr[int](test, 3, po)
end start_up


List do(
    quickSort := method(
        if(size > 1) then(
            pivot := at(size / 2 floor)
            return select(x, x < pivot) quickSort appendSeq(
                select(x, x == pivot) appendSeq(select(x, x > pivot) quickSort)
            )
        ) else(return self)
    )

    quickSortInPlace := method(
        copy(quickSort)
    )
)

lst := list(5, -1, -4, 2, 9)
lst quickSort println # ==> list(-4, -1, 2, 5, 9)
lst quickSortInPlace println # ==> list(-4, -1, 2, 5, 9)


# insertion_sort(var [value1 value2...]) sorts a list of integers.
function(insertion_sort var)
  math(EXPR last "${ARGC} - 1")         # Sort ARGV[1..last].
  foreach(i RANGE 1 ${last})
    # Extend the sorted area to ARGV[1..i].
    set(b ${i})
    set(v ${ARGV${b}})
    # Insert v == ARGV[b] in sorted order. While b > 1, check if b is
    # too high, then decrement b. After loop, set ARGV[b] = v.
    while(b GREATER 1)
      math(EXPR a "${b} - 1")
      set(u ${ARGV${a}})
      # Now u == ARGV[a]. Pretend v == ARGV[b]. Compare.
      if(u GREATER ${v})
        # ARGV[a] and ARGV[b] are in wrong order. Fix by moving ARGV[a]
        # to ARGV[b], making room for later insertion of v.
        set(ARGV${b} ${u})
      else()
        break()
      endif()
      math(EXPR b "${b} - 1")
    endwhile()
    set(ARGV${b} ${v})
  endforeach(i)

  set(answer)
  foreach(i RANGE 1 ${last})
    list(APPEND answer ${ARGV${i}})
  endforeach(i)
  set("${var}" "${answer}" PARENT_SCOPE)
endfunction(insertion_sort)


       C-PROCESS SECTION.
           PERFORM E-INSERTION VARYING WB-IX-1 FROM 1 BY 1
                               UNTIL WB-IX-1 > WC-SIZE.

...

       E-INSERTION SECTION.
       E-000.
           MOVE WB-ENTRY(WB-IX-1) TO WC-TEMP.
           SET WB-IX-2 TO WB-IX-1.

           PERFORM F-PASS UNTIL WB-IX-2 NOT > 1 OR
                                WC-TEMP NOT < WB-ENTRY(WB-IX-2 - 1).

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

       E-999.
           EXIT.

       F-PASS SECTION.
       F-000.
           MOVE WB-ENTRY(WB-IX-2 - 1) TO WB-ENTRY(WB-IX-2).
           SET WB-IX-2                DOWN BY 1.

       F-999.
           EXIT.


theory Quicksort
imports Main
begin

fun quicksort :: "('a :: linorder) list ⇒ 'a list" where
  "quicksort [] = []"
| "quicksort (x#xs) = (quicksort [y←xs. y<x]) @ [x] @ (quicksort [y←xs. y>x])"

lemma "quicksort [4::int, 2, 7, 1] = [1, 2, 4, 7]"
  by(code_simp)

lemma set_first_second_partition:
  fixes x :: "'a :: linorder"
  shows "{y ∈ ys. y < x} ∪ {x} ∪ {y ∈ ys. x < y} =
         insert x ys"
  by fastforce

lemma set_quicksort: "set (quicksort xs) = set xs"
  by(induction xs rule: quicksort.induct)
    (simp add: set_first_second_partition[simplified])+

theorem "sorted (quicksort xs)"
proof(induction xs rule: quicksort.induct)
  case 1
  show "sorted (quicksort [])" by simp
next
  case (2 x xs)
  assume IH_less:    "sorted (quicksort [y←xs. y<x])"
  assume IH_greater: "sorted (quicksort [y←xs. y>x])"
  have pivot_geq_first_partition:
    "∀z∈set (quicksort [y←xs. y<x]). z ≤ x"
    by (simp add: set_quicksort less_imp_le)
  have pivot_leq_second_partition:
    "∀z ∈ (set (quicksort [y←xs. y>x])). (x ≤ z)"
    by (simp add: set_quicksort less_imp_le)
  have first_partition_leq_second_partition:
    "∀p∈set (quicksort [y←xs. y<x]).
        ∀z ∈ (set (quicksort [y←xs. y>x])). (p ≤ z)"
    by (auto simp add: set_quicksort)

  from IH_less IH_greater
       pivot_geq_first_partition pivot_leq_second_partition
       first_partition_leq_second_partition
  show "sorted (quicksort (x # xs))"  by(simp add: sorted_append)
qed

text‹
The specification on rosettacode says
 ▪ All elements less than the pivot must be in the first partition.
 ▪ All elements greater than the pivot must be in the second partition.
Since this specification neither says "less than or equal" nor
"greater or equal", this quicksort implementation removes duplicate elements.
›
lemma "quicksort [1::int, 1, 1, 2, 2, 3] = [1, 2, 3]"
  by(code_simp)

text‹If we try the following, we automatically get a counterexample›
lemma "length (quicksort xs) = length xs"
(*
  Auto Quickcheck found a counterexample:
    xs = [a⇩1, a⇩1]
  Evaluated terms:
    length (quicksort xs) = 1
    length xs = 2
*)
  oops
end


(defun span (predicate list)
  (let ((tail (member-if-not predicate list)))
    (values (ldiff list tail) tail)))

(defun less-than (x)
  (lambda (y) (< y x)))

(defun insert (list elt)
  (multiple-value-bind (left right) (span (less-than elt) list)
    (append left (list elt) right)))

(defun insertion-sort (list)
  (reduce #'insert list :initial-value nil))


void insertionSort(T)(T[] data) pure nothrow @safe @nogc {
    foreach (immutable i, value; data[1 .. $]) {
        auto j = i + 1;
        for ( ; j > 0 && value < data[j - 1]; j--)
            data[j] = data[j - 1];
        data[j] = value;
    }
}

void main() {
    import std.stdio;
    auto items = [28, 44, 46, 24, 19, 2, 17, 11, 25, 4];
    items.insertionSort;
    items.writeln;
}


sel=: 1 : 'u # ['

quicksort=: 3 : 0
 if.
  1 >: #y
 do.
  y
 else.
  e=. y{~?#y
  (quicksort y <sel e),(y =sel e),quicksort y >sel e
 end.
)


insertSort(List<int> array){
  for(int i = 1; i < array.length; i++){
    int value = array[i];
    int j = i - 1;
    while(j >= 0 && array[j] > value){
      array[j + 1] = array[j];
      j = j - 1;
    }
    array[j + 1] = value;
  }
  return array;
}

void main() {
    List<int> a = insertSort([10, 3, 11, 15, 19, 1]);
    print('${a}');
}


program TestInsertionSort;

{$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 InsertionSort(var A: TArray);
var
  I, J: Integer;
  Item: TItem;

begin
  for I:= 1 + Low(A) to High(A) do begin
    Item:= A[I];
    J:= I - 1;
    while (J >= Low(A)) and (A[J] > Item) do begin
      A[J + 1]:= A[J];
      Dec(J);
    end;
    A[J + 1]:= 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;
  InsertionSort(A);
  for I:= Low(A) to High(A) do
    Write(A[I]:3);
  Writeln;
  Readln;
end.


public static <E extends Comparable<? super E>> List<E> quickSort(List<E> arr) {
    if (arr.isEmpty())
        return arr;
    else {
        E pivot = arr.get(0);

        List<E> less = new LinkedList<E>();
        List<E> pivotList = new LinkedList<E>();
        List<E> more = new LinkedList<E>();

        // Partition
        for (E i: arr) {
            if (i.compareTo(pivot) < 0)
                less.add(i);
            else if (i.compareTo(pivot) > 0)
                more.add(i);
            else
                pivotList.add(i);
        }

        // Recursively sort sublists
        less = quickSort(less);
        more = quickSort(more);

        // Concatenate results
        less.addAll(pivotList);
        less.addAll(more);
        return less;
    }
}


def insertionSort(array) {
    for i in 1..!(array.size()) {
        def value := array[i]
        var j := i-1
        while (j >= 0 && array[j] > value) {
            array[j + 1] := array[j]
            j -= 1
        }
        array[j+1] := value
   }
}


subr sort
  for i = 1 to len data[] - 1
    h = data[i]
    j = i - 1
    while j >= 0 and h < data[j]
      data[j + 1] = data[j]
      j -= 1
    .
    data[j + 1] = h
  .
.
data[] = [ 29 4 72 44 55 26 27 77 92 5 ]
call sort
print data[]


function sort(array, less) {

  function swap(i, j) {
    var t = array[i];
    array[i] = array[j];
    array[j] = t;
  }

  function quicksort(left, right) {

    if (left < right) {
      var pivot = array[left + Math.floor((right - left) / 2)],
          left_new = left,
          right_new = right;

      do {
        while (less(array[left_new], pivot)) {
          left_new += 1;
        }
        while (less(pivot, array[right_new])) {
          right_new -= 1;
        }
        if (left_new <= right_new) {
          swap(left_new, right_new);
          left_new += 1;
          right_new -= 1;
        }
      } while (left_new <= right_new);

      quicksort(left, right_new);
      quicksort(left_new, right);

    }
  }

  quicksort(0, array.length - 1);

  return array;
}


class
    MY_SORTED_SET [G -> COMPARABLE]
inherit
    TWO_WAY_SORTED_SET [G]
        redefine
            sort
        end
create
    make

feature
    sort
            -- Insertion sort
        local
            l_j: INTEGER
            l_value: like item
        do
            across 2 |..| count as ii loop
                from
                    l_j := ii.item - 1
                    l_value := Current.i_th (ii.item)
                until
                    l_j < 1 or Current.i_th (l_j) <= l_value
                loop
                    Current.i_th (l_j + 1) := Current.i_th (l_j)
                    l_j := l_j - 1
                end
                Current.i_th (l_j + 1) := l_value
            end
        end

end


import extensions;

extension op
{
    insertionSort()
        = self.clone().insertionSort(0, self.Length - 1);

    insertionSort(int first, int last)
    {
        for(int i := first + 1, i <= last, i += 1)
        {
            var entry := self[i];
            int j := i;

            while (j > first && self[j - 1] > entry)
            {
                self[j] := self[j - 1];

                j -= 1
            };

            self[j] := entry
        }
    }
}

public program()
{
    var list := new int[]{3, 9, 4, 6, 8, 1, 7, 2, 5};

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


DEFINE qsort ==
  [small]            # termination condition: 0 or 1 element
  []                 # do nothing
  [uncons [>] split] # pivot and two lists
  [enconcat]         # insert the pivot after the recursion
  binrec.            # recursion on the two lists


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

  def insert_sort([], sorted), do: sorted
  def insert_sort([h | t], sorted), do: insert_sort(t, insert(h, sorted))

  defp insert(x, []), do: [x]
  defp insert(x, sorted) when x < hd(sorted), do: [x | sorted]
  defp insert(x, [h | t]), do: [h | insert(x, t)]
end


(defun min-or-max-of-a-list (numbers comparator)
  "Return minimum or maximum of NUMBERS using COMPARATOR."
  (let ((extremum (car numbers)))
    (dolist (n (cdr numbers))
      (when (funcall comparator n extremum)
        (setq extremum n)))
    extremum))

(defun remove-number-from-list (numbers n)
  "Return NUMBERS without N.
If n is present twice or more, it will be removed only once."
  (let (result)
    (while numbers
      (let ((number (pop numbers)))
        (if (= number n)
            (while numbers
              (push (pop numbers) result))
          (push number result))))
    (nreverse result)))

(defun insertion-sort (numbers comparator)
  "Return sorted list of NUMBERS using COMPARATOR."
  (if numbers
      (let ((extremum (min-or-max-of-a-list numbers comparator)))
        (cons extremum
	      (insertion-sort (remove-number-from-list numbers extremum)
                              comparator)))
    nil))

(insertion-sort '(1 2 3 9 8 7 25 12 3 2 1) #'>)


-module(sort).
-export([insertion/1]).

insertion(L) -> lists:foldl(fun insert/2, [], L).

insert(X,[]) -> [X];
insert(X,L=[H|_]) when X =< H -> [X|L];
insert(X,[H|T]) -> [H|insert(X, T)].


PROGRAM INSERTION_SORT

DIM A[9]

PROCEDURE INSERTION_SORT(A[])
    LOCAL I,J
    FOR I=0 TO UBOUND(A,1) DO
        V=A[I]
        J=I-1
        WHILE J>=0 DO
          IF A[J]>V THEN
            A[J+1]=A[J]
            J=J-1
           ELSE
            EXIT
          END IF
        END WHILE
        A[J+1]=V
    END FOR
END PROCEDURE

BEGIN
  A[]=(4,65,2,-31,0,99,2,83,782,1)
  FOR I%=0 TO UBOUND(A,1) DO
     PRINT(A[I%];)
  END FOR
  PRINT
  INSERTION_SORT(A[])
  FOR I%=0 TO UBOUND(A,1) DO
     PRINT(A[I%];)
  END FOR
  PRINT
END PROGRAM


function insertion_sort(sequence s)
    object temp
    integer j
    for i = 2 to length(s) do
        temp = s[i]
        j = i-1
        while j >= 1 and compare(s[j],temp) > 0 do
            s[j+1] = s[j]
            j -= 1
        end while
        s[j+1] = temp
    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,insertion_sort(s),{2})


// This function performs an insertion sort with an array.
// The input parameter is a generic array (any type that can perform comparison).
// As is typical of functional programming style the input array is not modified;
// a copy of the input array is made and modified and returned.
let insertionSort (A: _ array) =
    let B = Array.copy A
    for i = 1 to B.Length - 1 do
        let mutable value = B.[i]
        let mutable j = i - 1
        while (j >= 0 && B.[j] > value) do
            B.[j+1] <- B.[j]
            j <- j - 1
        B.[j+1] <- value
    B  // the array B is returned


USING: kernel prettyprint sorting.extras sequences ;

: insertion-sort ( seq -- sorted-seq )
    <reversed> V{ } clone [ swap insort-left! ] reduce ;

{ 6 8 5 9 3 2 1 4 7 } insertion-sort .


: insert ( start end -- start )
  dup @ >r ( r: v )	\ v = a[i]
  begin
    2dup <			\ j>0
  while
    [email protected] over cell- @ <		\ a[j-1] > v
  while
    cell-			\ j--
    dup @ over cell+ !		\ a[j] = a[j-1]
  repeat then
  r> swap ! ;		\ a[j] = v

: sort ( array len -- )
  1 ?do dup i cells + insert loop drop ;

create test 7 , 3 , 0 , 2 , 9 , 1 , 6 , 8 , 4 , 5 ,
test 10 sort
test 10 cells dump


subroutine sort(n, a)
    implicit none
    integer :: n, i, j
    real :: a(n), x

    do i = 2, n
        x = a(i)
        j = i - 1
        do while (j >= 1)
            if (a(j) <= x) exit
            a(j + 1) = a(j)
            j = j - 1
        end do
        a(j + 1) = x
    end do
end subroutine


fun qsort( xs : list<int> ) : div list<int> {
  match(xs) {
    Cons(x,xx) -> {
      val ys = xx.filter fn(el) { el < x }
      val zs = xx.filter fn(el) { el >= x }
      qsort(ys) + [x] + qsort(zs)
    }
    Nil -> Nil
  }
}


fun <E : Comparable<E>> List<E>.qsort(): List<E> =
        if (size < 2) this
        else filter { it < first() }.qsort() +
                filter { it == first() } +
                filter { it > first() }.qsort()


F gnomesort(&a)
   V i = 1
   V j = 2
   L i < a.len
      I a[i - 1] <= a[i]
         i = j
         j++
      E
         swap(&a[i - 1], &a[i])
         i--
         I i == 0
            i = j
            j++
   R a

print(gnomesort(&[3, 4, 2, 5, 1, 6]))


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

Sub insertionSort( arr() As Long )

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

  Dim As Long lb = LBound(arr)
  Dim As Long i, j, value

  For i = lb +1 To UBound(arr)

    value = arr(i)
    j = i -1
    While j >= lb  And arr(j) > value
      arr(j +1) = arr(j)
      j = j -1
    Wend

    arr(j +1) = value

  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
insertionSort(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


*        Gnome sort - Array base 0 - 15/04/2020
GNOME    CSECT
         USING  GNOME,R13          base register
         B      72(R15)            skip savearea
         DC     17F'0'             savearea
         SAVE   (14,12)            save previous context
         ST     R13,4(R15)         link backward
         ST     R15,8(R13)         link forward
         LR     R13,R15            set addressability
         LA     R6,1               i=1
         LA     R7,2               j=2
       DO WHILE=(C,R6,LT,NN)       while i<nn
         LR     R1,R6                i
         SLA    R1,2                 ~
         LA     R8,TT-4(R1)          @tt(i-1)
         LA     R9,TT(R1)            @tt(i)
         L      R2,0(R8)             tt(i-1)
       IF     C,R2,LE,0(R9) THEN     if tt(i-1)<=tt(i) then
         LR     R6,R7                  i=j
         LA     R7,1(R7)               j=j+1
       ELSE     ,                    else
         L      R4,0(R8)               t=tt(i-1)
         L      R3,0(R9)               tt(i)
         ST     R3,0(R8)               tt(i-1)=tt(i)
         ST     R4,0(R9)               tt(i)=t
         BCTR   R6,0                   i=i-1
       IF   LTR,R6,Z,R6 THEN           if i=0 then
         LR     R6,R7                    i=j
         LA     R7,1(R7)                 j=j+1
       ENDIF    ,                      endif
       ENDIF    ,                    endif
       ENDDO    ,                  endwhile
         LA     R10,PG             @buffer
         LA     R7,TT              @tt
         LA     R6,1               i=1
       DO WHILE=(C,R6,LE,NN)       do i=1 to nn
         L      R2,0(R7)             tt(i)
         XDECO  R2,XDEC              edit tt(i)
         MVC    0(5,R10),XDEC+7      output tt(i)
         LA     R10,5(R10)           @buffer
         LA     R7,4(R7)             @tt++
         LA     R6,1(R6)             i++
       ENDDO    ,                  enddo i
         XPRNT  PG,L'PG            print buffer
         L      R13,4(0,R13)       restore previous savearea pointer
         RETURN (14,12),RC=0       restore registers from calling save
TT       DC     F'557',F'5143',F'5432',F'6798',F'2874'
         DC     F'3499',F'6949',F'4992',F'2555',F'4175'
         DC     F'8264',F'3522',F'2045',F'2963',F'2625'
         DC     F'-764',F'1845',F'1485',F'5792',F'7562'
         DC     F'5044',F'3598',F'6817',F'4891',F'4350'
NN       DC     A((NN-TT)/L'TT)    number of items of tt
XDEC     DS     CL12               temp for xdeco
PG       DC     CL125' '           buffer
         REGEQU
         END    GNOME


/* ARM assembly AARCH64 Raspberry PI 3B */
/*  program gnomeSort64.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   1,3,6,2,5,9,10,8,4,7
#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 gnomeSort
    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
/******************************************************************/
/*         gnome sort                                              */
/******************************************************************/
/* x0 contains the address of table */
/* x1 contains the first element    */
/* x2 contains the number of element */
gnomeSort:
    stp x1,lr,[sp,-16]!        // save  registers
    stp x2,x3,[sp,-16]!        // save  registers
    stp x4,x5,[sp,-16]!        // save  registers
    stp x6,x7,[sp,-16]!        // save  registers
    stp x8,x9,[sp,-16]!        // save  registers
    sub x2,x2,1                // compute end index n - 1
    add x3,x1,1                // index i
    add x7,x1,2                // index j
1:                             // start loop 1
    cmp x3,x2
    bgt 100f
    sub x4,x3,1                //
    ldr x5,[x0,x3,lsl 3]       // load value A[j]
    ldr x6,[x0,x4,lsl 3]       // load value A[j+1]
    cmp x5,x6                  // compare value
    bge 2f
    str x6,[x0,x3,lsl 3]       // if smaller inversion
    str x5,[x0,x4,lsl 3]
    sub x3,x3,1                // i = i - 1
    cmp x3,x1
    bne 1b                     // loop 1
2:
    mov x3,x7                  // i = j
    add x7,x7,1                // j = j + 1
    b 1b                       // loop 1

100:
    ldp x8,x9,[sp],16          // restaur  2 registers
    ldp x6,x7,[sp],16          // restaur  2 registers
    ldp x4,x5,[sp],16          // restaur  2 registers
    ldp x2,x3,[sp],16          // restaur  2 registers
    ldp x1,lr,[sp],16          // restaur  2 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"


PROC PrintArray(INT ARRAY a INT size)
  INT i

  Put('[)
  FOR i=0 TO size-1
  DO
    IF i>0 THEN Put(' ) FI
    PrintI(a(i))
  OD
  Put(']) PutE()
RETURN

PROC GnomeSort(INT ARRAY a INT size)
  INT i,j,tmp

  i=1 j=2
  WHILE i<size
  DO
    IF a(i-1)<=a(i) THEN
      i=j j==+1
    ELSE
      tmp=a(i-1) a(i-1)=a(i) a(i)=tmp
      i==-1
      IF i=0 THEN
        i=j j==+1
      FI
    FI
  OD
RETURN

PROC Test(INT ARRAY a INT size)
  PrintE("Array before sort:")
  PrintArray(a,size)
  GnomeSort(a,size)
  PrintE("Array after sort:")
  PrintArray(a,size)
  PutE()
RETURN

PROC Main()
  INT ARRAY
    a(10)=[1 4 65535 0 3 7 4 8 20 65530],
    b(21)=[10 9 8 7 6 5 4 3 2 1 0
      65535 65534 65533 65532 65531
      65530 65529 65528 65527 65526],
    c(8)=[101 102 103 104 105 106 107 108],
    d(12)=[1 65535 1 65535 1 65535 1
      65535 1 65535 1 65535]

  Test(a,10)
  Test(b,21)
  Test(c,8)
  Test(d,12)
RETURN


InsertionSort := function(L)
  local n, i, j, x;
  n := Length(L);
  for i in [ 2 .. n ] do
    x := L[i];
    j := i - 1;
    while j >= 1 and L[j] > x do
      L[j + 1] := L[j];
      j := j - 1;
    od;
    L[j + 1] := x;
  od;
end;

s := "BFKRIMPOQACNESWUTXDGLVZHYJ";
InsertionSort(s);
s;
# "ABCDEFGHIJKLMNOPQRSTUVWXYZ"


package main

import "fmt"

func insertionSort(a []int) {
    for i := 1; i < len(a); i++ {
        value := a[i]
        j := i - 1
        for j >= 0 && a[j] > value {
            a[j+1] = a[j]
            j = j - 1
        }
        a[j+1] = value
    }
}

func main() {
    list := []int{31, 41, 59, 26, 53, 58, 97, 93, 23, 84}
    fmt.Println("unsorted:", list)

    insertionSort(list)
    fmt.Println("sorted!  ", list)
}


include "std.lobster"

def quicksort(xs, lt):
    if xs.length <= 1:
        xs
    else:
        pivot := xs[0]
        tail := xs.slice(1, -1)
        f1 := filter tail:  lt(_, pivot)
        f2 := filter tail: !lt(_, pivot)
        append(append(quicksort(f1, lt), [ pivot ]),
                      quicksort(f2, lt))

sorted := [ 3, 9, 5, 4, 1, 3, 9, 5, 4, 1 ].quicksort(): _a < _b
print sorted


function gnomeSort(array:Array)
{
	var pos:uint = 0;
	while(pos < array.length)
	{
		if(pos == 0 || array[pos] >= array[pos-1])
			pos++;
		else
		{
			var tmp = array[pos];
			array[pos] = array[pos-1];
			array[pos-1] = tmp;
			pos--;
		}
	}
	return array;
}


generic
   type Element_Type is private;
   type Index is (<>);
   type Collection is array(Index) of Element_Type;
   with function "<=" (Left, Right : Element_Type) return Boolean is <>;
procedure Gnome_Sort(Item : in out Collection);


MODE SORTSTRUCT = CHAR;

PROC inplace gnome sort = (REF[]SORTSTRUCT list)REF[]SORTSTRUCT:
BEGIN
  INT i:=LWB list + 1, j:=LWB list + 2;
  WHILE i <= UPB list DO
    IF list[i-1] <= list[i] THEN
      i := j; j+:=1
    ELSE
      SORTSTRUCT swap = list[i-1]; list[i-1]:= list[i]; list[i]:= swap;
      i-:=1;
      IF i=LWB list THEN i:=j; j+:=1 FI
    FI
  OD;
  list
END;

PROC gnome sort = ([]SORTSTRUCT seq)[]SORTSTRUCT:
  in place gnome sort(LOC[LWB seq: UPB seq]SORTSTRUCT:=seq);

[]SORTSTRUCT char array data = "big fjords vex quick waltz nymph";
print((gnome sort(char array data), new line))


def insertionSort = { list ->

    def size = list.size()
    (1..<size).each { i ->
        def value = list[i]
        def j = i - 1
        for (; j >= 0 && list[j] > value; j--) {
            print "."; list[j+1] = list[j]
        }
        print "."; list[j+1] = value
    }
    list
}


import Data.List (insert)

insertionSort :: Ord a => [a] -> [a]
insertionSort = foldr insert []

-- Example use:
-- *Main> insertionSort [6,8,5,9,3,2,1,4,7]
-- [1,2,3,4,5,6,7,8,9]


; quicksort (lists, functional)

to small? :list
  output or [empty? :list] [empty? butfirst :list]
end
to quicksort :list
  if small? :list [output :list]
  localmake "pivot first :list
  output (sentence
    quicksort filter [? < :pivot] butfirst :list
              filter [? = :pivot]          :list
    quicksort filter [? > :pivot] butfirst :list
  )
end

show quicksort [1 3 5 7 9 8 6 4 2]


/* ARM assembly Raspberry PI  */
/*  program gnomeSort.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,3,6,2,5,9,10,8,4,7
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 gnomeSort
    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
/******************************************************************/
/*         gnome Sort                                          */
/******************************************************************/
/* r0 contains the address of table */
/* r1 contains the first element    */
/* r2 contains the number of element */
gnomeSort:
    push {r1-r9,lr}           @ save registers
    sub r2,r2,#1              @ compute end index = n - 1
    add r3,r1,#1              @ index i
    add r7,r1,#2              @ j
1:                            @ start loop 1
    cmp r3,r2
    bgt 100f
    sub r4,r3,#1
    ldr r5,[r0,r3,lsl #2]     @ load value A[j]
    ldr r6,[r0,r4,lsl #2]     @ load value A[j-1]
    cmp r5,r6                 @ compare value
    bge 2f
    str r6,[r0,r3,lsl #2]     @ if smaller inversion
    str r5,[r0,r4,lsl #2]
    sub r3,r3,#1             @ i = i - 1
    cmp r3,r1
    moveq r3,r7               @ if i = 0  i = j
    addeq r7,r7,#1            @ if i = 0  j = j+1
    b 1b                      @ loop 1
2:
    mov r3,r7                 @ i = j
    add r7,r7,#1              @ j = j + 1
    b 1b                      @ loop 1

100:
    pop {r1-r9,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"


class InsertionSort {
  @:generic
  public static function sort<T>(arr:Array<T>) {
    for (i in 1...arr.length) {
      var value = arr[i];
      var j = i - 1;
      while (j >= 0 && Reflect.compare(arr[j], value) > 0) {
        arr[j + 1] = arr[j--];
      }
      arr[j + 1] = value;
    }
  }
}

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);
    InsertionSort.sort(integerArray);
    Sys.println('Sorted Integers:   ' + integerArray);
    Sys.println('Unsorted Floats:   ' + floatArray);
    InsertionSort.sort(floatArray);
    Sys.println('Sorted Floats:     ' + floatArray);
    Sys.println('Unsorted Strings:  ' + stringArray);
    InsertionSort.sort(stringArray);
    Sys.println('Sorted Strings:    ' + stringArray);
  }
}


DO i = 2, LEN(A)
   value = A(i)
   j = i - 1
 1 IF( j > 0 ) THEN
     IF( A(j) > value ) THEN
       A(j+1) = A(j)
       j = j - 1
       GOTO 1 ! no WHILE in HicEst
     ENDIF
   ENDIF
   A(j+1) = value
ENDDO


quicksort(List, Sorted) :-
    quicksort(List, [], Sorted).

quicksort([], Sorted, Sorted).
quicksort([Pivot| Rest], Acc, Sorted) :-
    partition(Rest, Pivot, Smaller0, Bigger0),
    quicksort(Smaller0, [Pivot| Bigger], Sorted),
    quicksort(Bigger0, Acc, Bigger).

partition([], _, [], []).
partition([X| Xs], Pivot, Smalls, Bigs) :-
    (   X @< Pivot ->
        Smalls = [X| Rest],
        partition(Xs, Pivot, Rest, Bigs)
    ;   Bigs = [X| Rest],
        partition(Xs, Pivot, Smalls, Rest)
    ).


gnomeSort: function [items][
    i: 1
    j: 2
    arr: new items
    while [i < size arr][
        if? arr\[i-1] =< arr\[i] [
            i: j
            j: j + 1
        ]
        else [
            tmp: arr\[i]
            arr\[i]: arr\[i-1]
            arr\[i-1]: tmp

            i: i-1
            if i=0 [
                i: j
                j: j + 1
            ]
        ]
    ]
    return arr
]

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


MsgBox % GnomeSort("")
MsgBox % GnomeSort("xxx")
MsgBox % GnomeSort("3,2,1")
MsgBox % GnomeSort("dog,000000,xx,cat,pile,abcde,1,cat,zz,xx,z")

GnomeSort(var) {                         ; SORT COMMA SEPARATED LIST
   StringSplit a, var, `,                ; make array, size = a0
   i := 2, j := 3
   While i <= a0 {                       ; stop when sorted
      u := i-1
      If (a%u% < a%i%)                   ; search for pairs to swap
         i := j, j := j+1
      Else {                             ; swap
         t := a%u%, a%u% := a%i%, a%i% := t
         If (--i = 1)                    ; restart search
            i := j, j++
      }
   }
   Loop % a0                             ; construct string from sorted array
      sorted .= "," . a%A_Index%
   Return SubStr(sorted,2)               ; drop leading comma
}


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

procedure insertionsort(X,op)        #: return sorted X
local i,temp

   op := sortop(op,X)                # select how and what we sort

   every i := 2 to *X do {
      temp := X[j := i]
      while op(temp,X[1 <= (j -:= 1)]) do
         X[j+1] := X[j]
      X[j+1] := temp
      }
   return X
end


List do(
  insertionSortInPlace := method(
    for(j, 1, size - 1,
      key := at(j)
      i := j - 1

      while(i >= 0 and at(i) > key,
        atPut(i + 1, at(i))
        i = i - 1
      )
      atPut(i + 1, key)
    )
  )
)

lst := list(7, 6, 5, 9, 8, 4, 3, 1, 2, 0)
lst insertionSortInPlace println # ==> list(0, 1, 2, 3, 4, 5, 6, 7, 8, 9)


#!/usr/bin/awk -f

BEGIN {
    d[1] = 3.0
    d[2] = 4.0
    d[3] = 1.0
    d[4] = -8.4
    d[5] = 7.2
    d[6] = 4.0
    d[7] = 1.0
    d[8] = 1.2
    showD("Before: ")
    gnomeSortD()
    showD("Sorted: ")
    exit
}

function gnomeSortD(    i) {
    for (i = 2; i <= length(d); i++) {
        if (d[i] < d[i-1]) gnomeSortBackD(i)
    }
}

function gnomeSortBackD(i,     t) {
    for (; i > 1 && d[i] < d[i-1]; i--) {
        t = d[i]
        d[i] = d[i-1]
        d[i-1] = t
    }
}

function showD(p,   i) {
    printf p
    for (i = 1; i <= length(d); i++) {
        printf d[i] " "
    }
    print ""
}


DIM a(0 TO n-1) AS INTEGER
'...more code...
sort:
i = 1
j = 2

WHILE(i < UBOUND(a) - LBOUND(a))
  IF a(i-1) <= a(i) THEN
    i = j
    j = j + 1
  ELSE
    SWAP a(i-1), a(i)
    i = i - 1
    IF i = 0 THEN
       i = j
       j = j + 1
    END IF
  END IF
WEND


theory Insertionsort
  imports Main
begin

fun insert :: "int ⇒ int list ⇒ int list" where
  "insert x [] = [x]"
| "insert x (y#ys) = (if x ≤ y then (x#y#ys) else y#(insert x ys))"

text‹Example:›
lemma "insert 4 [1, 2, 3, 5, 6] = [1, 2, 3, 4, 5, 6]" by(code_simp)

fun insertionsort :: "int list ⇒ int list" where
  "insertionsort [] = []"
| "insertionsort (x#xs) = insert x (insertionsort xs)"

lemma "insertionsort [4, 2, 6, 1, 8, 1] = [1, 1, 2, 4, 6, 8]" by(code_simp)

text‹
Our function behaves the same as the \<^term>‹sort› function of the standard library.
›
lemma insertionsort: "insertionsort xs = sort xs"
proof(induction xs)
  case Nil
  show "insertionsort [] = sort []" by simp
next
  case (Cons x xs)
  text‹Our \<^const>‹insert› behaves the same as the std libs \<^const>‹insort›.›
  have "insert a as = insort a as" for a as by(induction as) simp+
  with Cons show "insertionsort (x # xs) = sort (x # xs)" by simp
qed

text‹
Given that we behave the same as the std libs sorting algorithm,
we get the correctness properties for free.
›
corollary insertionsort_correctness:
  "sorted (insertionsort xs)" and
  "set (insertionsort xs) = set xs"
  using insertionsort by(simp)+

text‹
The Haskell implementation from
🌐‹https://rosettacode.org/wiki/Sorting_algorithms/Insertion_sort#Haskell›
also behaves the same. Ultimately, they all return a sorted list.
One exception to the Haskell implementation is that the type signature of
\<^const>‹foldr› in Isabelle is slightly different:
The initial value of the accumulator goes last.
›
definition rosettacode_haskell_insertionsort :: "int list ⇒ int list" where
  "rosettacode_haskell_insertionsort ≡ λxs. foldr insert xs []"

lemma "rosettacode_haskell_insertionsort [4, 2, 6, 1, 8, 1] =
       [1, 1, 2, 4, 6, 8]" by(code_simp)

lemma "rosettacode_haskell_insertionsort xs = insertionsort xs"
  unfolding rosettacode_haskell_insertionsort_def by(induction xs) simp+

end


public static void insertSort(int[] A){
  for(int i = 1; i < A.length; i++){
    int value = A[i];
    int j = i - 1;
    while(j >= 0 && A[j] > value){
      A[j + 1] = A[j];
      j = j - 1;
    }
    A[j + 1] = value;
  }
}


qsort(a) = if eof(first a) then a else follow(qsort(b0),qsort(b1)) fi
 where
    p = first a < a;
    b0 = a whenever p;
    b1 = a whenever not p;
    follow(x,y) = if xdone then y upon xdone else x fi
                    where
                       xdone = iseod x fby xdone or iseod x;
                    end;
 end


@ECHO OFF
SETLOCAL EnableExtensions EnableDelayedExpansion
:: GnomeSort.cmd in WinNT Batch using pseudo array.
:: Set the number of random elements to sort.
SET numElements=100
:: Decrement numElements for use in zero-based loops as in (0, 1, %numElements% - 1).
SET /A tmpElements=%numElements% - 1

:: Create array of random numbers and output to file.
ECHO GnomeSort Random Input 0 to %tmpElements%:>%~n0.txt
FOR /L %%X IN (0, 1, %tmpElements%) DO (
	SET array[%%X]=!RANDOM!
	ECHO !array[%%X]!>>%~n0.txt
)

:GnomeSort
:: Initialize the pointers i-1, i, and j.
SET gs1=0
SET gs2=1
SET gs3=2
:GS_Loop
:: Implementing a WHILE loop in WinNT batch using GOTO. It only executes
:: if the condition is true and continues until the condition is false.
:: First, display [i-1][j - 2] to the Title Bar.
SET /A gsTmp=%gs3% - 2
TITLE GnomeSort:[%gs1%][%gsTmp%] of %tmpElements%
:: ...then start Main Loop. It's a direct implementation of the
:: pseudo code supplied by Rosetta Code. I had to add an additional
:: pointer to represent i-1, because of limitations in WinNT Batch.
IF %gs2% LSS %numElements% (
	REM if i-1 <= i advance pointers to next unchecked element, then loop.
	IF !array[%gs1%]! LEQ !array[%gs2%]! (
		SET /A gs1=%gs3% - 1
		SET /A gs2=%gs3%
		SET /A gs3=%gs3% + 1
	) ELSE (
	REM ... else swap i-1 and i, decrement pointers to check previous element, then loop.
		SET gsTmp=!array[%gs1%]!
		SET array[%gs1%]=!array[%gs2%]!
		SET array[%gs2%]=!gsTmp!
		SET /A gs1-=1
		SET /A gs2-=1
		REM if first element has been reached, set pointers to next unchecked element.
		IF !gs2! EQU 0 (
			SET /A gs1=%gs3% - 1
			SET /A gs2=%gs3%
			SET /A gs3=%gs3% + 1
		)
	)
	GOTO :GS_Loop
)
TITLE GnomeSort:[%gs1%][%gsTmp%] - Done!

:: write sorted elements out to file
ECHO.>>%~n0.txt
ECHO GnomeSort Sorted Output 0 to %tmpElements%:>>%~n0.txt
FOR /L %%X IN (0, 1, %tmpElements%) DO ECHO !array[%%X]!>>%~n0.txt

ENDLOCAL
EXIT /B 0


function insertionSort (a) {
    for (var i = 0; i < a.length; i++) {
        var k = a[i];
        for (var j = i; j > 0 && k < a[j - 1]; j--)
            a[j] = a[j - 1];
        a[j] = k;
    }
    return a;
}

var a = [4, 65, 2, -31, 0, 99, 83, 782, 1];
insertionSort(a);
document.write(a.join(" "));


def insertion_sort:
  reduce .[] as $x ([]; insert($x));


Module Checkit1 {
      Group Quick {
      Private:
            Function partition {
                     Read &A(), p, r
                     x = A(r)
                     i = p-1
                     For j=p to r-1 {
                         If .LE(A(j), x) Then {
                                i++
                                Swap A(i),A(j)
                             }
                      }
                      Swap A(i+1),A(r)
                     = i+1
                  }
      Public:
            LE=Lambda->Number<=Number
            Function quicksort {
                 Read &A(), p, r
                 If p < r Then {
                   q = .partition(&A(), p, r)
                   Call .quicksort(&A(), p, q - 1)
                   Call .quicksort(&A(), q + 1, r)
                }
            }
      }
      Dim A(10)<<Random(50, 100)
      Print A()
      Call Quick.quicksort(&A(), 0, Len(A())-1)
      Print A()
}
Checkit1


DEF PROC_GnomeSort1(Size%)
I%=2
J%=2
REPEAT
  IF data%(J%-1) <=data%(J%) THEN
    I%+=1
    J%=I%
  ELSE
    SWAP data%(J%-1),data%(J%)
    J%-=1
    IF J%=1 THEN
       I%+=1
       J%=I%
    ENDIF
  ENDIF
UNTIL I%>Size%
ENDPROC


get "libhdr"

let gnomesort(A, len) be
$(  let i=1 and j=2 and t=?
    while i < len
        test A!(i-1) <= A!i
        $(  i := j
            j := j + 1
        $)
        or
        $(  t := A!(i-1)
            A!(i-1) := a!i
            A!i := t
            i := i - 1
            if i = 0
            $(  i := j
                j := j + 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')
    gnomesort(array, length)
    writes("Output: ") ; writearray(array, length) ; wrch('*N')
$)


void gnome_sort(int *a, int n)
{
  int i=1, j=2, t;
# define swap(i, j) { t = a[i]; a[i] = a[j]; a[j] = t; }
  while(i < n) {
    if (a[i - 1] > a[i]) {
      swap(i - 1, i);
      if (--i) continue;
    }
    i = j++;
  }
# undef swap
}


# v0.6

function insertionsort!(A::Array{T}) where T <: Number
    for i in 1:length(A)-1
        value = A[i+1]
        j = i
        while j > 0 && A[j] > value
            A[j+1] = A[j]
            j -= 1
        end
        A[j+1] = value
    end
    return A
end

x = randn(5)
@show x insertionsort!(x)


fun insertionSort(array: IntArray) {
    for (index in 1 until array.size) {
        val value = array[index]
        var subIndex = index - 1
        while (subIndex >= 0 && array[subIndex] > value) {
            array[subIndex + 1] = array[subIndex]
            subIndex--
        }
        array[subIndex + 1] = value
    }
}

fun main(args: Array<String>) {
    val numbers = intArrayOf(5, 2, 3, 17, 12, 1, 8, 3, 4, 9, 7)

    fun printArray(message: String, array: IntArray) = with(array) {
        print("$message [")
        forEachIndexed { index, number ->
            print(if (index == lastIndex) number else "$number, ")
        }
        println("]")
    }

    printArray("Unsorted:", numbers)
    insertionSort(numbers)
    printArray("Sorted:", numbers)
}


#!/bin/ksh

# An insertion sort in ksh

#	# Variables:
#
typeset -a arr=( 4 65 2 -31 0 99 2 83 782 1 )

#	# Functions:
#

#	# Function _insertionSort(array) - Insersion sort of array of integers
#
function _insertionSort {
	typeset _arr ; nameref _arr="$1"
	typeset _i _j _val ; integer _i _j _val

    for (( _i=1; _i<${#_arr[*]}; _i++ )); do
        _val=${_arr[_i]}
        (( _j = _i - 1 ))
        while (( _j>=0 && _arr[_j]>_val )); do
            _arr[_j+1]=${_arr[_j]}
            (( _j-- ))
        done
        _arr[_j+1]=${_val}
    done
}

 ######
# main #
 ######

_insertionSort arr

printf "%s" "( "
for (( i=0; i<${#arr[*]}; i++ )); do
	printf "%d " ${arr[i]}
done
printf "%s\n" " )"


dnl  return the first element of a list when called in the funny way seen below
define(`arg1', `$1')dnl
dnl
dnl  append lists 1 and 2
define(`append',
   `ifelse(`$1',`()',
      `$2',
      `ifelse(`$2',`()',
         `$1',
         `substr($1,0,decr(len($1))),substr($2,1)')')')dnl
dnl
dnl  separate list 2 based on pivot 1, appending to left 3 and right 4,
dnl  until 2 is empty, and then combine the sort of left with pivot with
dnl  sort of right
define(`sep',
   `ifelse(`$2', `()',
      `append(append(quicksort($3),($1)),quicksort($4))',
      `ifelse(eval(arg1$2<=$1),1,
         `sep($1,(shift$2),append($3,(arg1$2)),$4)',
         `sep($1,(shift$2),$3,append($4,(arg1$2)))')')')dnl
dnl
dnl  pick first element of list 1 as pivot and separate based on that
define(`quicksort',
   `ifelse(`$1', `()',
      `()',
      `sep(arg1$1,(shift$1),`()',`()')')')dnl
dnl
quicksort((3,1,4,1,5,9))


        public static void gnomeSort(int[] anArray)
        {
            int first = 1;
            int second = 2;

            while (first < anArray.Length)
            {
                if (anArray[first - 1] <= anArray[first])
                {
                    first = second;
                    second++;
                }
                else
                {
                    int tmp = anArray[first - 1];
                    anArray[first - 1] = anArray[first];
                    anArray[first] = tmp;
                    first -= 1;
                    if (first == 0)
                    {
                        first = 1;
                        second = 2;
                    }
                }

            }
        }


{def sort

 {def sort.i
  {lambda {:x :a}
   {if {A.empty? :a}
    then {A.new :x}
    else {if {<= :x {A.first :a}}
    then {A.addfirst! :x :a}
    else {A.addfirst! {A.first :a} {sort.i :x {A.rest :a}}} }}}}

 {def sort.r
  {lambda {:a1 :a2}
   {if {A.empty? :a1}
    then :a2
    else {sort.r {A.rest :a1} {sort.i {A.first :a1} :a2}} }}}

 {lambda {:a}
  {sort.r :a {A.new}} }}
-> sort

{def A {A.new 4 65 2 -31 0 99 83 782 1}}
-> A

{sort {A}}
-> [-31,0,1,2,4,65,83,99,782]


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

    print "Before Sort"
    gosub [printArray]

'--- Insertion sort algorithm
    for i = 2 to itemCount
        value = A(i)
        j = i-1
        while j >= 0 and A(j) > value
            A(j+1) = A(j)
            j = j-1
        wend
        A(j+1) = value
    next
'--- end of (Insertion sort algorithm)

    print "After Sort"
    gosub [printArray]
end

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


;; While not strictly required, it simplifies the
;; implementation considerably to use filter. MACLisp
;; Doesn't have one out of the box, so we bring our own
(DEFUN FILTER (F LIST)
        (COND
         ((EQ LIST NIL) NIL)
         ((FUNCALL F (CAR LIST))
          (CONS (CAR LIST) (FILTER F (CDR LIST))))
         (T
          (FILTER F (CDR LIST)))))

;; And then, quicksort.
(DEFUN QUICKSORT (LIST)
    (COND
     ((OR (EQ LIST ())
          (EQ (CDR LIST) ()))
      LIST)
     (T
      (LET
        ((PIVOT (CAR LIST))
         (REST (CDR LIST)))
        (APPEND
            (QUICKSORT (FILTER #'(LAMBDA (X) (<= X PIVOT)) REST))
            (LIST PIVOT)
            (QUICKSORT (FILTER #'(LAMBDA (X) (> X PIVOT)) REST)))))))


(defn gnomesort
  ([c] (gnomesort c <))
  ([c pred]
     (loop [x [] [y1 & ys :as y] (seq c)]
       (cond (empty? y) x
             (empty? x) (recur (list y1) ys)
             true (let [zx (last x)]
                    (if (pred y1 zx)
                      (recur (butlast x) (concat (list y1 zx) ys))
                      (recur (concat x (list y1)) ys)))))))

(println (gnomesort [3 1 4 1 5 9 2 6 5]))


       C-SORT SECTION.
       C-000.
           DISPLAY "SORT STARTING".

           SET WB-IX-1 TO 2.
           MOVE 1 TO WC-NEXT-POSN.

           PERFORM E-GNOME UNTIL WC-NEXT-POSN > WC-SIZE.

           DISPLAY "SORT FINISHED".

       C-999.
           EXIT.

       E-GNOME SECTION.
       E-000.
           IF WB-ENTRY(WB-IX-1 - 1) NOT > WB-ENTRY(WB-IX-1)
              ADD 1       TO WC-NEXT-POSN
              SET WB-IX-1 TO WC-NEXT-POSN
           ELSE
              MOVE WB-ENTRY(WB-IX-1 - 1) TO WC-TEMP
              MOVE WB-ENTRY(WB-IX-1)     TO WB-ENTRY(WB-IX-1 - 1)
              MOVE WC-TEMP               TO WB-ENTRY(WB-IX-1)
              SET WB-IX-1                DOWN BY 1
              IF WB-IX-1 = 1
                 ADD 1       TO WC-NEXT-POSN
                 SET WB-IX-1 TO WC-NEXT-POSN.

       E-999.
           EXIT.


do
	local function lower_bound(container, container_begin, container_end, value, comparator)
		local count = container_end - container_begin + 1

		while count > 0 do
			local half = bit.rshift(count, 1) -- or math.floor(count / 2)
			local middle = container_begin + half

			if comparator(container[middle], value) then
				container_begin = middle + 1
				count = count - half - 1
			else
				count = half
			end
		end

		return container_begin
	end

	local function binary_insertion_sort_impl(container, comparator)
		for i = 2, #container do
			local j = i - 1
			local selected = container[i]
			local loc = lower_bound(container, 1, j, selected, comparator)

			while j >= loc do
				container[j + 1] = container[j]
				j = j - 1
			end

			container[j + 1] = selected
		end
	end

	local function binary_insertion_sort_comparator(a, b)
		return a < b
	end

	function table.bininsertionsort(container, comparator)
		if not comparator then
			comparator = binary_insertion_sort_comparator
		end

		binary_insertion_sort_impl(container, comparator)
	end
end


swap := proc(arr, a, b)
	local temp := arr[a]:
	arr[a] := arr[b]:
	arr[b] := temp:
end proc:
quicksort := proc(arr, low, high)
	local pi:
	if (low < high) then
		pi := qpart(arr,low,high):
		quicksort(arr, low, pi-1):
		quicksort(arr, pi+1, high):
	end if:
end proc:
qpart := proc(arr, low, high)
	local i,j,pivot;
	pivot := arr[high]:
	i := low-1:
	for j from low to high-1 by 1 do
		if (arr[j] <= pivot) then
			i++:
			swap(arr, i, j):
		end if;
	end do;
	swap(arr, i+1, high):
	return (i+1):
end proc:
a:=Array([12,4,2,1,0]);
quicksort(a,1,5);
a;


(defun gnome-sort (array predicate &aux (length (length array)))
  (do ((position (min 1 length)))
      ((eql length position) array)
    (cond
     ((eql 0 position)
      (incf position))
     ((funcall predicate
               (aref array position)
               (aref array (1- position)))
      (rotatef (aref array position)
               (aref array (1- position)))
      (decf position))
     (t (incf position)))))


import std.stdio, std.algorithm;

void gnomeSort(T)(T arr) {
    int i = 1, j = 2;
    while (i < arr.length) {
        if (arr[i-1] <= arr[i]) {
            i = j;
            j++;
        } else {
            swap(arr[i-1], arr[i]);
            i--;
            if (i == 0) {
                i = j;
                j++;
            }
        }
    }
}

void main() {
    auto a = [3,4,2,5,1,6];
    gnomeSort(a);
    writeln(a);
}


arr := Array([17,3,72,0,36,2,3,8,40,0]):
len := numelems(arr):
for i from 2 to len do
	val := arr[i]:
	j := i-1:
	while(j > 0 and arr[j] > val) do
		arr[j+1] := arr[j]:
		j--:
	end do:
	arr[j+1] := val:
end do:
arr;


insertionSort[a_List] := Module[{A = a},
  For[i = 2, i <= Length[A], i++,
   value = A[[i]];    j = i - 1;
   While[j >= 1 && A[[j]] > value, A[[j + 1]] = A[[j]]; j--;];
   A[[j + 1]] = value;];
A
]


function list = insertionSort(list)

    for i = (2:numel(list))

        value = list(i);
        j = i - 1;

        while (j >= 1) && (list(j) > value)
            list(j+1) = list(j);
            j = j-1;
        end

        list(j+1) = value;

    end %for
end %insertionSort


QuickSort[x_List] := Module[{pivot},
  If[[email protected] <= 1, Return[x]];
  pivot = [email protected];
  [email protected]{QuickSort[Cases[x, j_ /; j < pivot]], Cases[x, j_ /; j == pivot], QuickSort[Cases[x, j_ /; j > pivot]]}
  ]


program TestGnomeSort;

{$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 GnomeSort(var A: TArray);
var
  Item: TItem;
  I, J: Integer;

begin
  I:= Low(A) + 1;
  J:= Low(A) + 2;
  while I <= High(A) do begin
    if A[I - 1] <= A[I] then begin
      I:= J;
      J:= J + 1;
    end
    else begin
      Item:= A[I - 1];
      A[I - 1]:= A[I];
      A[I]:= Item;
      I:= I - 1;
      if I = Low(A) then begin
        I:= J;
        J:= J + 1;
      end;
    end;
  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;
  GnomeSort(A);
  for I:= Low(A) to High(A) do
    Write(A[I]:3);
  Writeln;
  Readln;
end.


insertion_sort(u) := block(
   [n: length(u), x, j],
   for i from 2 thru n do (
      x: u[i],
      j: i - 1,
      while j >= 1 and u[j] > x do (
         u[j + 1]: u[j],
         j: j - 1
      ),
      u[j + 1]: x
   )
)$


fn inSort arr =
(
	arr = deepcopy arr
	for i = 1 to arr.count do
	(
		j = i
		while j > 1 and arr[j-1] > arr[j] do
		(
			swap arr[j] arr[j-1]
			j -= 1
		)
	)
	return arr
)


function sortedArray = quickSort(array)

    if numel(array) <= 1 %If the array has 1 element then it can't be sorted
        sortedArray = array;
        return
    end

    pivot = array(end);
    array(end) = [];

    %Create two new arrays which contain the elements that are less than or
    %equal to the pivot called "less" and greater than the pivot called
    %"greater"
    less = array( array <= pivot );
    greater = array( array > pivot );

    %The sorted array is the concatenation of the sorted "less" array, the
    %pivot and the sorted "greater" array in that order
    sortedArray = [quickSort(less) pivot quickSort(greater)];

end


procedure GnomeSort(a : array of Integer);
var
   i, j : Integer;
begin
   i := 1;
   j := 2;
   while i < a.Length do begin
      if a[i-1] <= a[i] then begin
         i := j;
         j := j + 1;
      end else begin
         a.Swap(i-1, i);
         i := i - 1;
         if i = 0 then begin
            i := j;
            j := j + 1;
         end;
      end;
   end;
end;

var i : Integer;
var a := new Integer[16];

Print('{');
for i := 0 to a.High do begin
   a[i] := i xor 5;
   Print(Format('%3d ', [a[i]]));
end;
PrintLn('}');

GnomeSort(a);

Print('{');
for i := 0 to a.High do
   Print(Format('%3d ', [a[i]]));
PrintLn('}');


fun insertion_sort L =
	let
		fun insert
				(x,[]) = [x]
			|	(x, y :: ys) =
					if x <= y then
						x :: y :: ys
					else
						y :: insert (x, ys)
	in
		foldr (insert,[]) L
	end;

println ` insertion_sort [6,8,5,9,3,2,1,4,7];


MODULE InsertSort;

PROCEDURE IntSort(VAR item: ARRAY OF INTEGER) =
  VAR j, value: INTEGER;
  BEGIN
    FOR i := FIRST(item) + 1 TO LAST(item) DO
      value := item[i];
      j := i - 1;
      WHILE j >= FIRST(item) AND item[j] > value DO
        item[j + 1] := item[j];
        DEC(j);
      END;
      item[j + 1] := value;
    END;
  END IntSort;
END InsertSort.


fn quickSort arr =
(
    less = #()
    pivotList = #()
    more = #()
    if arr.count <= 1 then
    (
        arr
    )
    else
    (
        pivot = arr[arr.count/2]
        for i in arr do
        (
            case of
            (
                (i < pivot):	(append less i)
                (i == pivot):	(append pivotList i)
                (i > pivot):	(append more i)
            )
        )
        less = quickSort less
        more = quickSort more
        less + pivotList + more
    )
)
a = #(4, 89, -3, 42, 5, 0, 2, 889)
a = quickSort a