sleep_sort(L) :-
	thread_pool_create(rosetta, 1024, []) ,
	maplist(initsort, L, LID),
	maplist(thread_join, LID, _LStatus),
	thread_pool_destroy(rosetta).

initsort(V, Id) :-
	thread_create_in_pool(rosetta, (sleep(V), writeln(V)), Id, []).


NewMap threads()

Procedure Foo(n)
  Delay(n)
  PrintN(Str(n))
EndProcedure

If OpenConsole()
  For i=1 To CountProgramParameters()
    threads(Str(i)) = CreateThread(@Foo(), Val(ProgramParameter()))
  Next

  ForEach threads()
    WaitThread(threads())
  Next
  Print("Press ENTER to exit"): Input()
EndIf


from time import sleep
from threading import Timer

def sleepsort(values):
    sleepsort.result = []
    def add1(x):
        sleepsort.result.append(x)
    mx = values[0]
    for v in values:
        if mx < v: mx = v
        Timer(v, add1, [v]).start()
    sleep(mx+1)
    return sleepsort.result

if __name__ == '__main__':
    x = [3,2,4,7,3,6,9,1]
    if sleepsort(x) == sorted(x):
        print('sleep sort worked for:',x)
    else:
        print('sleep sort FAILED for:',x)


bar: "▁▂▃▄▅▆▇█"
barcount: to :floating dec size bar

while ø [
    line: input "Numbers separated by spaces: "
    numbers: to [:floating] split.words line
    mn: min numbers
    mx: max numbers
    extent: mx-mn
    sparkLine: new ""
    loop numbers 'n [
        i: to :integer barcount*(n-mn)//extent
        'sparkLine ++ bar\[i]
    ]
    print ["min:" round.to:1 mn "max:" round.to:1 mx]
    print sparkLine
    print ""
]


SetFormat, FloatFast, 0.1
strings := ["1 2 3 4 5 6 7 8 7 6 5 4 3 2 1"
         ,  "1.5, 0.5 3.5, 2.5 5.5, 4.5 7.5, 6.5"]

Loop, % strings.MaxIndex()
{
    SL := Sparklines(strings[A_Index])
    MsgBox, % "Min: " SL["Min"] ", Max: " SL["Max"] ", Range: " SL["Rng"] "`n" SL["Chars"]
}

Sparklines(s)
{
    s := RegexReplace(s, "[^\d\.]+", ",")
    Loop, Parse, s, `,
    {
        Max := A_LoopField > Max ? A_LoopField : Max
        Min := !Min ? Max : A_LoopField < Min ? A_LoopField : Min
    }
    Rng := Max - Min
    Loop, Parse, s, `,
        Chars .= Chr(0x2581 + Round(7 * (A_LoopField - Min) / Rng))
    return, {"Min": Min, "Max": Max, "Rng": Rng, "Chars": Chars}
}


function stooge(sequence s, integer i, integer j)
    object temp
    integer t
    if compare(s[j], s[i]) < 0 then
        temp = s[i]
        s[i] = s[j]
        s[j] = temp
    end if
    if j - i > 1 then
        t = floor((j - i + 1)/3)
        s = stooge(s, i  , j-t)
        s = stooge(s, i+t, j  )
        s = stooge(s, i  , j-t)
    end if
    return s
end function

function stoogesort(sequence s)
    return stooge(s,1,length(s))
end function

constant s = rand(repeat(1000,10))

? s
? stoogesort(s)


USING: kernel locals math prettyprint sequences ;
IN: rosetta-code.stooge-sort

<PRIVATE

:: (stooge-sort) ( seq i j -- )
    j i [ seq nth ] [email protected] < [
        j i seq exchange
    ] when
    j i - 1 > [
        j i - 1 + 3 /i :> t
        seq i j t - (stooge-sort)
        seq i t + j (stooge-sort)
        seq i j t - (stooge-sort)
    ] when ;

PRIVATE>

: stooge-sort ( seq -- sortedseq )
    [ clone dup ] [ drop 0 ] [ length 1 - ] tri (stooge-sort) ;

: stooge-sort-demo ( -- )
    { 1 4 5 3 -6 3 7 10 -2 -5 } stooge-sort . ;

MAIN: stooge-sort-demo


program Stooge
  implicit none

  integer :: i
  integer :: array(50) = (/ (i, i = 50, 1, -1) /) ! Reverse sorted array

  call Stoogesort(array)
  write(*,"(10i5)") array

contains

recursive subroutine Stoogesort(a)
  integer, intent(in out) :: a(:)
  integer :: j, t, temp

   j = size(a)
   if(a(j) < a(1)) then
     temp = a(j)
     a(j) = a(1)
     a(1) = temp
   end if

  if(j > 2) then
    t = j / 3
    call Stoogesort(a(1:j-t))
    call Stoogesort(a(1+t:j))
    call Stoogesort(a(1:j-t))
  end if

end subroutine
end program


generic
   type Element_Type is digits <>;
   type Index_Type is (<>);
   type Array_Type is array(Index_Type range <>) of Element_Type;
package Shell_Sort is
   procedure Sort(Item : in out Array_Type);
end Shell_Sort;


# -*- coding: utf-8 -*- #

COMMENT
  REQUIRES(
    MODE SORTELEMENT = mode of element of array to be sorted...
    OP < = (SORTELEMENT a, b)BOOL: a < b;
  )
END COMMENT

MODE SORTELEMENTCMP = PROC(SORTELEMENT,SORTELEMENT)BOOL;

# create a global sort procedure for convenience #
PROC(SORTELEMENT,SORTELEMENT)BOOL sort cmp default := (SORTELEMENT a, b)BOOL: a < b;
PROC sort cmp rev = (SORTELEMENT a, b)BOOL: NOT sort cmp default(a,b);

# Alternative gap calculations: #
#     ⌊n/2**k⌋; ⌊n/2⌋; Θ(n**2) [when n=2**p]; Donald Shell 1959 #
PROC sort gap shell = (INT k, n)INT: n OVER 2;
#     2 ⌊n/2**(k+1)⌋+1; 2 ⌊n/4⌋+1, ..., 3, 1; Θ(n**(3/2)); Frank & Lazarus, 1960 #
#     2**k-1; 1, 3, 7, 15, 31, 63, ...; Θ(n**(3/2)); Hibbard, 1963 #
#     2**k+1, prefixed with 1; 1, 3, 5, 9, 17, 33, 65, ...; Θ(n**(3/2)); Papernov & Stasevich, 1965 #
#     successive numbers of the form 2**p 3**q; 1, 2, 3, 4, 6, 8, 9, 12, ...; Θ(n log**2 n); Pratt 1971 #
#     (3**k-1)/2, not greater than ⌈n/3⌉; 1, 4, 13, 40, 121, ...; Θ(n**(3/2)); Knuth 1973 #
#     ∏a[q], where r=⌊√(2k+√(2k))⌋ and a[q]=min(n∈𝒩:n≥(5/2)**(q+1) and ∀ p:0≤ p<q → gcd(a[p],n)=1);
      limit where 0≤q<r and q≠(r**2+r)/2-k
         1, 3, 7, 21, 48, 112, ...; O(n e**√(8ln(5/2)ln n)); Incerpi & Sedgewick, 1985 #
#     4**k+3×2**(k-1)+1, prefixed with 1; 1, 8, 23, 77, 281, ...; Θ(n**(4/3)); Sedgewick, 1986 #
#     9(4**(k-1)-2**(k-1))+1, 4**(k+1)-6×2**k+1; 1, 5, 19, 41, 109, ...; Θ(n**(4/3)); Sedgewick, 1986 #
#     h[k]=max(⌊5h[k-1]/11⌋, 1), h[0]=n; ⌊5N/11⌋, ⌊5/11 ⌊5N/11⌋⌋, ..., 1; Θ(?); Gonnet & Baeza-Yates, 1991 #
PROC sort gap gonnet and baeza yates = (INT k, n)INT: IF n=2 THEN 1 ELSE n*5 OVER 11 FI;
#     ⌈(9**k-4**k)/(5×4**(k-1))⌉; 1, 4, 9, 20, 46, 103, ...; Θ(?); Tokuda, 1992 #
#     unknown; 1, 4, 10, 23, 57, 132, 301, 701; Θ(?); Ciura, 2001 #

# set default gap calculation #
PROC (INT #k#, INT #n#)INT sort gap := sort gap gonnet and baeza yates;

PROC shell sort in place = (REF []SORTELEMENT array, UNION(VOID, SORTELEMENTCMP) opt cmp)REF[]SORTELEMENT:(
  SORTELEMENTCMP cmp := (opt cmp|(SORTELEMENTCMP cmp): cmp | sort cmp default);
  INT n := ( UPB array + LWB array + 1 ) OVER 2; # initial gap #
  FOR k WHILE n NE 0 DO
    FOR index FROM LWB array TO UPB array DO
      INT i := index;
      SORTELEMENT element = array[i];
      WHILE ( i - LWB array >= n | cmp(element, array[i-n]) | FALSE ) DO
        array[i] := array[i-n];
        i -:= n
      OD;
      array[i] := element
    OD;
    n := sort gap(k,n)
  OD;
  array
);

PROC shell sort = ([]SORTELEMENT seq)[]SORTELEMENT:
  shell sort in place(LOC[LWB seq: UPB seq]SORTELEMENT:=seq, EMPTY);

PROC shell sort rev = ([]SORTELEMENT seq)[]SORTELEMENT:
  shell sort in place(LOC[LWB seq: UPB seq]SORTELEMENT:=seq, sort cmp rev);

SKIP


#lang racket

;; accepts a list to sort
(define (sleep-sort lst)
  (define done (make-channel))
  (for ([elem lst])
    (thread
     (λ ()
       (sleep elem)
       (channel-put done elem))))
  (for/list ([_ (length lst)])
    (channel-get done)))

;; outputs '(2 5 5 7 8 9 10)
(sleep-sort '(5 8 2 7 9 10 5))


await map -> $delay { start { sleep $delay ; say $delay } },
    <6 8 1 12 2 14 5 2 1 0>;


/*REXX program implements a sleep sort (with numbers entered from the command line (CL).*/
numeric digits 300                               /*over the top,  but what the hey!     */
                                                 /*  (above)  ··· from vaudeville.      */
@.=                                              /*placeholder for the array of numbers.*/
stuff= 1e9 50 5 40 4 1 100 30 3 12 2 8 9 7 6 6 10 20 0      /*alphabetically ··· so far.*/
parse arg numbers                                /*obtain optional arguments from the CL*/
if numbers=''  then numbers= stuff               /*Not specified?  Then use the default.*/
N= words(numbers)                                /*N  is the number of numbers in list. */
w= length(N)                                     /*width of  N  (used for nice output). */
parse upper version !ver .                       /*obtain which REXX we're running under*/
!regina= ('REXX-REGINA'==left(!ver, 11) )        /*indicate (or not) if this is Regina. */
say N  'numbers to be sorted:'   numbers         /*informative informational information*/
                                                 /*from department of redundancy depart.*/
    do j=1  for N                                /*let's start to boogie─woogie da sort.*/
    @.j= word(numbers, j)                        /*plug in a single number at a time.   */
    if datatype(@.j, 'N')  then @.j= @.j / 1     /*normalize it if it's a numeric number*/
    if !regina  then call fork                   /*only REGINA REXX supports  FORK  BIF.*/
    call sortItem j                              /*start a sort for an array number.    */
    end   /*j*/

      do forever  while \inOrder(N)              /*wait for the sorts to complete.      */
      call delay 1                               /*one second is minimum effective time.*/
      end    /*forever while*/                   /*well heck,  other than zero seconds. */

m= max(length(@.1), length(@.N) )                /*width of smallest or largest number. */
say;                        say  'after sort:'   /*display a blank line and a title.    */

      do k=1  for N                              /*list the  (sorted)  array's elements.*/
      say left('', 20)     'array element'      right(k, w)      '───►'      right(@.k, m)
      end   /*k*/
exit                                             /*stick a fork in it,  we're all done. */
/*──────────────────────────────────────────────────────────────────────────────────────*/
sortItem: procedure expose @.;   parse arg ?     /*sorts a single  (numeric)  item.     */
              do Asort=1  until \switched        /*sort unsorted array until it's sorted*/
              switched= 0                        /*it's all hunky─dorey, happy─dappy ···*/
                                     do i=1   while   @.i\==''  &  \switched
                                     if @.? >= @.i then iterate     /*item is in order. */
                                     parse value   @.?  @.i     with     @.i  @.?
                                     switched= 1                    /* [↑]  swapped one.*/
                                     end   /*i*/
              if Asort//?==0  then call delay switched              /*sleep if last item*/
              end   /*Asort*/
          return               /*Sleeping Beauty awakes.  Not to worry:  (c)=circa 1697.*/
/*──────────────────────────────────────────────────────────────────────────────────────*/
inOrder: procedure expose @.;  parse arg howMany /*is the array in numerical order?     */
           do m=1  for howMany-1;  next= m+1;  if @.m>@.next  then return 0 /*¬ in order*/
           end   /*m*/                           /*keep looking for fountain of youth.  */
         return 1                                /*yes, indicate with an indicator.     */


#include<string.h>
#include<stdlib.h>
#include<locale.h>
#include<stdio.h>
#include<wchar.h>
#include<math.h>

int main(int argC,char* argV[])
{
	double* arr,min,max;
	char* str;
	int i,len;
	if(argC == 1)
		printf("Usage : %s <data points separated by spaces or commas>",argV[0]);
	else{
		arr = (double*)malloc((argC-1)*sizeof(double));
		for(i=1;i<argC;i++){
			len = strlen(argV[i]);

			if(argV[i][len-1]==','){
				str = (char*)malloc(len*sizeof(char));
				strncpy(str,argV[i],len-1);
				arr[i-1] = atof(str);
				free(str);
			}
			else
				arr[i-1] = atof(argV[i]);
			if(i==1){
				min = arr[i-1];
				max = arr[i-1];
			}
			else{
				min=(min<arr[i-1]?min:arr[i-1]);
				max=(max>arr[i-1]?max:arr[i-1]);
			}
		}

		printf("\n%Max : %lf,Min : %lf,Range : %lf\n",max,min,max-min);

		setlocale(LC_ALL, "");

		for(i=1;i<argC;i++){
			printf("%lc", (wint_t)(9601 + (int)ceil((arr[i-1]-min)/(max-min)*7)));
		}
	}
	return 0;
}


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

Sub stoogesort(s() As Long, l As Long, r As Long)

    If s(r) < s(l) Then
        Swap s(r), s(l)
    End If

    If r - l > 1 Then
        Var t = (r - l +1) \ 3
        stoogesort(s(), l    , r - t)
        stoogesort(s(), l + t, r    )
        stoogesort(s(), l    , r - t)
    End If
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

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


package main

import "fmt"

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

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

func stoogesort(a []int) {
    last := len(a) - 1
    if a[last] < a[0] {
        a[0], a[last] = a[last], a[0]
    }
    if last > 1 {
        t := len(a) / 3
        stoogesort(a[:len(a)-t])
        stoogesort(a[t:])
        stoogesort(a[:len(a)-t])
    }
}


-- In-place Shell sort.
-- Algorithm: Donald Shell, 1959.
on ShellSort(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 stepSize to (r - l + 1) div 2
    repeat while (stepSize > 0)
        repeat with i from (l + stepSize) to r
            set currentValue to o's lst's item i
            repeat with j from (i - stepSize) to l by -stepSize
                set thisValue to o's lst's item j
                if (thisValue > currentValue) then
                    set o's lst's item (j + stepSize) to thisValue
                else
                    set j to j + stepSize
                    exit repeat
                end if
            end repeat
            if (j < i) then set o's lst's item j to currentValue
        end repeat
        set stepSize to (stepSize / 2.2) as integer
    end repeat

    return -- nothing.
end ShellSort
property sort : ShellSort

-- Demo:
local aList
set aList to {56, 44, 72, 4, 93, 26, 61, 72, 52, 9, 87, 26, 73, 75, 94, 91, 30, 18, 63, 16}
sort(aList, 1, -1) -- Sort items 1 thru -1 of aList.
return aList


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

/************************************/
/* 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                                     @ not use in routine
    mov r2,#NBELEMENTS                            @ number of élements
    bl shellSort
    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
/***************************************************/
/*   shell Sort                                    */
/***************************************************/

/* r0 contains the address of table */
/* r1 contains the first element but not use !!   */
/*   this routine use first element at index zero !!!  */
/* r2 contains the number of element */
shellSort:
    push {r0-r7,lr}              @save registers

    sub r2,#1                    @ index last item
    mov r1,r2                    @ init gap = last item
1:                               @ start loop 1
    lsrs r1,#1                   @ gap = gap / 2
    beq 100f                     @ if gap = 0 -> end
    mov r3,r1                    @ init loop indice 1
2:                               @ start loop 2
    ldr r4,[r0,r3,lsl #2]        @ load first value
    mov r5,r3                    @ init loop indice 2
3:                               @ start loop 3
    cmp r5,r1                    @ indice < gap
    blt 4f                       @ yes -> end loop 2
    sub r6,r5,r1                 @ index = indice - gap
    ldr r7,[r0,r6,lsl #2]        @ load second value
    cmp r4,r7                    @ compare values
    strlt r7,[r0,r5,lsl #2]      @ store if <
    sublt r5,r1                  @ indice = indice - gap
    blt 3b                       @ and loop
4:                               @ end loop 3
    str r4,[r0,r5,lsl #2]        @ store value 1 at indice 2
    add r3,#1                    @ increment indice 1
    cmp r3,r2                    @ end ?
    ble 2b                       @ no -> loop 2
    b 1b                         @ yes loop for new gap

100:                             @ end function
    pop {r0-r7,lr}               @ restaur registers
    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


require 'thread'

nums = ARGV.collect(&:to_i)
sorted = []
mutex = Mutex.new

threads = nums.collect do |n|
  Thread.new do
    sleep 0.01 * n
    mutex.synchronize {sorted << n}
  end
end
threads.each {|t| t.join}

p sorted


use std::thread;

fn sleepsort<I: Iterator<Item=u32>>(nums: I) {
    let threads: Vec<_> = nums.map(|n|
        thread::spawn(move || {
            thread::sleep_ms(n);
            println!("{}", n); })).collect();
    for t in threads { t.join(); }
}

fn main() {
    sleepsort(std::env::args().skip(1).map(|s| s.parse().unwrap()));
}


object SleepSort {

  def main(args: Array[String]): Unit = {
    val nums = args.map(_.toInt)
    sort(nums)
    Thread.sleep(nums.max * 21) // Keep the JVM alive for the example
  }

  def sort(nums: Seq[Int]): Unit =
    nums.foreach(i => new Thread {
      override def run() {
        Thread.sleep(i * 20) // just `i` is unpredictable with small numbers
        print(s"$i ")
      }
    }.start())

}


ARGV.map{.to_i}.map{ |i|
    {Sys.sleep(i); say i}.fork;
}.each{.wait};


#include <iostream>
#include <sstream>
#include <vector>
#include <cmath>
#include <algorithm>
#include <locale>

class Sparkline {
    public:
        Sparkline(std::wstring &cs) : charset( cs ){
        }
        virtual ~Sparkline(){
        }

        void print(std::string spark){
            const char *delim = ", ";
            std::vector<float> data;
            // Get first non-delimiter
            std::string::size_type last = spark.find_first_not_of(delim, 0);
            // Get end of token
            std::string::size_type pos = spark.find_first_of(delim, last);

            while( pos != std::string::npos || last != std::string::npos ){
                std::string tok = spark.substr(last, pos-last);
                // Convert to float:
                std::stringstream ss(tok);
                float entry;
                ss >> entry;

                data.push_back( entry );

                last = spark.find_first_not_of(delim, pos);
                pos = spark.find_first_of(delim, last);
            }

            // Get range of dataset
            float min = *std::min_element( data.begin(), data.end() );
            float max = *std::max_element( data.begin(), data.end() );

            float skip = (charset.length()-1) / (max - min);

            std::wcout<<L"Min: "<<min<<L"; Max: "<<max<<L"; Range: "<<(max-min)<<std::endl;

            std::vector<float>::const_iterator it;
            for(it = data.begin(); it != data.end(); it++){
                float v = ( (*it) - min ) * skip;
                std::wcout<<charset[ (int)floor( v ) ];
            }
            std::wcout<<std::endl;

        }
    private:
        std::wstring &charset;
};

int main( int argc, char **argv ){
    std::wstring charset = L"\u2581\u2582\u2583\u2584\u2585\u2586\u2587\u2588";

    // Mainly just set up utf-8, so wcout won't narrow our characters.
    std::locale::global(std::locale("en_US.utf8"));

    Sparkline sl(charset);

    sl.print("1 2 3 4 5 6 7 8 7 6 5 4 3 2 1");
    sl.print("1.5, 0.5 3.5, 2.5 5.5, 4.5 7.5, 6.5");

    return 0;
}


import Data.List
import Control.Arrow
import Control.Monad

insertAt e k = uncurry(++).second ((e:).drop 1). splitAt k

swapElems :: [a] -> Int -> Int -> [a]
swapElems xs i j = insertAt (xs!!j) i $ insertAt (xs!!i) j xs

stoogeSort [] = []
stoogeSort [x] = [x]
stoogeSort xs = doss 0 (length xs - 1) xs
doss :: (Ord a) => Int -> Int -> [a] -> [a]
doss i j xs
      | j-i>1 = doss i (j-t) $ doss (i+t) j $ doss i (j-t) xs'
      | otherwise = xs'
    where t = (j-i+1)`div`3
	  xs'
	    | xs!!j < xs!!i = swapElems xs i j
	    | otherwise = xs


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

procedure stoogesort(X,op,i,j)           #: return sorted list ascending(or descending)
local t

   if /i := 0 then {
      j := *X
      op := sortop(op,X)                 # select how and what we sort
      }

   if op(X[j],X[i]) then
      X[i] :=: X[j]
   if j - i > 1 then {
      t := (j - i + 1) / 3
      X := stoogesort(X,op,i,j-t)
      X := stoogesort(X,op,i+t,j)
      X := stoogesort(X,op,i,j-t)
      }
   return X                              # X must be returned and assigned to sort a string
end


shellSort: function [items][
    a: new items
    h: size a

    while [h > 0][
        h: h / 2
        loop h..dec size a 'i [
            k: a\[i]
            j: i

            while [and? [j >= h] [k < a\[j-h]]][
                a\[j]: a\[j-h]
                j: j - h
            ]
            a\[j]: k
        ]
    ]
    return a
]

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


MsgBox % ShellSort("")
MsgBox % ShellSort("xxx")
MsgBox % ShellSort("3,2,1")
MsgBox % ShellSort("dog,000000,xx,cat,pile,abcde,1,cat,zz,xx,z")
MsgBox % ShellSort("12,11,10,9,8,4,5,6,7,3,2,1,10,13,14,15,19,17,18,16,20,10")

ShellSort(var) {                         ; SORT COMMA SEPARATED LIST
   StringSplit a, var, `,                ; make array (length = a0)
   inc := a0
   While inc:=round(inc/2.2)             ; geometric gap sequence
      Loop % a0-inc {                    ; insertion sort:
         i := A_Index+inc, t := a%i%, j := i, k := j-inc
         While j > inc && a%k% > t
            a%j% := a%k%, j := k, k -= inc
         a%j% := t
      }
   Loop % a0                             ; construct string from sorted array
      s .= "," . a%A_Index%
   Return SubStr(s,2)                    ; drop leading comma
}


SIMULATION
BEGIN

    PROCESS CLASS SORTITEM(N); INTEGER N;
    BEGIN
        HOLD(N);
        OUTINT(N, 3);
    END;

    INTEGER I;
    FOR I := 3, 2, 4, 7, 3, 6, 9, 1 DO
    BEGIN
        REF(SORTITEM) SI;
        SI :- NEW SORTITEM(I);
        ACTIVATE SI;
    END;
    HOLD(100000);
    OUTIMAGE;

END;


      /$>\  input until eof
  #/?<\?,/  foreach: fork
   \ &/:+   copy and\
    /:\?-;    delay /
    \.#     print and exit thread


import Foundation

for i in [5, 2, 4, 6, 1, 7, 20, 14] {
    let time = dispatch_time(DISPATCH_TIME_NOW,
        Int64(i * Int(NSEC_PER_SEC)))

    dispatch_after(time, dispatch_get_main_queue()) {
        print(i)
    }
}

CFRunLoopRun()


#!/bin/env tclsh
set count 0
proc process val {
    puts $val
    incr ::count
}
# Schedule the output of the values
foreach val $argv {
    after [expr {$val * 10}] [list process $val]
}
# Run event loop until all values output...
while {$count < $argc} {
    vwait count
}


f() {
    sleep "$1"
    echo "$1"
}
while [ -n "$1" ]
do
    f "$1" &
    shift
done
wait


(defn sparkline [nums]
  (let [sparks   "▁▂▃▄▅▆▇█"
        high     (apply max nums)
        low      (apply min nums)
        spread   (- high low)
        quantize #(Math/round (* 7.0 (/ (- % low) spread)))]
        (apply str (map #(nth sparks (quantize %)) nums))))

(defn spark [line]
  (if line
    (let [nums (read-string (str "[" line "]"))]
      (println (sparkline nums))
      (recur (read-line)))))

(spark (read-line))


(defun buckets (numbers)
  (loop with min = (apply #'min numbers)
        with max = (apply #'max numbers)
        with width = (/ (- max min) 7)
        for base from (- min (/ width 2)) by width
        repeat 8
        collect (cons base (+ base width))))

(defun bucket-for-number (number buckets)
  (loop for i from 0
        for (min . max) in buckets
        when (and (<= min number) (< number max))
          return i))

(defun sparkline (numbers)
  (loop with buckets = (buckets numbers)
        with sparks = "▁▂▃▄▅▆▇█"
        with sparkline = (make-array (length numbers) :element-type 'character)
        with min = (apply #'min numbers)
        with max = (apply #'max numbers)
        for number in numbers
        for i from 0
        for bucket = (bucket-for-number number buckets)
        do (setf (aref sparkline i) (char sparks bucket))
        finally (format t "Min: ~A, Max: ~A, Range: ~A~%" min max (- max min))
                (write-line sparkline)))

(defun string->numbers (string)
  (flet ((delimiterp (c)
           (or (char= c #\Space) (char= c #\,))))
    (loop for prev-end = 0 then end
          while prev-end
          for start = (position-if-not #'delimiterp string :start prev-end)
          for end = (position-if #'delimiterp string :start start)
          for number = (read-from-string string t nil :start start :end end)
          do (assert (numberp number))
          collect number)))

(defun string->sparkline (string)
  (sparkline (string->numbers string)))

(string->sparkline "1 2 3 4 5 6 7 8 7 6 5 4 3 2 1")
(string->sparkline "1.5, 0.5 3.5, 2.5 5.5, 4.5 7.5, 6.5")


100 PROGRAM "StoogSrt.bas"
110 RANDOMIZE
120 NUMERIC ARRAY(5 TO 16)
130 CALL INIT(ARRAY)
140 CALL WRITE(ARRAY)
150 CALL STOOGESORT(ARRAY,LBOUND(ARRAY),UBOUND(ARRAY))
160 CALL WRITE(ARRAY)
170 DEF INIT(REF A)
180   FOR I=LBOUND(A) TO UBOUND(A)
190     LET A(I)=RND(99)+1
200   NEXT
210 END DEF
220 DEF WRITE(REF A)
230   FOR I=LBOUND(A) TO UBOUND(A)
240     PRINT A(I);
250   NEXT
260   PRINT
270 END DEF
280 DEF STOOGESORT(REF A,I,J)
290   NUMERIC T
300   IF A(J)<A(I) THEN LET T=A(J):LET A(J)=A(I):LET A(I)=T
310   IF J-I>1 THEN
320     LET T=IP((J-I+1)/3)
330     CALL STOOGESORT(A,I,J-T)
340     CALL STOOGESORT(A,I+T,J)
350     CALL STOOGESORT(A,I,J-T)
360   END IF
370 END DEF


swapElems=: |[email protected]:{`[`]}

stoogeSort=: 3 : 0
  (0,<:#y) stoogeSort y
:
  if. >/x{y do. y=.x swapElems y end.
  if. 1<-~/x do.
    t=. <.3%~1+-~/x
    (x-0,t) stoogeSort (x+t,0) stoogeSort (x-0,t) stoogeSort y
  else. y end.
)


import java.util.Arrays;

public class Stooge {
    public static void main(String[] args) {
        int[] nums = {1, 4, 5, 3, -6, 3, 7, 10, -2, -5};
        stoogeSort(nums);
        System.out.println(Arrays.toString(nums));
    }

    public static void stoogeSort(int[] L) {
        stoogeSort(L, 0, L.length - 1);
    }

    public static void stoogeSort(int[] L, int i, int j) {
        if (L[j] < L[i]) {
            int tmp = L[i];
            L[i] = L[j];
            L[j] = tmp;
        }
        if (j - i > 1) {
            int t = (j - i + 1) / 3;
            stoogeSort(L, i, j - t);
            stoogeSort(L, i + t, j);
            stoogeSort(L, i, j - t);
        }
    }
}


{
  line[NR] = $0
}
END { # sort it with shell sort
  increment = int(NR / 2)
  while ( increment > 0 ) {
    for(i=increment+1; i <= NR; i++) {
      j = i
      temp = line[i]
      while ( (j >= increment+1) && (line[j-increment] > temp) ) {
	line[j] = line[j-increment]
	j -= increment
      }
      line[j] = temp
    }
    if ( increment == 2 )
      increment = 1
    else
      increment = int(increment*5/11)
  }
  #print it
  for(i=1; i <= NR; i++) {
    print line[i]
  }
}


      DIM test(9)
      test() = 4, 65, 2, -31, 0, 99, 2, 83, 782, 1
      PROCshellsort(test(), 10)
      FOR i% = 0 TO 9
        PRINT test(i%) ;
      NEXT
      PRINT
      END

      DEF PROCshellsort(a(), n%)
      LOCAL h%, i%, j%, k
      h% = n%
      WHILE h%
        IF h% = 2 h% = 1 ELSE h% DIV= 2.2
        FOR i% = h% TO n% - 1
          k = a(i%)
          j% = i%
          WHILE j% >= h% AND k < a(ABS(j% - h%))
            a(j%) = a(j% - h%)
            j% -= h%
          ENDWHILE
          a(j%) = k
        NEXT
      ENDWHILE
      ENDPROC


import "timer" for Timer
import "io" for Stdout
import "os" for Process

var args = Process.arguments
var n = args.count
if (n < 2) Fiber.abort("There must be at least two arguments passed.")
var list = args.map{ |a| Num.fromString(a) }.toList
if (list.any { |i| i == null || !i.isInteger || i < 0 } ) {
    Fiber.abort("All arguments must be non-negative integers.")
}
var max = list.reduce { |acc, i| acc = (i > acc) ? i : acc }
var fibers = List.filled(max+1, null)
System.print("Before: %(list.join(" "))")
for (i in list) {
    var sleepSort = Fiber.new { |i|
        Timer.sleep(1000)
        Fiber.yield(i)
    }
    fibers[i] = sleepSort
}
System.write("After : ")
for (i in 0..max) {
    var fib = fibers[i]
    if (fib) {
        System.write("%(fib.call(i)) ")
        Stdout.flush()
    }
}
System.print()


void main() {
    import std.stdio, std.range, std.algorithm, std.conv,
           std.string, std.regex;

    "Numbers please separated by space/commas: ".write;
    immutable numbers = readln
                        .strip
                        .splitter(r"[\s,]+".regex)
                        .array /**/
                        .to!(real[]);
    immutable mm = numbers.reduce!(min, max);
    writefln("min: %4f, max: %4f", mm[]);
    immutable bars = iota(9601, 9609).map!(i => i.to!dchar).dtext;
    immutable div = (mm[1] - mm[0]) / (bars.length - 1);
    numbers.map!(n => bars[cast(int)((n - mm[0]) / div)]).writeln;
}


program Sparkline_in_unicode;

{$APPTYPE CONSOLE}

//Translated from: https://www.arduino.cc/reference/en/language/functions/math/map/
function map(x, in_min, in_max, out_min, out_max: Double): Double;
begin
  Result := ((x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min);
end;

procedure Normalize(var Values: TArray<Double>; outMin, outMax: Double);
var
  i: Integer;
  inMax, inMin, value: Double;
begin
  if Length(Values) = 0 then
    Exit;

  inMin := Values[0];
  inMax := Values[0];

  for value in Values do
  begin
    if value > inMax then
      inMax := value;
    if value < inMin then
      inMin := value;
  end;

  for i := 0 to High(Values) do
    Values[i] := map(Values[i], inMin, inMax, outMin, outMax);
end;

function Sparkline(Values: TArray<Double>): UnicodeString;
var
  value: Double;
const
  CHARS: UnicodeString = #$2581#$2582#$2583#$2584#$2585#$2586#$2587#$2588;
begin
  Result := '';
  Normalize(Values, 1, 8);
  for value in Values do
    Result := Result + CHARS[Trunc(value)];
end;

begin
  writeln(Sparkline([1, 2, 3, 4, 5, 6, 7, 8, 7, 6, 5, 4, 3, 2, 1]));
  writeln(Sparkline([1.5, 0.5, 3.5, 2.5, 5.5, 4.5, 7.5, 6.5]));
  Readln;
end.


function stoogeSort (array, i, j) {
    if (j === undefined) {
        j = array.length - 1;
    }

    if (i === undefined) {
        i = 0;
    }

    if (array[j] < array[i]) {
        var aux = array[i];
        array[i] = array[j];
        array[j] = aux;
    }

    if (j - i > 1) {
        var t = Math.floor((j - i + 1) / 3);
        stoogeSort(array, i, j-t);
        stoogeSort(array, i+t, j);
        stoogeSort(array, i, j-t);
    }
};


def stoogesort:
  def swap(i;j): .[i] as $t | .[i] = .[j] | .[j] = $t;

  # for efficiency, define an auxiliary function
  # that takes as input [L, i, j]
  def ss: .[1] as $i | .[2] as $j
     | .[0]
     | if .[$j] < .[$i] then swap($i;$j) else . end
     | if $j - $i > 1 then
          (($j - $i + 1) / 3 | floor) as $t
          | [., $i, $j-$t] | ss
	  | [., $i+$t, $j] | ss
	  | [., $i, $j-$t] | ss
       else .
       end;

  [., 0, length-1] | ss;


function stoogesort!(a::Array, i::Int=1, j::Int=length(a))
    if a[j] < a[i]
        a[[i, j]] = a[[j, i]];
    end

    if (j - i) > 1
        t = round(Int, (j - i + 1) / 3)
        a = stoogesort!(a, i,     j - t)
        a = stoogesort!(a, i + t, j)
        a = stoogesort!(a, i,     j - t)
    end

    return a
end

x = randn(10)
@show x stoogesort!(x)


GET "libhdr"

LET shellsort(v, upb) BE
{ LET m = 1
  UNTIL m>upb DO m := m*3 + 1  // Find first suitable value in the
                                // series:  1, 4, 13, 40, 121, 364, ...
  { m := m/3
    FOR i = m+1 TO upb DO
    { LET vi = v!i
      LET j = i
      { LET k = j - m
        IF k<=0 | v!k < vi BREAK
        v!j := v!k
        j := k
      } REPEAT
      v!j := vi
    }
 } REPEATUNTIL m=1
}

MANIFEST { upb = 10000  }

LET start() = VALOF
{ LET v = getvec(upb)

  try("shell", shellsort, v, upb)

  writes("*nEnd of test*n")
  freevec(v)
  RESULTIS 0
}

AND try(name, sortroutine, v, upb) BE
{ // delay, referencing the first and last elements of v
   FOR i = 1 TO 50000 DO v!upb := v!1
   writef("*nSetting %n words of data for %s sort*n", upb, name)
   FOR i = 1 TO upb DO v!i := randno(10000)
   writef("Entering %s sort routine*n", name)
   sortroutine(v, upb)
   writes("Sorting complete*n")
   TEST sorted(v, upb)
   THEN writes("The data is now sorted*n")
   ELSE writef("### ERROR: %s sort does not work*n", name)
}

AND sorted(v, n) = VALOF
{ //FOR i = 1 TO n-1 UNLESS v!i<=v!(i+1) RESULTIS FALSE
   RESULTIS TRUE
}


vm.arglist.apply(fcn(n){ Atomic.sleep(n); print(n) }.launch);
Atomic.waitFor(fcn{ vm.numThreads == 1 }); Atomic.sleep(2); println();


defmodule RC do
  def sparkline(str) do
    values = str |> String.split(~r/(,| )+/)
                 |> Enum.map(&elem(Float.parse(&1), 0))
    {min, max} = Enum.min_max(values)
    IO.puts Enum.map(values, &(round((&1 - min) / (max - min) * 7 + 0x2581)))
  end
end


open System
open System.Globalization
open System.Text.RegularExpressions

let bars = Array.map Char.ToString ("▁▂▃▄▅▆▇█".ToCharArray())

while true do
    printf "Numbers separated by anything: "
    let numbers =
        [for x in Regex.Matches(Console.ReadLine(), @"-?\d+(?:\.\d*)?") do yield x.Value]
        |> List.map (fun x -> Double.Parse(x, CultureInfo.InvariantCulture))
    if numbers.Length = 0 then System.Environment.Exit(0)
    if numbers.Length = 1 then
        printfn "A sparkline for 1 value is not very useful... ignoring entry"
    else
        let min, max = List.min numbers, List.max numbers
        printfn "min: %5f; max: %5f" min max
        let barsCount = float (bars.GetUpperBound(0))
        numbers
        |> List.map (fun x -> bars.[int ((x - min)/(max - min) * barsCount)])
        |> String.Concat
        |> printfn "%s"


USING: formatting kernel math math.order math.parser
math.statistics sequences splitting ;

: sparkline-index ( v min max -- i )
    [ drop - 8 * ] [ swap - /i ] 2bi 0 7 clamp 9601 + ;

: (sparkline) ( seq -- new-seq )
    dup minmax [ sparkline-index ] 2curry "" map-as ;

: sparkline ( str -- new-str )
    ", " split harvest [ string>number ] map (sparkline) ;

{
    "1 2 3 4 5 6 7 8 7 6 5 4 3 2 1"
    "1.5, 0.5 3.5, 2.5 5.5, 4.5 7.5, 6.5"
    "0, 1, 19, 20"
    "0, 999, 4000, 4999, 7000, 7999"
} [ dup sparkline "%u -> %s\n" printf ] each


// version 1.1.0

fun stoogeSort(a: IntArray, i: Int, j: Int) {
    if (a[j] < a[i]) {
        val temp = a[j]
        a[j] = a[i]
        a[i] = temp
    }
    if (j - i > 1) {
        val t = (j - i + 1) / 3
        stoogeSort(a, i, j - t)
        stoogeSort(a, i + t, j)
        stoogeSort(a, i, j - t)
    }
}

fun main(args: Array<String>) {
    val a = intArrayOf(100, 2, 56, 200, -52, 3, 99, 33, 177, -199)
    println("Original : ${a.asList()}")
    stoogeSort(a, 0, a.size - 1)
    println("Sorted   : ${a.asList()}")
}


local Y = function (f)
  return (function(x) return x(x) end)(function(x) return f(function(...) return x(x)(...) end) end)
end

function stoogesort(L, pred)

  pred = pred or function(a,b) return a < b end

  Y(function(recurse)
    return function(i,j)
      if pred(L[j], L[i]) then
        L[j],L[i] = L[i],L[j]
      end
      if j - i > 1 then
        local t = math.floor((j - i + 1)/3)
        recurse(i,j-t)
        recurse(i+t,j)
        recurse(i,j-t)
      end
    end
  end)(1,#L)

  return L
end

print(unpack(stoogesort{9,7,8,5,6,3,4,2,1,0}))


public static class ShellSorter
{
    public static void Sort<T>(IList<T> list) where T : IComparable
    {
        int n = list.Count;
        int h = 1;

        while (h < (n >> 1))
        {
            h = (h << 1) + 1;
        }

        while (h >= 1)
        {
            for (int i = h; i < n; i++)
            {
                int k = i - h;
                for (int j = i; j >= h && list[j].CompareTo(list[k]) < 0; k -= h)
                {
                    T temp = list[j];
                    list[j] = list[k];
                    list[k] = temp;
                    j = k;
                }
            }
            h >>= 1;
        }
    }
}


{
  variables:
  s: sign (1 or -1)
  u: current number
  f: current number fraction length
  v: current number is valid
  t: number of numbers read
  x: biggest fraction
  y: smallest number (without fraction)
  z: biggest number (without fraction)
}

{function a: test if top is 0-9, without popping the value, codes 48-57 are in range}
[$$47>\57>~&]a:

{function b: test if top is ',' or ' ', without popping the value}
[$$',=\' =|]b:

{function c: read a number from the input, given that the first character of the input is already on the stack}
[
  1s:0u:0f:0v: {reset values}

  $'-=[1_s:%^]? {if (it is negative) set the sign value to -1 move to next}
  [a;!][48-u;10*+u:1_v:^]# {while (isnumber) do number = number * 10 + decimal and set valid number and move to next}
  $'.=[ {if (it is a decimal) move forward and read fraction}
    %^
    [a;!][48-u;10*+u:f;1+f:1_v:^]# {while (isnumber) do number = number * 10 + decimal and increase fraction length and set valid number and move to next}
  ]?
  $$'-=\'.=|[0v:]? {if next charachter is a '-' or a '.', set invalid}
]c:

{function d: normalize number/fraction from stack to max fraction and push that number}
[
  [$x;=~][1+\10*\]# {while (fraction != max) fraction + 1, value * 10}
  % {pop fraction}
]d:

0t:
0x:
1_v: { nothing read, so we are still valid }
^[b;!][%^]# {read away any initial separators}
[$1_=~v;&][ {while input != -1 and valid input, leaving input on the stack}
  c;! {read a number}
  t;1+t:u;s;*f;@ {increase count, push number * sign and fraction length onto the stack and bring input back up}
  f;x;>[f;x:]? {set fraction to biggest of current and previous biggest}
  [b;!][%^]# {while (isseparator) move forward}
]#
v;~["error at charachter ",]? {if invalid number, tell them when}
v;[ {if last number also valid, do the math}
  %        {pop the -1}
  t;2*1-q: {var q: points to next value}
  0p:      {var p: whether min/max have been set}
  [q;1+t;>][ {while q + 1 > t}
    q;ø        {current number}
    q;ø        {current fraction}
    d;!        {normalize}
    p;[$y;\>[$y:]? $z;>[$z:]?]?      {compare min/max}
    p;~[1_p:$y:$z:]?     {if (first)) set min/max}
    q;1-q:     {move pointer}
  ]#

  t;q: {point q to first value}
  [q;0>][ {while q > 0}
    q;1-øy;-7*z;y;-/ {(number - minvalue) * 7 / (maxvalue - minvalue), should result in 0..7}
    9601+,           {print character}
    q;1-q:           {move pointer}
  ]#
]?


package main

import (
    "bufio"
    "errors"
    "fmt"
    "math"
    "os"
    "regexp"
    "strconv"
    "strings"
)

func main() {
    fmt.Println("Numbers please separated by space/commas:")
    sc := bufio.NewScanner(os.Stdin)
    sc.Scan()
    s, n, min, max, err := spark(sc.Text())
    if err != nil {
        fmt.Println(err)
        return
    }
    if n == 1 {
        fmt.Println("1 value =", min)
    } else {
        fmt.Println(n, "values.  Min:", min, "Max:", max)
    }
    fmt.Println(s)
}

var sep = regexp.MustCompile(`[\s,]+`)

func spark(s0 string) (sp string, n int, min, max float64, err error) {
    ss := sep.Split(s0, -1)
    n = len(ss)
    vs := make([]float64, n)
    var v float64
    min = math.Inf(1)
    max = math.Inf(-1)
    for i, s := range ss {
        switch v, err = strconv.ParseFloat(s, 64); {
        case err != nil:
        case math.IsNaN(v):
            err = errors.New("NaN not supported.")
        case math.IsInf(v, 0):
            err = errors.New("Inf not supported.")
        default:
            if v < min {
                min = v
            }
            if v > max {
                max = v
            }
            vs[i] = v
            continue
        }
        return
    }
    if min == max {
        sp = strings.Repeat("▄", n)
    } else {
        rs := make([]rune, n)
        f := 8 / (max - min)
        for j, v := range vs {
            i := rune(f * (v - min))
            if i > 7 {
                i = 7
            }
            rs[j] = '▁' + i
        }
        sp = string(rs)
    }
    return
}


swap := proc(arr, a, b)
	local temp := arr[a];
	arr[a] := arr[b];
	arr[b] := temp;
end proc:

stoogesort:= proc(arr, start_index, end_index)
	local cur;
	if (arr[end_index] < arr[start_index]) then
		swap(arr, start_index, end_index);
	end if;

	if  end_index - start_index > 1 then
		cur := trunc((end_index - start_index + 1)/3);
		stoogesort(arr, start_index, end_index - cur);
		stoogesort(arr, start_index + cur, end_index);
		stoogesort(arr, start_index, end_index - cur);
	end if;

	return arr;
end proc:

arr := Array([4, 2, 6, 1, 3, 7, 9, 5, 8]):
stoogesort(arr, 1, numelems(arr));


stoogeSort[lst_, I_, J_] := Module[{i = I, j = J, list = lst},
 If[list[[j]] < list[[i]], list[[{i,j}]] = list[[{j,i}]];]
 If[(j-i) > 1, t = Round[(j-i+1)/3];
  list=stoogeSort[list,i,j-t];
  list=stoogeSort[list,i+t,j];
  list=stoogeSort[list,i,j-t];];
 list
]


%Required inputs:
%i = 1
%j = length(list)
%
function list = stoogeSort(list,i,j)

    if list(j) < list(i)
        list([i j]) = list([j i]);
    end

    if (j - i) > 1
        t = round((j-i+1)/3);
        list = stoogeSort(list,i,j-t);
        list = stoogeSort(list,i+t,j);
        list = stoogeSort(list,i,j-t);
    end

end


fn stoogeSort arr i: j: =
(
	if i == unsupplied do i = 1
	if j == unsupplied do j = arr.count

	if arr[j] < arr[i] do
	(
		swap arr[j] arr[i]
	)
	if j - i > 1 do
	(
		local  t = (j - i+1)/3
		arr = stoogeSort arr i:i j:(j-t)
		arr = stoogeSort arr i:(i+t) j:j
		arr = stoogeSort arr i:i j:(j-t)
	)
	return arr
)


      *******************************************************
       IDENTIFICATION DIVISION.
      *******************************************************
       PROGRAM-ID.      SHELLSRT.
      ************************************************************
      *** SHELLSORT                                           ****
      ************************************************************
       ENVIRONMENT DIVISION.
       DATA DIVISION.
       WORKING-STORAGE SECTION.
       01 II                        PIC S9(008) COMP-5.
       01 IJ                        PIC S9(008) COMP-5.
       01 IZ                        PIC S9(008) COMP-5.
       01 IA                        PIC S9(008) COMP-5.
       01 STRT1                     PIC S9(008) COMP-5.
       01 STRT2                     PIC S9(008) COMP-5.
       01 LGT                       PIC S9(008) COMP-5.
       01 ORG                       PIC S9(008) COMP-5.
       01 DST                       PIC S9(008) COMP-5.
      *
       01 GAP                       PIC S9(008) COMP-5.
       01 NEGAP                     PIC S9(008) COMP-5.
       01 TEMP                      PIC X(32768).
       77 KEY-RESULT                PIC X.
      *
       LINKAGE SECTION.
       01 SRT-ARRAY                 PIC  X(1000000).
       01 NUM-ITEM                  PIC  9(008) COMP-5.
       01 SRT-DATA.
          03 LGT-ITEM               PIC  9(004) COMP-5.
          03 SRT-KEYS.
             05 SRT-KEY OCCURS 10.
                07 K-START         PIC S9(004) COMP-5.
                07 K-LENGTH        PIC S9(004) COMP-5.
                07 K-ASC           PIC X.
      *
      *    P R O C E D U R E      D I V I S I O N
      *
       PROCEDURE DIVISION USING SRT-ARRAY NUM-ITEM SRT-DATA.

           COMPUTE GAP = NUM-ITEM / 2.
           PERFORM UNTIL GAP < 1
              COMPUTE NEGAP = GAP * -1
              PERFORM VARYING II FROM GAP BY 1
                        UNTIL II GREATER  NUM-ITEM
                 MOVE ' ' TO KEY-RESULT
                 COMPUTE ORG = (II - 1) * LGT-ITEM + 1
                 MOVE SRT-ARRAY(ORG:LGT-ITEM) TO TEMP(1:LGT-ITEM)
                 PERFORM VARYING IJ FROM II BY NEGAP
                           UNTIL IJ NOT GREATER  GAP
                              OR (KEY-RESULT NOT EQUAL '<' AND ' ')
                    COMPUTE IA = IJ - GAP
                    IF IA < 1
                       MOVE 1 TO IA
                    END-IF
                    PERFORM COMPARE-KEYS
                    IF KEY-RESULT = '<'
                       COMPUTE ORG = (IA - 1) * LGT-ITEM + 1
                       COMPUTE DST = (IJ - 1) * LGT-ITEM + 1
                       MOVE SRT-ARRAY(ORG:LGT-ITEM)
                         TO SRT-ARRAY(DST:LGT-ITEM)
                       COMPUTE DST = (IA - 1) * LGT-ITEM + 1
                       MOVE TEMP(1:LGT-ITEM) TO SRT-ARRAY(DST:LGT-ITEM)
                    END-IF
                 END-PERFORM
              END-PERFORM
              IF GAP = 2
                 MOVE 1 TO GAP
              ELSE
                 COMPUTE GAP = GAP / 2.2
              END-IF
           END-PERFORM.
           GOBACK.
      *
       COMPARE-KEYS.
           MOVE ' ' TO KEY-RESULT
           PERFORM VARYING IZ FROM 1 BY 1
                     UNTIL IZ GREATER 10
                        OR (KEY-RESULT NOT EQUAL '=' AND ' ')
              IF SRT-KEY(IZ) GREATER LOW-VALUES
                 COMPUTE STRT1 = (IJ - 1) * LGT-ITEM + K-START(IZ)
                 COMPUTE STRT2 = (IA - 1) * LGT-ITEM + K-START(IZ)
                 MOVE K-LENGTH(IZ) TO LGT
                 IF SRT-ARRAY(STRT1:LGT) > SRT-ARRAY(STRT2:LGT) AND
                    K-ASC(IZ) EQUAL 'A'
                 OR SRT-ARRAY(STRT1:LGT) < SRT-ARRAY(STRT2:LGT) AND
                    K-ASC(IZ) EQUAL 'D'
                    MOVE '>' TO KEY-RESULT
                 END-IF
                 IF SRT-ARRAY(STRT1:LGT) < SRT-ARRAY(STRT2:LGT) AND
                    K-ASC(IZ) EQUAL 'A'
                 OR SRT-ARRAY(STRT1:LGT) > SRT-ARRAY(STRT2:LGT) AND
                    K-ASC(IZ) EQUAL 'D'
                    MOVE '<' TO KEY-RESULT
                 END-IF
              END-IF
           END-PERFORM.
           IF KEY-RESULT = ' '
              MOVE '=' TO KEY-RESULT
           END-IF.


def sparkline(List<Number> list) {
    def (min, max) = [list.min(), list.max()]
    def div = (max - min) / 7
    list.collect { (char)(0x2581 + (it-min) * div) }.join()
}
def sparkline(String text) { sparkline(text.split(/[ ,]+/).collect { it as Double }) }


import Data.List.Split (splitOneOf)
import Data.Char (chr)

toSparkLine :: [Double] -> String
toSparkLine xs = map cl xs
  where
    top = maximum xs
    bot = minimum xs
    range = top - bot
    cl x = chr $ 0x2581 + floor (min 7 ((x - bot) / range * 8))

makeSparkLine :: String -> (String, Stats)
makeSparkLine xs = (toSparkLine parsed, stats parsed)
  where
    parsed = map read $ filter (not . null) $ splitOneOf " ," xs

data Stats = Stats
  { minValue, maxValue, rangeOfValues :: Double
  , numberOfValues :: Int
  }

instance Show Stats where
  show (Stats mn mx r n) =
    "min: " ++
    show mn ++
    "; max: " ++
    show mx ++ "; range: " ++ show r ++ "; no. of values: " ++ show n

stats :: [Double] -> Stats
stats xs =
  Stats
  { minValue = mn
  , maxValue = mx
  , rangeOfValues = mx - mn
  , numberOfValues = length xs
  }
  where
    mn = minimum xs
    mx = maximum xs

drawSparkLineWithStats :: String -> IO ()
drawSparkLineWithStats xs = putStrLn sp >> print st
  where
    (sp, st) = makeSparkLine xs

main :: IO ()
main =
  mapM_
    drawSparkLineWithStats
    [ "0, 1, 19, 20"
    , "0, 999, 4000, 4999, 7000, 7999"
    , "1 2 3 4 5 6 7 8 7 6 5 4 3 2 1"
    , "1.5, 0.5 3.5, 2.5 5.5, 4.5 7.5, 6.5"
    , "3 2 1 0 -1 -2 -3 -4 -3 -2 -1 0 1 2 3"
    , "-1000 100 1000 500 200 -400 -700 621 -189 3"
    ]


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

iList = [int 1, 4, 5, 3, -6, 3, 7, 10, -2, -5, 7, 5, 9, -3, 7]
sList = Arrays.copyOf(iList, iList.length)

sList = stoogeSort(sList)

lists = [iList, sList]
loop ln = 0 to lists.length - 1
  cl = lists[ln]
  rpt = Rexx('')
  loop ct = 0 to cl.length - 1
    rpt = rpt cl[ct]
    end ct
    say '['rpt.strip().changestr(' ', ',')']'
  end ln

return

method stoogeSort(L_ = int[], i_ = 0, j_ = L_.length - 1) public static returns int[]

  if L_[j_] < L_[i_] then do
    Lt     = L_[i_]
    L_[i_] = L_[j_]
    L_[j_] = Lt
    end
  if j_ - i_ > 1 then do
    t_ = (j_ - i_ + 1) % 3
    L_ = stoogeSort(L_, i_, j_ - t_)
    L_ = stoogeSort(L_, i_ + t_, j_)
    L_ = stoogeSort(L_, i_, j_ - t_)
    end

  return L_


proc stoogeSort[T](a: var openarray[T], i, j: int) =
  if a[j] < a[i]: swap a[i], a[j]
  if j - i > 1:
    let t = (j - i + 1) div 3
    stoogeSort(a, i, j - t)
    stoogeSort(a, i + t, j)
    stoogeSort(a, i, j - t)

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


bundle Default {
  class Stooge {
    function : Main(args : String[]) ~ Nil {
      nums := [1, 4, 5, 3, -6, 3, 7, 10, -2, -5];
      StoogeSort(nums);
      each(i : nums) {
        IO.Console->Print(nums[i])->Print(",");
      };
      IO.Console->PrintLine();
    }

    function : native : StoogeSort(l : Int[]) ~ Nil {
      StoogeSort(l, 0, l->Size() - 1);
    }

    function : native : StoogeSort(l : Int[], i : Int, j : Int) ~ Nil {
       if(l[j] < l[i]) {
        tmp := l[i];
        l[i] := l[j];
        l[j] := tmp;
      };

      if(j - i > 1) {
        t := (j - i + 1) / 3;
        StoogeSort(l, i, j - t);
        StoogeSort(l, i + t, j);
        StoogeSort(l, i, j - t);
      };
    }
  }
}


(defun gap-insertion-sort (array predicate gap)
  (let ((length (length array)))
    (if (< length 2) array
      (do ((i 1 (1+ i))) ((eql i length) array)
        (do ((x (aref array i))
             (j i (- j gap)))
            ((or (< (- j gap) 0)
                 (not (funcall predicate x (aref array (1- j)))))
             (setf (aref array j) x))
          (setf (aref array j) (aref array (- j gap))))))))

(defconstant +gaps+
  '(1750 701 301 132 57 23 10 4 1)
  "The best sequence of gaps, according to Marcin Ciura.")

(defun shell-sort (array predicate &optional (gaps +gaps+))
  (assert (eql 1 (car (last gaps))) (gaps)
    "Last gap of ~w is not 1." gaps)
  (dolist (gap gaps array)
    (gap-insertion-sort array predicate gap)))


import std.stdio: writeln;

void shellSort(T)(T[] seq) pure nothrow {
    int inc = seq.length / 2;
    while (inc) {
        foreach (ref i, el; seq) {
            while (i >= inc && seq[i - inc] > el) {
                seq[i] = seq[i - inc];
                i -= inc;
            }
            seq[i] = el;
        }
        inc = (inc == 2) ? 1 : cast(int)(inc * 5.0 / 11);
    }
}

void main() {
    auto data = [22, 7, 2, -5, 8, 4];
    shellSort(data);
    writeln(data);
}


   spkln =: verb define
   	y spkln~ 4 u:16b2581+i.8  NB.  ▁▂▃▄▅▆▇█
   :
   	'MIN MAX' =. (<./ , >./) y
   	N         =. # x
   	x {~ <. (N-1) * (y-MIN) % MAX-MIN
   )


public class Sparkline
{
	String bars="▁▂▃▄▅▆▇█";
	public static void main(String[] args)
	{
		Sparkline now=new Sparkline();
		float[] arr={1, 2, 3, 4, 5, 6, 7, 8, 7, 6, 5, 4, 3, 2, 1};
		now.display1D(arr);
		System.out.println(now.getSparkline(arr));
		float[] arr1={1.5f, 0.5f, 3.5f, 2.5f, 5.5f, 4.5f, 7.5f, 6.5f};
		now.display1D(arr1);
		System.out.println(now.getSparkline(arr1));
	}
	public void display1D(float[] arr)
	{
		for(int i=0;i<arr.length;i++)
			System.out.print(arr[i]+" ");
		System.out.println();
	}
	public String getSparkline(float[] arr)
	{
		float min=Integer.MAX_VALUE;
		float max=Integer.MIN_VALUE;
		for(int i=0;i<arr.length;i++)
		{
			if(arr[i]<min)
				min=arr[i];
			if(arr[i]>max)
				max=arr[i];
		}
		float range=max-min;
		int num=bars.length()-1;
		String line="";
		for(int i=0;i<arr.length;i++)
		{

			line+=bars.charAt((int)Math.ceil(((arr[i]-min)/range*num)));
		}
		return line;
	}
}


let swap ar i j =
  let tmp = ar.(i) in
  ar.(i) <- ar.(j);
  ar.(j) <- tmp

let stoogesort ar =
  let rec aux i j =
    if ar.(j) < ar.(i) then
      swap ar i j
    else if j - i > 1 then begin
      let t = (j - i + 1) / 3 in
      aux (i) (j-t);
      aux (i+t) (j);
      aux (i) (j-t);
    end
  in
  aux 0 (Array.length ar - 1)


/* Rexx */

call demo
return
exit

-- -----------------------------------------------------------------------------
--  Stooge sort implementation
-- -----------------------------------------------------------------------------
::routine stoogeSort
  use arg rL_, i_ = 0, j_ = .nil
  if j_ = .nil then j_ = rL_~items() - 1

  if rL_~get(j_) < rL_~get(i_) then do
    Lt = rL_~get(i_)
    rL_~set(i_, rL_~get(j_))
    rL_~set(j_, Lt)
    end
  if j_ - i_ > 1 then do
    t_ = (j_ - i_ + 1) % 3
    rL_ = stoogeSort(rL_, i_, j_ - t_)
    rL_ = stoogeSort(rL_, i_ + t_, j_)
    rL_ = stoogeSort(rL_, i_, j_ - t_)
    end

  return rL_

-- -----------------------------------------------------------------------------
-- Demonstrate the implementation
-- -----------------------------------------------------------------------------
::routine demo

  iList = .nlist~of(1, 4, 5, 3, -6, 3, 7, 10, -2, -5, 7, 5, 9, -3, 7)
  sList = iList~copy()

  placesList = .nlist~of( -
      "UK  London",     "US  New York",   "US  Boston",     "US  Washington" -
    , "UK  Washington", "US  Birmingham", "UK  Birmingham", "UK  Boston"     -
  )

  sList = stoogeSort(sList)
  sortedList = stoogeSort(placesList~copy())

  iLists = .list~of(iList, sList)
  loop ln = 0 to iLists~items() - 1
    icl = iLists[ln]
    rpt = ''
    loop ct = 0 to icl~items() - 1
      rpt = rpt icl[ct]
      end ct
      say '['rpt~strip()~changestr(' ', ',')']'
    end ln

  say
  sLists = .list~of(placesList, sortedList)
  loop ln = 0 to sLists~items() - 1
    scl = sLists[ln]
    loop ct = 0 to scl~items() - 1
      say right(ct + 1, 3)':' scl[ct]
      end ct
      say
    end ln

  return

-- -----------------------------------------------------------------------------
-- Helper class.  Map get and set methods for easier conversion from java.util.List
-- -----------------------------------------------------------------------------
::class NList mixinclass List public

-- Map get() to at()
::method get
  use arg ix
  return self~at(ix)

-- Map set() to put()
::method set
  use arg ix, item
  self~put(item, ix)
  return


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

shellSort(List<int> array) {
	int n = array.length;

        // Start with a big gap, then reduce the gap
        for (int gap = n~/2; gap > 0; gap ~/= 2)
        {
            // Do a gapped insertion sort for this gap size.
            // The first gap elements a[0..gap-1] are already
            // in gapped order keep adding one more element
            // until the entire array is gap sorted
            for (int i = gap; i < n; i += 1)
            {
                // add a[i] to the elements that have been gap
                // sorted save a[i] in temp and make a hole at
                // position i
                int temp = array[i];

                // shift earlier gap-sorted elements up until
                // the correct location for a[i] is found
                int j;
                for (j = i; j >= gap && array[j - gap] > temp; j -= gap)
                    array[j] = array[j - gap];

                // put temp (the original a[i]) in its correct
                // location
                array[j] = temp;
            }
        }
  return array;
}


Procedure ShellSort(var buf:Array of Integer);
const
  gaps:array[0..7] of Integer = (701, 301, 132, 57, 23, 10, 4, 1);

var
  whichGap, i, j, n, gap, temp : Integer;

begin
  n := high(buf);
  for whichGap := 0 to high(gaps) do begin
    gap := gaps[whichGap];
    for i := gap to n do begin
      temp := buf[i];

      j := i;
      while ( (j >= gap ) and ( (buf[j-gap] > dt) ) do begin
        buf[j] := buf[j-gap];
        dec(j, gap);
      end;
      buf[j] := temp;
    end;
  end;
end;


(() => {
    'use strict';

    const main = () => {

        // sparkLine :: [Num] -> String
        const sparkLine = xs => {
            const hist = dataBins(8)(xs);
            return unlines([
                concat(map(
                    i => '▁▂▃▄▅▆▇█' [i],
                    hist.indexes
                )),
                unwords(xs),
                [
                    'Min: ' + hist.min,
                    'Mean: ' + hist.mean.toFixed(2),
                    'Median: ' + hist.median,
                    'Max: ' + hist.max,
                ].join('\t'),
                ''
            ]);
        };

        // dataBins :: Int -> [Num] ->
        //      {indexes:: [Int], min:: Float, max:: Float,
        //        range :: Float, lbounds :: [Float]}
        const dataBins = intBins => xs => {
            const
                iLast = intBins - 1,
                ys = sort(xs),
                mn = ys[0],
                mx = last(ys),
                rng = mx - mn,
                w = rng / intBins,
                lng = xs.length,
                mid = lng / 2,
                lbounds = map(
                    i => mn + (w * i),
                    enumFromTo(1, iLast)
                );
            return {
                indexes: map(
                    x => {
                        const mb = findIndex(b => b > x, lbounds);
                        return mb.Nothing ? (
                            iLast
                        ) : mb.Just;
                    },
                    xs
                ),
                lbounds: lbounds,
                min: mn,
                median: even(lng) ? (
                    sum([ys[mid - 1], ys[mid]]) / 2
                ) : ys[Math.floor(mid)],
                mean: sum(xs) / lng,
                max: mx,
                range: rng
            };
        };

        // numbersFromString :: String -> [Float]
        const numbersFromString = s =>
            map(x => parseFloat(x, 10),
                s.split(/[,\s]+/)
            );

        return unlines(map(
            compose(sparkLine, numbersFromString),
            [
                '0, 1, 19, 20',
                '0, 999, 4000, 4999, 7000, 7999',
                '1 2 3 4 5 6 7 8 7 6 5 4 3 2 1',
                '1.5, 0.5 3.5, 2.5 5.5, 4.5 7.5, 6.5'
            ]
        ));
    };

    // GENERIC FUNCTIONS ----------------------------

    // Just :: a -> Maybe a
    const Just = x => ({
        type: 'Maybe',
        Nothing: false,
        Just: x
    });

    // Nothing :: Maybe a
    const Nothing = () => ({
        type: 'Maybe',
        Nothing: true,
    });

    // compose (<<<) :: (b -> c) -> (a -> b) -> a -> c
    const compose = (f, g) => x => f(g(x));

    // concat :: [[a]] -> [a]
    // concat :: [String] -> String
    const concat = xs =>
        0 < xs.length ? (() => {
            const unit = 'string' !== typeof xs[0] ? (
                []
            ) : '';
            return unit.concat.apply(unit, xs);
        })() : [];

    // enumFromTo :: (Int, Int) -> [Int]
    const enumFromTo = (m, n) =>
        Array.from({
            length: 1 + n - m
        }, (_, i) => m + i);

    // even :: Int -> Bool
    const even = n => 0 === n % 2;

    // last :: [a] -> a
    const last = xs =>
        0 < xs.length ? xs.slice(-1)[0] : undefined;

    // map :: (a -> b) -> [a] -> [b]
    const map = (f, xs) =>
        (Array.isArray(xs) ? (
            xs
        ) : xs.split('')).map(f);

    // sort :: Ord a => [a] -> [a]
    const sort = xs => xs.slice()
        .sort((a, b) => a < b ? -1 : (a > b ? 1 : 0));

    // findIndex :: (a -> Bool) -> [a] -> Maybe Int
    const findIndex = (p, xs) => {
        const
            i = (
                'string' !== typeof xs ? (
                    xs
                ) : xs.split('')
            ).findIndex(p);
        return -1 !== i ? (
            Just(i)
        ) : Nothing();
    };

    // sum :: [Num] -> Num
    const sum = xs => xs.reduce((a, x) => a + x, 0);

    // unlines :: [String] -> String
    const unlines = xs => xs.join('\n');

    // unwords :: [String] -> String
    const unwords = xs => xs.join(' ');

    // MAIN ---
    return main();
})();


declare
  proc {StoogeSort Arr}
     proc {Swap I J}
        Tmp = Arr.I
     in
        Arr.I := Arr.J
        Arr.J := Tmp
     end

     proc {Sort I J}
        Size = J-I+1
     in
        if Arr.J < Arr.I then
           {Swap I J}
        end
        if Size >= 3 then
           Third = Size div 3
        in
           {Sort I J-Third}
           {Sort I+Third J}
           {Sort I J-Third}
        end
     end
  in
     {Sort {Array.low Arr} {Array.high Arr}}
  end

  Arr = {Tuple.toArray unit(1 4 5 3 ~6 3 7 10 ~2 ~5 7 5 9 ~3 7)}
in
  {System.printInfo "\nUnsorted: "}
  for I in {Array.low Arr}..{Array.high Arr} do
     {System.printInfo Arr.I#", "}
  end

  {StoogeSort Arr}

  {System.printInfo "\nSorted  : "}
  for I in {Array.low Arr}..{Array.high Arr} do
     {System.printInfo Arr.I#", "}
  end


stoogeSort(v)={
  local(v=v); \\ Give children access to v
  ss(1,#v);   \\ Sort
  v
}

ss(i,j)={
  my(t);
  if(v[j]<v[i],
    t=v[i];
    v[i]=v[j];
    v[j]=t
  );
  if(j-i > 1,
    t=(1+j-i)\3;
    ss(i,j-t);
    ss(i+t,j);
    ss(i,j-t)
  )
};


/** Shell sort (in-place) */
def shellSort(array) {
    var inc := array.size() // 2
    while (inc.aboveZero()) {
        for var i => a in array {
            while (i >= inc && (def b := array[i - inc]) > a) {
                array[i] := b
                i -= inc
            }
            array[i] := a
        }
        inc := if (inc <=> 2) { 1 } else { (inc * 5.0 / 11).floor() }
    }
}


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

feature

    sort
            -- Shell sort
        local
            inc: INTEGER
            j: INTEGER
            l_value: like item
        do
            from
                inc := (count.to_double / 2.0).rounded
            until
                inc <= 0
            loop
                across inc |..| (count - 1) as ii
                loop
                    l_value := Current [ii.item + 1]
                    from
                        j := ii.item
                    until
                        j < inc or Current [j - inc + 1] <= l_value
                    loop
                        Current [j + 1] := Current [j - inc + 1]
                        j := j - inc
                    end
                    Current [j + 1] := l_value
                end
                inc := (inc.to_double / 2.2).rounded
            end
        end

end


def sparkline:
  min as $min
  | ( (max - $min) / 7 ) as $div
  | map( 9601 +  (. - $min) * $div )
  | implode ;

def string2array:
  def tidy: select( length > 0 );
  [split(" ") | .[] | split(",") | .[] | tidy | tonumber];


function sparklineit(arr)
    sparkchars = '\u2581':'\u2588'
    dyn = length(sparkchars)
    lo, hi = extrema(arr)
    b = @. max(ceil(Int, dyn * (arr - lo) / (hi - lo)), 1)
    return join(sparkchars[b])
end

v = rand(0:10, 10)
println("$v → ", sparklineit(v))
v = 10rand(10)
println("$(round.(v, 2)) → ", sparklineit(v))

lines = strip.(split("""
    1 2 3 4 5 6 7 8 7 6 5 4 3 2 1
    1.5, 0.5 3.5, 2.5 5.5, 4.5 7.5, 6.5""", "\n"))
arrays = map(lin -> split(lin, r"\s+|\s*,\s*") .|> s -> parse(Float64, s), lines)
foreach(v -> println("$v → ", sparklineit(v)), arrays)


internal const val bars = "▁▂▃▄▅▆▇█"
internal const val n = bars.length - 1

fun <T: Number> Iterable<T>.toSparkline(): String {
    var min = Double.MAX_VALUE
    var max = Double.MIN_VALUE
    val doubles = map { it.toDouble() }
    doubles.forEach { i -> when { i < min -> min = i; i > max -> max = i } }
    val range = max - min
    return doubles.fold("") { line, d -> line + bars[Math.ceil((d - min) / range * n).toInt()] }
}

fun String.toSparkline() = replace(",", "").split(" ").map { it.toFloat() }.toSparkline()

fun main(args: Array<String>) {
    val s1 = "1 2 3 4 5 6 7 8 7 6 5 4 3 2 1"
    println(s1)
    println(s1.toSparkline())
    val s2 = "1.5, 0.5 3.5, 2.5 5.5, 4.5 7.5, 6.5"
    println(s2)
    println(s2.toSparkline())
}


program StoogeSortDemo;

type
  TIntArray = array of integer;

procedure stoogeSort(var m: TIntArray; i, j: integer);
  var
    t, temp: integer;
  begin
    if m[j] < m[i] then
    begin
      temp := m[j];
      m[j] := m[i];
      m[i] := temp;
    end;
    if j - i > 1 then
    begin
      t := (j - i + 1) div 3;
      stoogesort(m, i, j-t);
      stoogesort(m, i+t, j);
      stoogesort(m, i, j-t);
    end;
  end;

var
  data: TIntArray;
  i: integer;

begin
  setlength(data, 8);
  Randomize;
  writeln('The data before sorting:');
  for i := low(data) to high(data) do
  begin
    data[i] := Random(high(data));
    write(data[i]:4);
  end;
  writeln;
  stoogeSort(data, low(data), high(data));
  writeln('The data after sorting:');
  for i := low(data) to high(data) do
  begin
    write(data[i]:4);
  end;
  writeln;
end.


defmodule Sort do
  def shell_sort(list) when length(list)<=1, do: list
  def shell_sort(list), do: shell_sort(list, div(length(list),2))

  defp shell_sort(list, inc) do
    gb = Enum.with_index(list) |> Enum.group_by(fn {_,i} -> rem(i,inc) end)
    wk = Enum.map(0..inc-1, fn i ->
           Enum.map(gb[i], fn {x,_} -> x end) |> insert_sort([])
         end)
         |> merge
    if sorted?(wk), do: wk, else: shell_sort( wk, max(trunc(inc / 2.2), 1) )
  end

  defp merge(lists) do
    len = length(hd(lists))
    Enum.map(lists, fn list -> if length(list)<len, do: list++[nil], else: list end)
    |> List.zip
    |> Enum.flat_map(fn tuple -> Tuple.to_list(tuple) end)
    |> Enum.filter(&(&1))               # remove nil
  end

  defp sorted?(list) do
    Enum.chunk(list,2,1) |> Enum.all?(fn [a,b] -> a <= b end)
  end

  defp insert_sort(list), do: insert_sort(list, [])

  defp insert_sort([], sorted), do: sorted
  defp 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

list = [0, 14, 11, 8, 13, 15, 5, 7, 16, 17, 1, 6, 12, 2, 10, 4, 19, 9, 18, 3]
IO.inspect Sort.shell_sort(list)


function shell_sort(sequence s)
    integer gap,j
    object temp
    gap = floor(length(s)/2)
    while gap > 0 do
        for i = gap to length(s) do
            temp = s[i]
            j=i-gap
            while j >= 1 and compare(temp, s[j]) <= 0 do
                s[j+gap]=s[j]
                j -= gap
            end while
            s[j+gap] = temp
        end for
        gap = floor(gap/2)
    end while
    return s
end function

constant s = rand(repeat(1000,10))
puts(1,"Before: ")
? s
puts(1,"After:  ")
? shell_sort(s)


defer less?   ' < is less?

: shell { array len -- }
  1 begin dup len u<= while 2* 1+ repeat { gap }
  begin gap 2 = if 1 else gap 5 11 */ then dup to gap while
    len gap do
      array i cells +
      dup @ swap         ( temp last )
      begin gap cells -
            array over u<=
      while 2dup @ less?
      while dup gap cells + over @ swap !
      repeat then
      gap cells + !
    loop
  repeat ;

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

array 10 shell
array 10 cells dump


command sparklines listOfNums
    local utfbase=0x2581
    local tStats, utfp, tmin,tmax,trange
    put listOfNums into tStats
    replace ", " with space in tStats
    replace space with comma in tStats
    put min(tStats) into tmin
    put max(tStats) into tmax
    put tmax - tmin into trange
    put "Min:" && tmin && tab into plot
    put "Max:" && tmax && tab after plot
    put "Range:" && trange && tab after plot
    put "Mean" && average(tStats) && tab after plot
    put "Stdev:" && standardDeviation(tStats) && tab after plot
    put "Variance:" && variance(tStats) && return after plot

    repeat for each item i in tStats
        put  (round(i - tmin/trange * 7)) + utfbase into utfp
        put numToCodepoint(utfp) after plot
    end repeat
    put plot
end sparklines


Module CheckIt {
      Function Row$(a) {
          def item$(a)=str$(car(a)#val(0),0)
          rep$=item$(a)
          while len(a)
          rep$+=", "+item$(a)
          a=cdr(a)
          End While
          =rep$
      }
      Font "Dejavu Sans Mono"
      Cls
      Const bar$="▁▂▃▄▅▆▇█"
      Document doc$
      data1=(1, 2, 3, 4, 5, 6, 7, 8, 7, 6, 5, 4, 3, 2, 1)
      data2=(1.5, 0.5, 3.5, 2.5, 5.5, 4.5, 7.5, 6.5)
      SparkLine(data1)
      SparkLine(data2)
      Clipboard doc$
      Sub SparkLine(dat as array)
            Local min=dat#min(), range=(dat#max()-dat#min()), range1=7/range
            Local item, rep$="Input:"+Row$(dat)+{
            }
            item=each(dat)
            While item
            rep$+=Mid$(bar$,(array(item)-min)*range1+1 ,1)
            End While
            rep$+=" ("+str$(range,1033)+")"
            doc$=rep$+{
            }
            Report rep$
      End Sub
}
Checkit


toSparkline[data_String] := FromCharacterCode[Round[7 [email protected]@ImportString[data, "Table", "FieldSeparators" -> {" ", ","}]] + 16^^2581];


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

runSample(arg)
return

-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
method sparkline(spark) private static
  spark = spark.changestr(',', ' ')
  bars = '\u2581 \u2582 \u2583 \u2584 \u2585 \u2586 \u2587 \u2588'
  barK = bars.words()
  nmin = spark.word(1)
  nmax = nmin
  -- get min & max values
  loop iw = 1 to spark.words()
    nval = spark.word(iw)
    nmin = nval.min(nmin)
    nmax = nval.max(nmax)
    end iw
  range = nmax - nmin + 1
  slope = ''
  loop iw = 1 to spark.words()
    point = Math.ceil((spark.word(iw) - nmin + 1) / range * barK)
    slope = slope || bars.word(point)
    end iw
  return slope nmin nmax range

-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
method runSample(arg) private static
  -- sample data setup
  parse arg vals
  sparks = 0
  sparks[0] = 0
  if vals = '' then do
    si = sparks[0] + 1; sparks[0] = si; sparks[si] = 1 2 3 4 5 6 7 8 7 6 5 4 3 2 1
    si = sparks[0] + 1; sparks[0] = si; sparks[si] = '1.5, 0.5 3.5, 2.5 5.5, 4.5 7.5, 6.5'
    end
  else do
    loop until vals = ''
      -- split input on a ! character
      parse vals lst '!' vals
      si = sparks[0] + 1; sparks[0] = si; sparks[si] = lst
      end
    end
  -- run the samples
  loop si = 1 to sparks[0]
    vals = sparks[si]
    parse sparkline(vals) slope .
    say 'Input:        ' vals
    say 'Sparkline:    ' slope
    say
    end si

  return


with javascript_semantics

function stoogesort(sequence s, integer i=1, j=length(s))
    if s[j]<s[i] then
        {s[i],s[j]} = {s[j],s[i]}
    end if
    if j-i>1 then
        integer t = floor((j-i+1)/3)
        s = stoogesort(s,i,  j-t)
        s = stoogesort(s,i+t,j  )
        s = stoogesort(s,i,  j-t)
    end if
    return s
end function

?stoogesort(shuffle(tagset(10)))


function stoogeSort(&$arr, $i, $j)
{
	if($arr[$j] < $arr[$i])
	{
		list($arr[$j],$arr[$i]) = array($arr[$i], $arr[$j]);
	}
	if(($j - $i) > 1)
	{
		$t = ($j - $i + 1) / 3;
		stoogesort($arr, $i, $j - $t);
		stoogesort($arr, $i + $t, $j);
		stoogesort($arr, $i, $j - $t);
	}
}


MODULE sort

CONTAINS

SUBROUTINE Shell_Sort(a)

  IMPLICIT NONE
  INTEGER :: i, j, increment
  REAL :: temp
  REAL, INTENT(in out) :: a(:)

  increment = SIZE(a) / 2
  DO WHILE (increment > 0)
      DO i = increment+1, SIZE(a)
         j = i
         temp = a(i)
         DO WHILE (j >= increment+1 .AND. a(j-increment) > temp)
            a(j) = a(j-increment)
            j = j - increment
         END DO
         a(j) = temp
      END DO
      IF (increment == 2) THEN
   	  increment = 1
      ELSE
         increment = increment * 5 / 11
      END IF
  END DO

END SUBROUTINE Shell_Sort

END MODULE sort

PROGRAM Shellsort

USE sort

  IMPLICIT NONE
  REAL :: array(1000)

  CALL RANDOM_SEED
  CALL RANDOM_NUMBER(array)

  WRITE (*,*) "Unsorted array"
  WRITE (*,*) array
  WRITE (*,*)
  CALL Shell_Sort(array)
  WRITE (*,*) "Sorted array"
  WRITE (*,*) array

END PROGRAM Shellsort


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

Sub shellsort(s() 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(s)
    Dim As Long ub = UBound(s)
    Dim As Long done, i, inc = ub - lb

    Do
        inc = Int(inc / 2.2)
        If inc < 1 Then inc = 1

        Do
            done = 0
            For i = lb To ub - inc
                ' replace "<" with ">" for downwards sort
                If s(i) > s(i + inc) Then
                    Swap s(i), s(i + inc)
                    done = 1
                End If
            Next
        Loop Until done = 0

    Loop Until inc = 1

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
shellsort(array())  ' sort the 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


import rdstdin, sequtils, strutils

const bar = ["\u2581", "\u2582", "\u2583", "\u2584", "\u2585", "\u2586", "\u2587", "\u2588"]
const barcount = float(bar.high)

while true:
  let
    line = readLineFromStdin "Numbers please separated by space/commas: "
    numbers = line.split({' ', ','}).filterIt(it.len != 0).map(parseFloat)
    mn = min(numbers)
    mx = max(numbers)
    extent = mx - mn
  var sparkline = ""
  for n in numbers:
    let i = int((n - mn) / extent * barcount)
    sparkline.add bar[i]
  echo "min: ", mn.formatFloat(precision = 0), "; max: ", mx.formatFloat(precision = -1)
  echo sparkline


let before_first_bar = 0x2580
let num_bars = 8

let sparkline numbers =
  let max_num = List.fold_left max 0. numbers in
  let scale = float_of_int num_bars /. max_num in
  let bars = Buffer.create num_bars in
  let add_bar number =
    let scaled = scale *. number |> Float.round |> int_of_float in
    if scaled <= 0 then
      (* Using underscore character to differentiate between zero and one *)
      Buffer.add_char bars '_'
    else
      scaled + before_first_bar |> Uchar.of_int |> Buffer.add_utf_8_uchar bars
  in
  List.iter add_bar numbers;
  Buffer.contents bars

let print_sparkline line =
  Printf.printf "Numbers: %s\n" line;
  line
  |> String.trim
  |> String.split_on_char ' '
  |> List.map (String.split_on_char ',')
  |> List.flatten
  |> List.filter_map (function
    | "" -> None
    | number -> Some (float_of_string number))
  |> sparkline
  |> print_endline

let () =
  "0 0 1 1; 0 1 19 20; 0 999 4000 4999 7000 7999;
   1 2 3 4 5 6 7 8 7 6 5 4 3 2 1;
   1.5, 0.5 3.5, 2.5 5.5, 4.5 7.5, 6.5 "
  |> String.trim
  |> String.split_on_char ';'
  |> List.iter print_sparkline


binmode(STDOUT, ":utf8");
our @sparks=map {chr} 0x2581 .. 0x2588;
sub sparkline(@) {
    my @n=map {0+$_} grep {length} @_ or return "";
    my($min,$max)=($n[0])x2;
    if (@n>1) {
        for (@n[1..$#n]) {
            if    ($_<$min) { $min=$_ }
            elsif ($_>$max) { $max=$_ }
        }
    }
    my $sparkline="";
    for(@n) {
        my $height=int( $max==$min ? @sparks/2 : ($_-$min)/($max-$min)*@sparks );
        $height=$#sparks if $height>$#sparks;
        $sparkline.=$sparks[$height];
    }
    my $summary=sprintf "%d values; range %s..%s", scalar(@n), $min, $max;
    return wantarray ? ($summary, "\n", $sparkline, "\n") : $sparkline;
}

# one number per line
# print sparkline( <> );

# in scalar context, get just the sparkline without summary or trailing newline
# my $sl=sparkline( <> ); print $sl;

# one sparkline per line
print sparkline( split /[\s,]+/ ) while <>;


(de stoogeSort (L N)
   (default N (length L))
   (let P (nth L N)
      (when (> (car L) (car P))
         (xchg L P) ) )
   (when (> N 2)
      (let D (/ N 3)
         (stoogeSort L (- N D))
         (stoogeSort (nth L (inc D)) (- N D))
         (stoogeSort L (- N D)) ) )
   L )


stoogesort: procedure (L) recursive; /* 16 August 2010 */
   declare L(*) fixed binary;
   declare (i, j, t, temp) fixed binary;

   j = hbound(L,1);
   do i = lbound(L, 1) to j;
     if L(j) < L(i) then
         do; temp = L(i); L(i) = L(j); L(j) = temp; end;
     if j - i > 1 then
         do;
            t = (j - i + 1)/3;
            call stoogesort(L, i  , j-t);
            call stoogesort(L, i+t, j  );
            call stoogesort(L, i  , j-t);
         end;
   end;
end stoogesort;


%arraysize = 10

SUB stoogesort (L() AS LONG, i AS LONG, j AS LONG)
    IF L(j) < L(i) THEN SWAP L(i), L(j)
    IF (j - i) > 1 THEN
        DIM t AS LONG
        t = (j - i + 1) / 3
        stoogesort L(), i, j - t
        stoogesort L(), i + t, j
        stoogesort L(), i, j - t
    END IF
END SUB

FUNCTION PBMAIN () AS LONG
    RANDOMIZE TIMER

    DIM x(%arraysize) AS LONG
    DIM i AS LONG, s AS STRING

    s = "Before: "
    FOR i = 0 TO %arraysize
        x(i) = INT(RND * 100)
        s = s & STR$(x(i)) & " "
    NEXT

    stoogesort x(), 0, %arraysize

    #IF %DEF(%PB_CC32)
        PRINT s
        s = ""
    #ELSE
        s = s & $CRLF
    #ENDIF

    s = s & "After: "
    FOR i = 0 TO %arraysize
        s = s & STR$(x(i)) & " "
    NEXT

    ? s
END FUNCTION


package main

import "fmt"

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

func main() {
    fmt.Println("before:", a)
    for inc := len(a) / 2; inc > 0; inc = (inc + 1) * 5 / 11 {
        for i := inc; i < len(a); i++ {
            j, temp := i, a[i]
            for ; j >= inc && a[j-inc] > temp; j -= inc {
                a[j] = a[j-inc]
            }
            a[j] = temp
        }
    }
    fmt.Println("after: ", a)
}


import Data.List

shellSort xs = foldr (invColumnize (map (foldr insert []))) xs gaps
  where gaps = takeWhile (< length xs) $ iterate (succ.(3*)) 1
        invColumnize f k = concat. transpose. f. transpose
                           . takeWhile (not.null). unfoldr (Just. splitAt k)


with javascript_semantics
requires("1.0.2") -- (a fix for JS)
include builtins\unicode_console.e

constant tests = {"0 1 19 20", "0 0 1 1",
                  "0 999 4000 4999 7000 7999", "1 1 2 2 3 3",
                  "1 2 3 4 5 6 7 8 7 6 5 4 3 2 1",
                  "1.5, 0.5 3.5, 2.5 5.5, 4.5 7.5, 6.5"}

for i=1 to length(tests) do
    sequence ti = split_any(tests[i]," ,")
    for j=1 to length(ti) do
        {{ti[j]}} = scanf(ti[j],"%f")
    end for
    atom mn = min(ti),
         mx = max(ti),
         range = mx-mn
    printf(1,"Min :%g, Max :%g, Range :%g\n",{mn,mx,range})

    if unicode_console() then
        for j=1 to length(ti) do
            ti[j] = #2581 + min(7,floor((ti[j]-mn)/range*8))
        end for
        printf(1,"%s\n",{utf32_to_utf8(ti)})
    else
        puts(1,"unicode is not supported\n")
    end if
end for


(de sparkLine (Lst)
   (let (Min (apply min Lst)  Max (apply max Lst)  Rng (- Max Min))
      (for N Lst
         (prin
            (char (+ 9601 (*/ (- N Min) 7 Rng)) ) ) )
      (prinl) ) )


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

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


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

procedure shellsort(X,op)             #: return sorted X
local i,j,inc,temp

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

   inc := *X/2
   while inc > 0 do {
      every i := inc to *X do {
         temp := X[j := i]
         while op(temp,X[j - (j >= inc)]) do
            X[j] := X[j -:= inc]
         X[j] := temp
         }
      inc := if inc = 2 then 1 else inc*5/11 # switch to insertion near the end
      }
   return X
end


List do(
    shellSortInPlace := method(
        gap := (size / 2) round
        while(gap > 0,
            for(i, gap, size - 1,
                key := at(i)
                j := i

                while(j >= gap and at(j - gap) > key,
                    atPut(j, at(j - gap))
                    j = j - gap
                )
                atPut(j, key)
            )
            gap = (gap / 2.2) round
        )
    self)
)

l := list(2, 3, 4, 5, 1)
l shellSortInPlace println # ==> list(1, 2, 3, 4, 5)


# -*- coding: utf-8 -*-

# Unicode: 9601, 9602, 9603, 9604, 9605, 9606, 9607, 9608
bar = '▁▂▃▄▅▆▇█'
barcount = len(bar)

def sparkline(numbers):
    mn, mx = min(numbers), max(numbers)
    extent = mx - mn
    sparkline = ''.join(bar[min([barcount - 1,
                                 int((n - mn) / extent * barcount)])]
                        for n in numbers)
    return mn, mx, sparkline

if __name__ == '__main__':
    import re

    for line in ("0 0 1 1; 0 1 19 20; 0 999 4000 4999 7000 7999;"
                 "1 2 3 4 5 6 7 8 7 6 5 4 3 2 1;"
                 "1.5, 0.5 3.5, 2.5 5.5, 4.5 7.5, 6.5 ").split(';'):
        print("\nNumbers:", line)
        numbers = [float(n) for n in re.split(r'[\s,]+', line.strip())]
        mn, mx, sp = sparkline(numbers)
        print('  min: %5f; max: %5f' % (mn, mx))
        print("  " + sp)


bars <-  intToUtf8(seq(0x2581, 0x2588), multiple = T)  # ▁ ▂ ▃ ▄ ▅ ▆ ▇ █
n_chars <- length(bars)

sparkline <- function(numbers) {
  mn <- min(numbers)
  mx <- max(numbers)
  interval <- mx - mn

  bins <- sapply(
    numbers,
    function(i)
      bars[[1 + min(n_chars - 1, floor((i - mn) / interval * n_chars))]]
  )
  sparkline <- paste0(bins, collapse = "")

  return(sparkline)
}

sparkline(c(1, 2, 3, 4, 5, 6, 7, 8, 7, 6, 5, 4, 3, 2, 1))
sparkline(c(1.5, 0.5, 3.5, 2.5, 5.5, 4.5, 7.5, 6.5))
sparkline(c(0, 999, 4000, 4999, 7000, 7999))
sparkline(c(0, 0, 1, 1))
sparkline(c(0, 1, 19, 20))


Procedure Stooge_Sort(Array L.i(1), i=0 , j=0)
  If j=0
    j=ArraySize(L())
  EndIf
  If L(i)>L(j)
    Swap L(i), L(j)
  EndIf
  If j-i>1
    Protected t=(j-i+1)/3
    Stooge_Sort(L(), i,   j-t)
    Stooge_Sort(L(), i+t, j )
    Stooge_Sort(L(), i,   j-t)
  EndIf
EndProcedure


100 PROGRAM "ShellSrt.bas"
110 RANDOMIZE
120 LET N=20 ! Number of elements
130 NUMERIC ARRAY(1 TO N)
140 CALL INIT(ARRAY)
150 CALL WRITE(ARRAY)
160 CALL SHELLSORT(ARRAY)
170 CALL WRITE(ARRAY)
180 DEF INIT(REF A)
190   FOR I=LBOUND(A) TO UBOUND(A)
200     LET A(I)=RND(N)+1
210   NEXT
220 END DEF
230 DEF WRITE(REF A)
240   FOR I=LBOUND(A) TO UBOUND(A)
250     PRINT A(I);
260   NEXT
270   PRINT
280 END DEF
290 DEF SHELLSORT(REF A)
300   LET D=2^INT(LOG(N)/LOG(2))-1
310   DO
320     LET I=1
330     DO WHILE I<=D AND I+D<=N
340       FOR J=I+D TO N STEP D
350         LET AH=A(J):LET BH=J-D
360         DO WHILE BH>0 AND AH<A(BH)
370           LET A(BH+D)=A(BH):LET BH=BH-D
380         LOOP
390         LET A(BH+D)=AH
400       NEXT
410       LET I=I+1
420     LOOP
430     LET D=INT(D/2)
440   LOOP WHILE D>0
450 END DEF


public static void shell(int[] a) {
	int increment = a.length / 2;
	while (increment > 0) {
		for (int i = increment; i < a.length; i++) {
			int j = i;
			int temp = a[i];
			while (j >= increment && a[j - increment] > temp) {
				a[j] = a[j - increment];
				j = j - increment;
			}
			a[j] = temp;
		}
		if (increment == 2) {
			increment = 1;
		} else {
			increment *= (5.0 / 11);
		}
	}
}


#lang racket (require syntax/parse)

(define bars "▁▂▃▄▅▆▇█")
(define bar-count (string-length bars))

(define (sparks str)
  (define ns (map string->number (string-split str #rx"[ ,]" #:repeat? #t)))
  (define mn (apply min ns))
  (define bar-width (/ (- (apply max ns) mn) (- bar-count 1)))
  (apply string (for/list ([n ns]) (string-ref bars (exact-floor (/ (- n mn) bar-width))))))

(sparks "1 2 3 4 5 6 7 8 7 6 5 4 3 2 1")
(sparks "1.5, 0.5 3.5, 2.5 5.5, 4.5 7.5, 6.5")


constant @bars = '▁' ... '█';
while prompt 'Numbers separated by anything: ' -> $_ {
    my @numbers = map +*, .comb(/ '-'? [[\d+ ['.' \d*]?] | ['.' \d+]] /);
    my ($mn,$mx) = @numbers.minmax.bounds;
    say "min: $mn.fmt('%5f'); max: $mx.fmt('%5f')";
    say @bars[ @numbers.map: { @bars * ($_ - $mn) / ($mx - $mn) min @bars - 1 } ].join;
}


/* Rexx */

parse arg aaa
call runSample aaa
return

-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
sparkline:
  procedure
  parse arg spark
  spark = changestr(',', spark, ' ')
  bars = '▁ ▂ ▃ ▄ ▅ ▆ ▇ █'
  barK = words(bars)
  nmin = word(spark, 1)
  nmax = nmin
  -- get min & max values
  do iw = 1 to words(spark)
    nval = word(spark, iw)
    nmin = min(nval, nmin)
    nmax = max(nval, nmax)
    end iw
  range = nmax - nmin + 1
  slope = ''
  do iw = 1 to words(spark)
    point = ceiling((word(spark, iw) - nmin + 1) / range * barK)
    slope = slope || word(bars, point)
    end iw
  return slope nmin nmax range

-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
ceiling:
procedure
  parse arg ceil
  return trunc(ceil) + (ceil > 0) * (ceil \= trunc(ceil))
floor:
procedure
  parse arg flor
  return trunc(flor) - (flor < 0) * (flor \= trunc(flor))

-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
runSample:
procedure
  -- sample data setup
  parse arg vals
  sparks = 0
  sparks.0 = 0
  if vals = '' then do
    si = sparks.0 + 1; sparks.0 = si; sparks.si = 1 2 3 4 5 6 7 8 7 6 5 4 3 2 1
    si = sparks.0 + 1; sparks.0 = si; sparks.si = '1.5, 0.5 3.5, 2.5 5.5, 4.5 7.5, 6.5'
    end
  else do
    do until vals = ''
      -- split input on a ! character
      parse var vals lst '!' vals
      si = sparks.0 + 1; sparks.0 = si; sparks.si = lst
      end
    end
  -- run the samples
  do si = 1 to sparks.0
    vals = sparks.si
    parse value sparkline(vals) with slope .
    say 'Input:        ' vals
    say 'Sparkline:    ' slope
    say
    end si

  return


  [ 2 * 3 /mod 0 > + ]       is twothirds  ( n --> n )

  [ dup 0 peek over -1 peek
    2dup > iff
      [ rot 0 poke -1 poke ]
    else 2drop ]             is swapends   ( [ --> [ )

  [ swapends
    dup size 3 < if done
    dup size twothirds split
    swap recurse swap join
    dup size 3 / split
    recurse join
    dup size twothirds split
    swap recurse swap join ] is stoogesort ( [ --> [ )

  [] 33 times [ 90 random 10 + join ]
  dup echo cr
  stoogesort echo


stoogesort = function(vect) {
	i = 1
	j = length(vect)
	if(vect[j] < vect[i])  vect[c(j, i)] = vect[c(i, j)]
	if(j - i > 1) {
		t = (j - i + 1) %/% 3
		vect[i:(j - t)] = stoogesort(vect[i:(j - t)])
		vect[(i + t):j] = stoogesort(vect[(i + t):j])
		vect[i:(j - t)] = stoogesort(vect[i:(j - t)])
	}
	vect
}

v = sample(21, 20)
k = stoogesort(v)
v
k


#lang racket
(define (stooge-sort xs [i 0] [j (- (vector-length xs) 1)])
  (define (x i) (vector-ref xs i))
  (define (x! i v) (vector-set! xs i v))
  (define (swap! i j) (define t (x i)) (x! i (x j)) (x! j t))
  (when (> (x i) (x j)) (swap! i j))
  (when (> (- j i) 1)
    (define t (quotient (+ j (- i) 1) 3))
    (stooge-sort xs i (- j t))
    (stooge-sort xs (+ i t) j)
    (stooge-sort xs i (- j t)))
  xs)


sub stoogesort( @L, $i = 0, $j = @L.end ) {
    @L[$j,$i] = @L[$i,$j] if @L[$i] > @L[$j];

    my $interval = $j - $i;

    if $interval > 1 {
         my $t = ( $interval + 1 ) div 3;
         stoogesort( @L, $i   , $j-$t );
         stoogesort( @L, $i+$t, $j    );
         stoogesort( @L, $i   , $j-$t );
    }
    return @L;
}

my @L = 1, 4, 5, 3, -6, 3, 7, 10, -2, -5;

stoogesort(@L).Str.say;


function shellSort (a) {
    for (var h = a.length; h > 0; h = parseInt(h / 2)) {
        for (var i = h; i < a.length; i++) {
            var k = a[i];
            for (var j = i; j >= h && k < a[j - h]; j -= h)
                a[j] = a[j - h];
            a[j] = k;
        }
    }
    return a;
}

var a = [];
var n = location.href.match(/\?(\d+)|$/)[1] || 10;
for (var i = 0; i < n; i++)
    a.push(parseInt(Math.random() * 100));
shellSort(a);
document.write(a.join(" "));


# The "while" loops are implemented using the following jq function:

# As soon as "condition" is true, then emit . and stop:
def do_until(condition; next):
  def u: if condition then . else (next|u) end;
  u;

# sort the input array
def shellSort:
  length as $length
  | [ ($length/2|floor), .]                          # L1: state: [h, array]
  | do_until( .[0] == 0;
              .[0] as $h
              | reduce range($h; $length) as $i      # L2: state: array
                  ( .[1];
                   .[$i] as $k
                   | [ $i, . ]                       # L3: state: [j, array]
                   | do_until( .[0] < $h or ($k >= .[1][.[0] - $h]);
                               .[0] as $j
                               | [ ($j - $h), (.[1]|setpath([$j]; .[$j - $h])) ] )
                   | .[0] as $j | (.[1]|setpath([$j]; $k))  # i.e. a[j] = $k
                  )
              | [(($h+1)*5/11 | floor), .] )
       | .[1] ;


# v0.6

function shellsort!(a::Array{Int})::Array{Int}
    incr = div(length(a), 2)
    while incr > 0
        for i in incr+1:length(a)
            j = i
            tmp = a[i]
            while j > incr && a[j - incr] > tmp
                a[j] = a[j-incr]
                j -= incr
            end
            a[j] = tmp
        end
        if incr == 2
            incr = 1
        else
            incr = floor(Int, incr * 5.0 / 11)
        end
    end
    return a
end

x = rand(1:10, 10)
@show x shellsort!(x)
@assert issorted(x)


bar = ('▁'..'█').to_a
loop {print 'Numbers please separated by space/commas: '
  numbers = gets.split(/[\s,]+/).map(&:to_f)
  min, max = numbers.minmax
  puts "min: %5f; max: %5f"% [min, max]
  div = (max - min) / (bar.size - 1)
  puts min == max ? bar.last*numbers.size : numbers.map{|num| bar[((num - min) / div).to_i]}.join
}