Sorting algorithms/Gnome sort: Difference between revisions

From Rosetta Code
Content added Content deleted
(Added Elixir)
(Added Julia version)
Line 1,189: Line 1,189:
}
}
]</lang>
]</lang>

=={{header|Julia}}==

Julia is one-indexed so the implementation differs slightly from the pseudocode.

<lang Julia>function gnomesort(A::AbstractVector)
i = 1
j = 2
while i < length(A)
if A[i] <= A[i + 1]
i = j
j += 1
else
A[i], A[i + 1] = A[i + 1], A[i]
i -= 1
if i == 0
i = j
j += 1
end
end
end
A
end

A = randcycle(20)
println("unsorted: ", A)
println("sorted: ", gnomesort(A))</lang>

{{out}}

<pre>unsorted: [13,15,6,11,3,19,17,20,2,18,9,14,8,10,16,7,12,1,4,5]
sorted: [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20]</pre>


=={{header|Lua}}==
=={{header|Lua}}==

Revision as of 06:32, 19 June 2015

Task
Sorting algorithms/Gnome sort
You are encouraged to solve this task according to the task description, using any language you may know.
This page uses content from Wikipedia. The original article was at Gnome sort. The list of authors can be seen in the page history. As with Rosetta Code, the text of Wikipedia is available under the GNU FDL. (See links for details on variance)

Gnome sort is a sorting algorithm which is similar to Insertion sort, except that moving an element to its proper place is accomplished by a series of swaps, as in Bubble Sort.

The pseudocode for the algorithm is:

function gnomeSort(a[0..size-1])
    i := 1
    j := 2
    while i < size do
        if a[i-1] <= a[i] then
            // for descending sort, use >= for comparison
            i := j
            j := j + 1 
        else
            swap a[i-1] and a[i]
            i := i - 1
            if i = 0 then
                i := j
                j := j + 1
            endif
        endif
    done

Task: implement the Gnome sort in your language to sort an array (or list) of numbers.

ActionScript

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

Ada

This example is a generic procedure for constrained array types. <lang Ada>generic

  type Element_Type is private;
  type Index is (<>);
  type Collection is array(Index) of Element_Type;
  with function "<=" (Left, Right : Element_Type) return Boolean is <>;

procedure Gnome_Sort(Item : in out Collection);</lang>

<lang Ada>procedure Gnome_Sort(Item : in out Collection) is

  procedure Swap(Left, Right : in out Element_Type) is
     Temp : Element_Type := Left;
  begin
     Left := Right;
     Right := Temp;
  end Swap;
  
  I : Integer := Index'Pos(Index'Succ(Index'First));
  J : Integer := I + 1;

begin

  while I <= Index'Pos(Index'Last) loop
     if Item(Index'Val(I - 1)) <= Item(Index'Val(I)) then
        I := J;
        J := J + 1;
     else
        Swap(Item(Index'Val(I - 1)), Item(Index'Val(I)));
        I := I - 1;
        if I = Index'Pos(Index'First) then
           I := J;
           J := J + 1;
        end if;
     end if;
  end loop;

end Gnome_Sort;</lang> Usage example: <lang Ada>with Gnome_Sort; with Ada.Text_Io; use Ada.Text_Io;

procedure Gnome_Sort_Test is

  type Index is range 0..9;
  type Buf is array(Index) of Integer;
  procedure Sort is new Gnome_Sort(Integer, Index, Buf);
  A : Buf := (900, 700, 800, 600, 400, 500, 200, 100, 300, 0);

begin

  for I in A'range loop
     Put(Integer'Image(A(I)));
  end loop;
  New_Line;
  Sort(A);
  for I in A'range loop
     Put(Integer'Image(A(I)));
  end loop;
  New_Line;

end Gnome_Sort_Test;</lang>

ALGOL 68

Works with: ALGOL 68 version Standard - no extensions to language used
Works with: ALGOL 68G version Any - tested with release mk15-0.8b.fc9.i386
Works with: ELLA ALGOL 68 version Any (with appropriate job cards AND formatted transput statements removed) - tested with release 1.8.8d.fc9.i386

<lang algol68>MODE SORTSTRUCT = CHAR;

PROC inplace gnome sort = (REF[]SORTSTRUCT list)REF[]SORTSTRUCT: BEGIN

 INT i:=LWB list + 1, j:=LWB list + 2;
 WHILE i <= UPB list DO
   IF list[i-1] <= list[i] THEN
     i := j; j+:=1
   ELSE
     SORTSTRUCT swap = list[i-1]; list[i-1]:= list[i]; list[i]:= swap;
     i-:=1;
     IF i=LWB list THEN i:=j; j+:=1 FI
   FI
 OD;
 list

END;

PROC gnome sort = ([]SORTSTRUCT seq)[]SORTSTRUCT:

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

[]SORTSTRUCT char array data = "big fjords vex quick waltz nymph"; print((gnome sort(char array data), new line))</lang> Output:

     abcdefghiijklmnopqrstuvwxyz

AutoHotkey

contributed by Laszlo on the ahk forum <lang AutoHotkey>MsgBox % GnomeSort("") MsgBox % GnomeSort("xxx") MsgBox % GnomeSort("3,2,1") MsgBox % GnomeSort("dog,000000,xx,cat,pile,abcde,1,cat,zz,xx,z")

GnomeSort(var) {  ; SORT COMMA SEPARATED LIST

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

}</lang>

AWK

AWK arrays can be passed as parameters, but not returned, so they are usually global.

This version includes the mark/resume optimization. It remembers where it was before backing up so that once an item is backed up to its proper place the process resumes from where it was before backing up.

<lang awk>#!/usr/bin/awk -f

BEGIN {

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

}

function gnomeSortD( i) {

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

}

function gnomeSortBackD(i, t) {

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

}

function showD(p, i) {

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

} </lang>

Example output:

Before: 3 4 1 -8.4 7.2 4 1 1.2 
Sorted: -8.4 1 1 1.2 3 4 4 7.2

BASIC

Works with: QuickBasic version 4.5
Translation of: C

<lang qbasic>dim a(0 to n-1) as integer '...more code... sort: i = 1 j = 2

while(i < ubound(a) - lbound(a))

 if a(i-1) <= a(i) then
   i = j
   j = j + 1
 else 
   swap a(i-1), a(i)
   i = i - 1
   if i = 0 then
      i = j
      j = j + 1
   end if
 end if

wend</lang>

Batch File

Works with: Windows NT

<lang Batch File>@ECHO OFF SETLOCAL EnableExtensions EnableDelayedExpansion

GnomeSort.cmd in WinNT Batch using pseudo array.
Set the number of random elements to sort.

SET numElements=100

Decrement numElements for use in zero-based loops as in (0, 1, %numElements% - 1).

SET /A tmpElements=%numElements% - 1

Create array of random numbers and output to file.

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

GnomeSort
Initialize the pointers i-1, i, and j.

SET gs1=0 SET gs2=1 SET gs3=2

GS_Loop
Implementing a WHILE loop in WinNT batch using GOTO. It only executes
if the condition is true and continues until the condition is false.
First, display [i-1][j - 2] to the Title Bar.

SET /A gsTmp=%gs3% - 2 TITLE GnomeSort:[%gs1%][%gsTmp%] of %tmpElements%

...then start Main Loop. It's a direct implementation of the
pseudo code supplied by Rosetta Code. I had to add an additional
pointer to represent i-1, because of limitations in WinNT Batch.

IF %gs2% LSS %numElements% ( REM if i-1 <= i advance pointers to next unchecked element, then loop. IF !array[%gs1%]! LEQ !array[%gs2%]! ( SET /A gs1=%gs3% - 1 SET /A gs2=%gs3% SET /A gs3=%gs3% + 1 ) ELSE ( REM ... else swap i-1 and i, decrement pointers to check previous element, then loop. SET gsTmp=!array[%gs1%]! SET array[%gs1%]=!array[%gs2%]! SET array[%gs2%]=!gsTmp! SET /A gs1-=1 SET /A gs2-=1 REM if first element has been reached, set pointers to next unchecked element. IF !gs2! EQU 0 ( SET /A gs1=%gs3% - 1 SET /A gs2=%gs3% SET /A gs3=%gs3% + 1 ) ) GOTO :GS_Loop ) TITLE GnomeSort:[%gs1%][%gsTmp%] - Done!

write sorted elements out to file

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

ENDLOCAL EXIT /B 0</lang>

BBC BASIC

<lang BBCBASIC>DEF PROC_GnomeSort1(Size%) I%=2 J%=2 REPEAT

 IF data%(J%-1) <=data%(J%) THEN
   I%+=1
   J%=I%
 ELSE
   SWAP data%(J%-1),data%(J%)
   J%-=1
   IF J%=1 THEN
      I%+=1
      J%=I%
   ENDIF
 ENDIF

UNTIL I%>Size% ENDPROC</lang>

C

This algorithm sorts in place modifying the passed array (of n integer numbers). <lang c>void gnome_sort(int *a, int n) {

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

}</lang>

C#

Translation of: Java

<lang csharp>public static void gnomeSort(ref int[] a) {

   int i = 1;
   int j = 2;
   while (i < a.Length)
   {
       if (a[i - 1] <= a[i])
       {
           i = j;
           j++;
       }
       else
       {
           int tmp = a[i - 1];
           a[i - 1] = a[i];
           a[i] = tmp;
           i -= 1;
           if (i == 0)
           {
               i = 1;
               j = 2;
           }
       }
   }

}</lang>

C++

Uses C++11. Compile with

g++ -std=c++11 gnome.cpp

<lang cpp>#include <algorithm>

  1. include <iterator>
  2. include <iostream>

template<typename RandomAccessIterator> void gnome_sort(RandomAccessIterator begin, RandomAccessIterator end) {

 auto i = begin + 1;
 auto j = begin + 2;

 while (i < end) {
   if (!(*i < *(i - 1))) {
     i = j;
     ++j;
   } else {
     std::iter_swap(i - 1, i);
     --i;
     if (i == begin) {
       i = j;
       ++j;
     }
   }
 }

}

int main() {

 int a[] = {100, 2, 56, 200, -52, 3, 99, 33, 177, -199};
 gnome_sort(std::begin(a), std::end(a));
 copy(std::begin(a), std::end(a), std::ostream_iterator<int>(std::cout, " "));
 std::cout << "\n";

}</lang> Output:

-199 -52 2 3 33 56 99 100 177 200

Clojure

Translation of: Haskell

<lang clojure>(defn gnomesort

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

(println (gnomesort [3 1 4 1 5 9 2 6 5]))</lang>

COBOL

Procedure division stuff only. <lang COBOL> C-SORT SECTION.

      C-000.
          DISPLAY "SORT STARTING".
          SET WB-IX-1 TO 2.
          MOVE 1 TO WC-NEXT-POSN.
          PERFORM E-GNOME UNTIL WC-NEXT-POSN > WC-SIZE.
          DISPLAY "SORT FINISHED".
      C-999.
          EXIT.
      E-GNOME SECTION.
      E-000.
          IF WB-ENTRY(WB-IX-1 - 1) NOT > WB-ENTRY(WB-IX-1)
             ADD 1       TO WC-NEXT-POSN
             SET WB-IX-1 TO WC-NEXT-POSN
          ELSE
             MOVE WB-ENTRY(WB-IX-1 - 1) TO WC-TEMP
             MOVE WB-ENTRY(WB-IX-1)     TO WB-ENTRY(WB-IX-1 - 1)
             MOVE WC-TEMP               TO WB-ENTRY(WB-IX-1)
             SET WB-IX-1                DOWN BY 1
             IF WB-IX-1 = 1
                ADD 1       TO WC-NEXT-POSN
                SET WB-IX-1 TO WC-NEXT-POSN.
      E-999.
          EXIT.</lang>

Common Lisp

<lang lisp>(defun gnome-sort (array predicate &aux (length (length array)))

 (do ((position (min 1 length)))
     ((eql length position) array)
   (cond
    ((eql 0 position)
     (incf position))
    ((funcall predicate
              (aref array position)
              (aref array (1- position)))
     (rotatef (aref array position)
              (aref array (1- position)))
     (decf position))
    (t (incf position)))))</lang>

D

<lang d>import std.stdio, std.algorithm;

void gnomeSort(T)(T arr) {

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

}

void main() {

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

}</lang>

Delphi

Dynamic array is a 0-based array of variable length

Static array is an arbitrary-based array of fixed length <lang Delphi>program TestGnomeSort;

{$APPTYPE CONSOLE}

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

type

 TItem = Integer;   // declare ordinal type for array item

{$IFDEF DYNARRAY}

 TArray = array of TItem;          // dynamic array

{$ELSE}

 TArray = array[0..15] of TItem;   // static array

{$ENDIF}

procedure GnomeSort(var A: TArray); var

 Item: TItem;
 I, J: Integer;

begin

 I:= Low(A) + 1;
 J:= Low(A) + 2;
 while I <= High(A) do begin
   if A[I - 1] <= A[I] then begin
     I:= J;
     J:= J + 1;
   end
   else begin
     Item:= A[I - 1];
     A[I - 1]:= A[I];
     A[I]:= Item;
     I:= I - 1;
     if I = Low(A) then begin
       I:= J;
       J:= J + 1;
     end;
   end;
 end;

end;

var

 A: TArray;
 I: Integer;

begin {$IFDEF DYNARRAY}

 SetLength(A, 16);

{$ENDIF}

 for I:= Low(A) to High(A) do
   A[I]:= Random(100);
 for I:= Low(A) to High(A) do
   Write(A[I]:3);
 Writeln;
 GnomeSort(A);
 for I:= Low(A) to High(A) do
   Write(A[I]:3);
 Writeln;
 Readln;

end.</lang> Output:

  0  3 86 20 27 67 31 16 37 42  8 47  7 84  5 29
  0  3  5  7  8 16 20 27 29 31 37 42 47 67 84 86

DWScript

<lang delphi>procedure GnomeSort(a : array of Integer); var

  i, j : Integer;

begin

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

end;

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

Print('{'); for i := 0 to a.High do begin

  a[i] := i xor 5;
  Print(Format('%3d ', [a[i]]));

end; PrintLn('}');

GnomeSort(a);

Print('{'); for i := 0 to a.High do

  Print(Format('%3d ', [a[i]]));

PrintLn('}'); </lang> Ouput :

{  5   4   7   6   1   0   3   2  13  12  15  14   9   8  11  10 }
{  0   1   2   3   4   5   6   7   8   9  10  11  12  13  14  15 }

E

<lang e>def gnomeSort(array) {

   var size := array.size()
   var i := 1
   var j := 2
   while (i < size) {
       if (array[i-1] <= array[i]) {
           i := j
           j += 1
       } else {
           def t := array[i-1]
           array[i-1] := array[i]
           array[i] := t
           i -= 1
           if (i <=> 0) {
               i := j
               j += 1
           }
       }
   }

}</lang>

<lang e>? def a := [7,9,4,2,1,3,6,5,0,8].diverge()

  1. value: [7, 9, 4, 2, 1, 3, 6, 5, 0, 8].diverge()

? gnomeSort(a) ? a

  1. value: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9].diverge()</lang>

Eiffel

<lang Eiffel> class GNOME_SORT [G -> COMPARABLE]

feature

sort (ar: ARRAY [G]): ARRAY [G] -- Sorted array in ascending order. require array_not_void: ar /= Void local i, j: INTEGER ith: G do create Result.make_empty Result.deep_copy (ar) from i := 2 j := 3 until i > Result.count loop if Result [i - 1] <= Result [i] then i := j j := j + 1 else ith := Result [i - 1] Result [i - 1] := Result [i] Result [i] := ith i := i - 1 if i = 1 then i := j j := j + 1 end end end ensure Same_length: ar.count = Result.count Result_is_sorted: is_sorted (Result) end

feature {NONE}

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

end

</lang> Test: <lang Eiffel> class APPLICATION

create make

feature

make do test := <<7, 99, -7, 1, 0, 25, -10>> io.put_string ("unsorted:%N") across test as ar loop io.put_string (ar.item.out + "%T") end io.new_line io.put_string ("sorted:%N") create gnome test := gnome.sort (test) across test as ar loop io.put_string (ar.item.out + "%T") end end

test: ARRAY [INTEGER]

gnome: GNOME_SORT [INTEGER]

end

</lang>

Output:
Unsorted: 
7    99    -7    1    0    25    -10
Sorted: 
-7    -10    0    1    7    25    99

Elixir

Translation of: Erlang

<lang elixir>defmodule Sort do

 def gnome_sort(list) when length(list) <= 1, do: list
 def gnome_sort([h|t]), do: gnome_sort([h], t)
 
 defp gnome_sort(list, []), do: list
 defp gnome_sort([prev|p], [next|n]) when next > prev, do: gnome_sort(p, [next|[prev|n]])
 defp gnome_sort(p, [next|n]), do: gnome_sort([next|p], n)

end

IO.inspect Sort.gnome_sort([8,3,9,1,3,2,6])</lang>

Output:
[1, 2, 3, 3, 6, 8, 9]

Erlang

<lang Erlang>-module(gnome_sort). -export([gnome/1]).

gnome(L, []) -> L; gnome([Prev|P], [Next|N]) when Next > Prev -> gnome(P, [Next|[Prev|N]]); gnome(P, [Next|N]) -> gnome([Next|P], N). gnome([H|T]) -> gnome([H], T).</lang> <lang Erlang>Eshell V5.7.3 (abort with ^G) 1> c(gnome_sort). {ok,gnome_sort} 2> gnome_sort:gnome([8,3,9,1,3,2,6]). [1,2,3,3,6,8,9] 3> </lang>

Euphoria

<lang euphoria>function gnomeSort(sequence s)

   integer i,j
   object temp
   i = 1
   j = 2
   while i < length(s) do
       if compare(s[i], s[i+1]) <= 0 then
           i = j
           j += 1
       else
           temp = s[i]
           s[i] = s[i+1]
           s[i+1] = temp
           i -= 1
           if i = 0 then
               i = j
               j += 1
           end if
       end if
   end while
   return s

end function</lang>

F#

<lang fsharp>let inline gnomeSort (a: _ []) =

 let rec loop i j =
   if i < a.Length then
     if a.[i-1] <= a.[i] then loop j (j+1) else
       let t = a.[i-1]
       a.[i-1] <- a.[i]
       a.[i] <- t
       if i=1 then loop j (j+1) else loop (i-1) j
 loop 1 2</lang>

Fantom

<lang fantom> class Main {

 Int[] gnomesort (Int[] list)
 {
   i := 1
   j := 2
   while (i < list.size)
   {
     if (list[i-1] <= list[i])
     {
       i = j
       j += 1
     }
     else
     {
       list.swap(i-1, i)
       i -= 1
       if (i == 0)
       {
         i = j
         j += 1
       }
     }
   }
   return list
 }
 Void main ()
 {
   list := [4,1,5,8,2,1,5,7]
   echo ("" + list + " sorted is " + gnomesort (list))
 }

} </lang>

Output:

[4, 1, 5, 8, 2, 1, 5, 7] sorted is [1, 1, 2, 4, 5, 5, 7, 8]

Forth

<lang forth>defer precedes defer exchange

gnomesort ( a n)
 swap >r 1                   ( n c)
 begin                       ( n c)
   over over >               ( n c f)
 while                       ( n c)
   dup if                    ( n c)
     dup dup 1- over over r@ precedes
     if r@ exchange 1- else drop drop 1+ then
   else 1+ then              ( n c)
 repeat drop drop r> drop    ( --)

create example

 8 93 69 52 50 79 33 52 19 77 , , , , , , , , , ,
noname >r cells r@ + @ swap cells r> + @ swap < ; is precedes
noname >r cells r@ + swap cells r> + over @ over @ swap rot ! swap ! ; is exchange
.array 10 0 do example i cells + ? loop cr ;

.array example 10 gnomesort .array</lang> A slightly optimized version is presented below, where Gnome sort keeps track of its previous position. This reduces the number of iterations significantly. <lang forth>: gnomesort+ ( a n)

 swap >r 2 tuck 1-                    ( c2 n c1)
 begin                                ( c2 n c1)
   over over >                        ( c2 n c1 f)
 while                                ( c2 n c1)
   dup if                             ( c2 n c1)
     dup dup 1- over over r@ precedes
     if r@ exchange 1- else drop drop drop >r dup 1+ swap r> swap then
   else drop >r dup 1+ swap r> swap then
 repeat drop drop drop r> drop
( --)</lang>

Fortran

Works with: Fortran version 90 and later

<lang fortran>program example

 implicit none

 integer :: array(8) = (/ 2, 8, 6, 1, 3, 5, 4, 7 /)
 call Gnomesort(array)
 write(*,*) array

contains

subroutine Gnomesort(a)

 integer, intent(in out) :: a(:)
 integer :: i, j, temp
 i = 2
 j = 3
 do while (i <= size(a))
   if (a(i-1) <= a(i)) then
     i = j
     j = j + 1
   else
     temp = a(i-1)
     a(i-1) = a(i)
     a(i) = temp
     i = i -  1
     if (i == 1) then
       i = j
       j = j + 1
     end if
   end if
 end do

end subroutine Gnomesort

end program example</lang>

Go

<lang go>package main

import "fmt"

func main() {

   a := []int{170, 45, 75, -90, -802, 24, 2, 66}
   fmt.Println("before:", a)
   gnomeSort(a)
   fmt.Println("after: ", a)

}

func gnomeSort(a []int) {

   for i, j := 1, 2; i < len(a); {
       if a[i-1] > a[i] {
           a[i-1], a[i] = a[i], a[i-1]
           i--
           if i > 0 {
               continue
           }
       }
       i = j
       j++
   }

}</lang>

More generic version that sorts anything that implements sort.Interface: <lang go>package main

import (

 "sort"
 "fmt"

)

func main() {

   a := []int{170, 45, 75, -90, -802, 24, 2, 66}
   fmt.Println("before:", a)
   gnomeSort(sort.IntSlice(a))
   fmt.Println("after: ", a)

}

func gnomeSort(a sort.Interface) {

   for i, j := 1, 2; i < a.Len(); {
       if a.Less(i, i-1) {
           a.Swap(i-1, i)
           i--
           if i > 0 {
               continue
           }
       }
       i = j
       j++
   }

}</lang>

Groovy

Solution: <lang groovy>def makeSwap = { a, i, j = i+1 -> print "."; aj,i = ai,j }

def checkSwap = { list, i, j = i+1 -> [(list[i] > list[j])].find{ it }.each { makeSwap(list, i, j) } }

def gnomeSort = { input ->

   def swap = checkSwap.curry(input)
   def index = 1
   while (index < input.size()) {
       index += (swap(index-1) && index > 1) ? -1 : 1
   }
   input

}</lang>

Test: <lang groovy>println (gnomeSort([23,76,99,58,97,57,35,89,51,38,95,92,24,46,31,24,14,12,57,78,4])) println (gnomeSort([88,18,31,44,4,0,8,81,14,78,20,76,84,33,73,75,82,5,62,70,12,7,1]))</lang>

Output:

..............................................................................................................................................[4, 12, 14, 23, 24, 24, 31, 35, 38, 46, 51, 57, 57, 58, 76, 78, 89, 92, 95, 97, 99]
.........................................................................................................................................[0, 1, 4, 5, 7, 8, 12, 14, 18, 20, 31, 33, 44, 62, 70, 73, 75, 76, 78, 81, 82, 84, 88]

Haskell

<lang haskell>gnomeSort [] = [] gnomeSort (x:xs) = gs [x] xs

   where

gs vv@(v:vs) (w:ws) | v<=w = gs (w:vv) ws | otherwise = gs vs (w:v:ws) gs [] (y:ys) = gs [y] ys gs xs [] = reverse xs -- keeping the first argument of gs in reverse order avoids the deterioration into cubic behaviour </lang>

Io

Naive version: <lang io>List do(

   gnomeSortInPlace := method(
       idx := 1
       while(idx <= size,
           if(idx == 0 or at(idx) > at(idx - 1)) then(
               idx = idx + 1
           ) else(
               swapIndices(idx, idx - 1)
               idx = idx - 1
           )
       )
   self)

)

lst := list(5, -1, -4, 2, 9) lst gnomeSortInPlace println # ==> list(-4, -1, 2, 5, 9)</lang>

Optimized version, storing the position before traversing back towards the begining of the list (Wikipedia) <lang io>List do(

   gnomeSortInPlace := method(
       idx1 := 1
       idx2 := 2
       while(idx1 <= size,
           if(idx1 == 0 or at(idx1) > at(idx1 - 1)) then(
               idx1 = idx2
               idx2 = idx2 + 1
           ) else(
               swapIndices(idx1, idx1 - 1)
               idx1 = idx1 - 1
           )
       )
   self)

)

lst := list(5, -1, -4, 2, 9) lst gnomeSortInPlace println # ==> list(-4, -1, 2, 5, 9)</lang>

Icon and Unicon

<lang Icon>procedure main() #: demonstrate various ways to sort a list and string

  demosort(gnomesort,[3, 14, 1, 5, 9, 2, 6, 3],"qwerty")

end

procedure gnomesort(X,op) #: return sorted list local i,j

  op := sortop(op,X)                # select how and what we sort
  j := (i := 2) + 1                 # translation of pseudo code
  while i <= *X do {
     if op(X[i],X[i-1]) then {
        X[i] :=: X[i -:= 1]
        if i > 1 then next
     }
     j := (i := j) + 1
  }
  return X        

end</lang>

Note: This example relies on the supporting procedures 'sortop', and 'demosort' in Bubble Sort. The full demosort exercises the named sort of a list with op = "numeric", "string", ">>" (lexically gt, descending),">" (numerically gt, descending), a custom comparator, and also a string.

Abbreviated sample output:

Sorting Demo using procedure gnomesort
  on list : [ 3 14 1 5 9 2 6 3 ]
    with op = &null:         [ 1 2 3 3 5 6 9 14 ]   (0 ms)
  ...
  on string : "qwerty"
    with op = &null:         "eqrtwy"   (0 ms)

J

Generally, this task should be accomplished in J using /:~. Here we take an approach that's more comparable with the other examples on this page.

<lang J>position=: 0 {.@I.@, [ swap=: ] A.~ *@position * #@[ !@- <:@position gnome=: swap~ 2 >/\ ] gnomes=: gnome^:_</lang>

Note 1: this implementation of swap is actually rather silly, and will not work on long lists. A better implementation would be:<lang J>swap=: position (] {~ _1 0 + [)`(0 _1 + [)`]}^:(*@[) ]</lang>

Note 2: this implementation only works for domains where > is defined (in J, "greater than" only works on numbers). To work around this issue, you could define:<lang J>gt=: -.@(-: /:~)@,&< gnome=: swap~ 2 gt/\ ]</lang>

Note 3: this implementation does not return intermediate results. If you want them, you could use<lang J>gnomeps=: gnome^:a:</lang>

Note 4: gnomeps just shows intermediate results and does not show the gnome's position. You can extract the gnome's position using an expression such as<lang J>2 ~:/\ gnomeps</lang>.

Java

Translation of: C

<lang java>public static void gnomeSort(int[] a) {

 int i=1;
 int j=2;

 while(i < a.length) {
   if ( a[i-1] <= a[i] ) {
     i = j; j++;
   } else {
     int tmp = a[i-1];
     a[i-1] = a[i];
     a[i--] = tmp;
     i = (i==0) ? j++ : i;
   }
 }

}</lang>

JavaScript

<lang javascript>function gnomeSort(a) {

   function moveBack(i) {
       for( ; i > 0 && a[i-1] > a[i]; i--) {
           var t = a[i];
           a[i] = a[i-1];
           a[i-1] = t;
       }
   }
   for (var i = 1; i < a.length; i++) {
       if (a[i-1] > a[i]) moveBack(i);
   }
   return a;

}</lang>

jq

Works with: jq version 1.4

This implementation adheres to the specification. The array to be sorted, however, can be any JSON array. <lang jq># 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;
  1. input: an array

def gnomeSort:

 def swap(i;j): .[i] as $x | .[i]=.[j] | .[j]=$x;
 length as $length
 # state: [i, j, ary]
 | [1, 2, .] 
 | do_until( .[0] >= $length;
             .[0] as $i | .[1] as $j
             | .[2]
             # for descending sort, use >= for comparison
             | if .[$i-1] <= .[$i] then [$j, $j + 1, .]
               else swap( $i-1; $i)
               | ($i - 1) as $i
               | if $i == 0 then [$j, $j + 1, .]
                 else [$i, $j, .]
                 end
               end )
 | .[2];</lang>

Example: <lang jq>[(2|sqrt), [1], null, 1, 0.5, 2, 1, -3, {"a": "A"}] | gnomeSort</lang>

Output:

<lang sh>$ jq -M -n -f Gnome_sort.jq [

 null,
 -3,
 0.5,
 1,
 1,
 1.4142135623730951,
 2,
 [
   1
 ],
 {
   "a": "A"
 }

]</lang>

Julia

Julia is one-indexed so the implementation differs slightly from the pseudocode.

<lang Julia>function gnomesort(A::AbstractVector)

   i = 1
   j = 2
   while i < length(A)
       if A[i] <= A[i + 1]
           i = j
           j += 1
       else
           A[i], A[i + 1] = A[i + 1], A[i]
           i -= 1
           if i == 0
               i = j
               j += 1
           end
       end
   end
   A

end

A = randcycle(20) println("unsorted: ", A) println("sorted: ", gnomesort(A))</lang>

Output:
unsorted: [13,15,6,11,3,19,17,20,2,18,9,14,8,10,16,7,12,1,4,5]
sorted:   [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20]

Lua

Keep in mind that Lua arrays initial index is 1. <lang lua>function gnomeSort(a)

   local i, j = 2, 3
   while i < #a do
       if a[i-1] <= a[i] then
           i = j
           j = j + 1
       else
           a[i-1], a[i] = a[i], a[i-1] -- swap
           i = i - 1
           if i == 1 then -- 1 instead of 0
               i = j
               j = j + 1
           end
       end
   end

end</lang> Example: <lang lua>list = { 5, 6, 1, 2, 9, 14, 2, 15, 6, 7, 8, 97 } gnomeSort(list) for i, j in pairs(list) do

   print(j)

end</lang>

Mathematica

<lang Mathematica>gnomeSort[list_]:=Module[{i=2,j=3}, While[ i<=Lengthlist, If[ listi-1<=listi,

i=j; j++;,
listi-1;;i=listi;;i-1;i--;];

If[i==1,i=j;j++;] ]]</lang>

MATLAB / Octave

<lang MATLAB>function list = gnomeSort(list)

   i = 2;
   j = 3;
   
   while i <= numel(list)
      
       if list(i-1) <= list(i)
           i = j;
           j = j+1;
       else
           list([i-1 i]) = list([i i-1]); %Swap
           i = i-1;
           if i == 1
               i = j;
               j = j+1;
           end
       end %if
       
   end %while

end %gnomeSort</lang>

Sample Usage: <lang MATLAB>>> gnomeSort([4 3 1 5 6 2])

ans =

    1     2     3     4     5     6</lang>

MAXScript

<lang MAXScript>fn gnomeSort arr = ( local i = 2 local j = 3 while i <= arr.count do ( if arr[i-1] <= arr[i] then ( i = j j += 1 ) else ( swap arr[i-1] arr[i] i -= 1 if i == 1 then ( i = j j += 1 ) ) ) return arr )</lang> Output: <lang MAXScript> a = for i in 1 to 10 collect random 1 20

  1. (20, 10, 16, 2, 19, 12, 11, 3, 5, 16)

gnomesort a

  1. (2, 3, 5, 10, 11, 12, 16, 16, 19, 20)

</lang>

Metafont

<lang metafont>def gnomesort(suffix v)(expr n) = begingroup save i, j, t;

 i := 1; j := 2;
 forever: exitif not (i < n);
   if v[i-1] <= v[i]:
     i := j; j := j + 1;
   else:
     t := v[i-1];
     v[i-1] := v[i];
     v[i] := t;
     i := i - 1;
     i := if i=0: j; j := j + 1 else: i fi;
   fi
 endfor

endgroup enddef;</lang>

<lang metafont>numeric a[]; for i = 0 upto 9: a[i] := uniformdeviate(40); message decimal a[i]; endfor message char10;

gnomesort(a, 10); for i = 0 upto 9: message decimal a[i]; endfor end</lang>

NetRexx

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

import java.util.List

i1 = ArrayList(Arrays.asList([Integer(3), Integer(3), Integer(1), Integer(2), Integer(4), Integer(3), Integer(5), Integer(6)])) say i1.toString say gnomeSort(i1).toString

return

method isTrue public constant binary returns boolean

 return 1 == 1

method isFalse public constant binary returns boolean

 return \isTrue

method gnomeSort(a = String[], sAsc = isTrue) public constant binary returns String[]

 rl = String[a.length]
 al = List gnomeSort(Arrays.asList(a), sAsc)
 al.toArray(rl)
 return rl

method gnomeSort(a = List, sAsc = isTrue) public constant binary returns ArrayList

 sDsc = \sAsc -- Ascending/descending switches
 ra = ArrayList(a)
 i_ = 1
 j_ = 2
 loop label i_ while i_ < ra.size
   ctx = (Comparable ra.get(i_ - 1)).compareTo(Comparable ra.get(i_))
   if (sAsc & ctx <= 0) | (sDsc & ctx >= 0) then do
     i_ = j_
     j_ = j_ + 1
     end
   else do
     swap = ra.get(i_)
     ra.set(i_, ra.get(i_ - 1))
     ra.set(i_ - 1, swap)
     i_ = i_ - 1
     if i_ = 0 then do
       i_ = j_
       j_ = j_ + 1
       end
     end
   end i_
 return ra

</lang>

Output
[3, 3, 1, 2, 4, 3, 5, 6]
[1, 2, 3, 3, 3, 4, 5, 6]

Nim

<lang nim>proc gnomeSort[T](a: var openarray[T]) =

 var
   n = a.len
   i = 1
   j = 2
 while i < n:
   if a[i-1] > a[i]:
     swap a[i-1], a[i]
     dec i
     if i > 0: continue
   i = j
   inc j

var a = @[4, 65, 2, -31, 0, 99, 2, 83, 782] gnomeSort a echo a</lang> Output:

@[-31, 0, 2, 2, 4, 65, 83, 99, 782]

Objeck

Translation of: C

<lang objeck> function : GnomeSort(a : Int[]) {

 i := 1;
 j := 2;

 

 while(i < a->Size()) {
   if (a[i-1] <= a[i]) {
     i := j; 
     j += 1;
   } 
   else {
     tmp := a[i-1];
     a[i-1] := a[i];
     a[i] := tmp;
     i -= 1;
     if(i = 0) {
       i := j;
       j += 1;
     };
   };
 };

} </lang>

OCaml

from the toplevel: <lang ocaml># let gnome_sort a =

   let i = ref 1 
   and j = ref 2 in
   while !i < Array.length a do
     if a.(!i-1) <= a.(!i) then
     begin
       i := !j;
       j := !j + 1;
     end else begin
       swap a (!i-1) (!i);
       i := !i - 1;
       if !i = 0 then begin
         i := !j;
         j := !j + 1;
       end;
     end;
   done;
 ;;

val gnome_sort : 'a array -> unit = <fun>

  1. let a = [| 7; 9; 4; 2; 1; 3; 6; 5; 0; 8; |] ;;

val a : int array = [|7; 9; 4; 2; 1; 3; 6; 5; 0; 8|]

  1. gnome_sort a ;;

- : unit = ()

  1. a ;;

- : int array = [|0; 1; 2; 3; 4; 5; 6; 7; 8; 9|]</lang>

Octave

<lang octave>function s = gnomesort(v)

 i = 2; j = 3;
 while ( i <= length(v) )
   if ( v(i-1) <= v(i) )
     i = j;
     j++;
   else
     t = v(i-1);
     v(i-1) = v(i);
     v(i) = t;
     i--;
     if ( i == 1 )

i = j; j++;

     endif
   endif
 endwhile
 s = v;

endfunction</lang>

<lang octave>v = [7, 9, 4, 2, 1, 3, 6, 5, 0, 8]; disp(gnomesort(v));</lang>

ooRexx

version 1

Translation of: NetRexx

<lang ooRexx>/* Rexx */

call demo return exit

-- ----------------------------------------------------------------------------- -- Gnome sort implementation -- -----------------------------------------------------------------------------

routine gnomeSort
 use arg ra, sAsc = 
 if sAsc =  then sAsc = isTrue()
 sDsc = \sAsc -- Ascending/descending switches
 i_ = 1
 j_ = 2
 loop label i_ while i_ < ra~items()
   ctx = (ra~get(i_ - 1))~compareTo(ra~get(i_))
   if (sAsc & ctx <= 0) | (sDsc & ctx >= 0) then do
     i_ = j_
     j_ = j_ + 1
     end
   else do
     swap = ra~get(i_)
     ra~set(i_, ra~get(i_ - 1))
     ra~set(i_ - 1, swap)
     i_ = i_ - 1
     if i_ = 0 then do
       i_ = j_
       j_ = j_ + 1
       end
     end
   end i_
 return ra

-- ----------------------------------------------------------------------------- -- Demonstrate the implementation -- -----------------------------------------------------------------------------

routine demo
 placesList = .nlist~of( -
     "UK  London",     "US  New York",   "US  Boston",     "US  Washington" -
   , "UK  Washington", "US  Birmingham", "UK  Birmingham", "UK  Boston"     -
 )
 lists = .nlist~of( -
     placesList -
   , gnomeSort(placesList~copy()) -
 )
 loop ln = 0 to lists~items() - 1
   cl = lists[ln]
   loop ct = 0 to cl~items() - 1
     say right(ct + 1, 3)':' cl[ct]
     end ct
   say
   end ln
 i_.0 = 3
 i_.1 = .nlist~of(3, 3, 1, 2, 4, 3, 5, 6)
 i_.2 = gnomeSort(i_.1~copy(), isTrue())
 i_.3 = gnomeSort(i_.1~copy(), isFalse())
 loop s_ = 1 to i_.0
   ss = 
   loop x_ = 0 to i_.s_~items() - 1
     ss ||= right(i_.s_~get(x_), 3)' '
     end x_
   say strip(ss, 'T')
   end s_
 return

-- -----------------------------------------------------------------------------

routine isTrue
 return 1 == 1

-- -----------------------------------------------------------------------------

routine isFalse
 return \isTrue()

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

</lang> Output:

  1: UK  London
  2: US  New York
  3: US  Boston
  4: US  Washington
  5: UK  Washington
  6: US  Birmingham
  7: UK  Birmingham
  8: UK  Boston

  1: UK  Birmingham
  2: UK  Boston
  3: UK  London
  4: UK  Washington
  5: US  Birmingham
  6: US  Boston
  7: US  New York
  8: US  Washington

  3   3   1   2   4   3   5   6
  1   2   3   3   3   4   5   6
  6   5   4   3   3   3   2   1

version 2

Translation of: REXX

<lang oorexx>/* REXX ---------------------------------------------------------------

  • 28.06.2014 Walter Pachl
  • 30.06.2014 corrected in sync with REXX version 2
  • --------------------------------------------------------------------*/
 Call gen                         /* generate the array elements.   */
 Call show 'before sort'          /* show  "before"  array elements.*/
 Call gnomeSort x                 /* invoke the infamous gnome sort.*/
 Call show ' after sort'          /* show  "after"   array elements.*/
 Exit                             /* done.                          */

gnomesort: Procedure

 Use Arg x
 n=x~items
 k=2
 Do j=3 While k<=n
   km=k-1
   If x[km]<=x[k] Then
     k=j
   Else Do
     t=x[km]; x[km]=x[k]; x[k]=t  /* swap two entries in the array. */
     k=k-1
     If k==1 Then
       k=j
     Else
       j=j-1
     End
   End
 Return

gen:

 x=.array~of('---the seven virtues---','=======================',,
             'Faith','Hope','Charity  [Love]','Fortitude','  Justice',,
             'Prudence','Temperance')
 Return

show:

 Say arg(1)
 Do i=1 To x~items
   Say 'element' right(i,2) x[i]
   End
 Return</lang>

output Same as REXX version 2

Oz

Translation of: Haskell

<lang oz>declare

 fun {GnomeSort Xs}
    case Xs of nil then nil
    [] X|Xr then {Loop [X] Xr}
    end
 end
 fun {Loop Vs Ws}
    case [Vs Ws]
    of [V|_  W|Wr] andthen V =< W then {Loop W|Vs Wr}
    [] [V|Vr W|Wr] then {Loop Vr W|V|Wr}
    [] [nil  W|Wr] then {Loop [W] Wr}
    [] [Vs   nil ] then {Reverse Vs}
    end
 end

in

 {Show {GnomeSort [3 1 4 1 5 9 2 6 5]}}</lang>

PARI/GP

<lang parigp>gnomeSort(v)={

 my(i=2,j=3,n=#v,t);
 while(i<=n,
   if(v[i-1]>v[i],
     t=v[i];
     v[i]=v[i-1];
     v[i--]=t;
     if(i==1, i=j; j++);
   ,
     i=j;
     j++
   )
 );
 v

};</lang>

Pascal

<lang pascal>procedure gnomesort(var arr : Array of Integer; size : Integer); var

  i, j, t	: Integer;

begin

  i := 1;
  j := 2;
  while i < size do begin
     if arr[i-1] <= arr[i] then
     begin

i := j; j := j + 1

     end
     else begin

t := arr[i-1]; arr[i-1] := arr[i]; arr[i] := t; i := i - 1; if i = 0 then begin i := j; j := j + 1 end

     end
  end;

end;</lang>

Perl

<lang perl>use strict;

sub gnome_sort {

   my @a = @_;
   my $size = scalar(@a);
   my $i = 1;
   my $j = 2;
   while($i < $size) {

if ( $a[$i-1] <= $a[$i] ) { $i = $j; $j++; } else { @a[$i, $i-1] = @a[$i-1, $i]; $i--; if ($i == 0) { $i = $j; $j++; } }

   }
   return @a;

}</lang>

<lang perl>my @arr = ( 10, 9, 8, 5, 2, 1, 1, 0, 50, -2 ); print "$_\n" foreach gnome_sort( @arr );</lang>

Perl 6

Works with: Rakudo version #24 "Seoul"

<lang perl6>sub gnome_sort (@a is rw) {

   my ($i, $j) = 1, 2;
   while $i < @a {
       if @a[$i - 1] <= @a[$i] {
           ($i, $j) = $j, $j + 1;
       }
       else {
           (@a[$i - 1], @a[$i]) = @a[$i], @a[$i - 1];
           --$i or ($i, $j) = $j, $j + 1;
       }
   }

}</lang>

PHP

<lang php>function gnomeSort($arr){ $i = 1; $j = 2; while($i < count($arr)){ if ($arr[$i-1] <= $arr[$i]){ $i = $j; $j++; }else{ list($arr[$i],$arr[$i-1]) = array($arr[$i-1],$arr[$i]); $i--; if($i == 0){ $i = $j; $j++; } } } return $arr; } $arr = array(3,1,6,2,9,4,7,8,5); echo implode(',',gnomeSort($arr));</lang>

1,2,3,4,5,6,7,8,9

PicoLisp

<lang PicoLisp>(de gnomeSort (Lst)

  (let J (cdr Lst)
     (for (I Lst (cdr I))
        (if (>= (cadr I) (car I))
           (setq I J  J (cdr J))
           (xchg I (cdr I))
           (if (== I Lst)
              (setq I J  J (cdr J))
              (setq I (prior I Lst)) ) ) ) )
  Lst )</lang>

PowerBASIC

The BASIC example will work as-is if the array is declared in the same function as the sort. This example doesn't require that, but forces you to know your data type beforehand.

<lang powerbasic>SUB gnomeSort (a() AS LONG)

   DIM i AS LONG, j AS LONG
   i = 1
   j = 2
   WHILE (i < UBOUND(a) + 1)
       IF (a(i - 1) <= a(i)) THEN
           i = j
           INCR j
       ELSE
           SWAP a(i - 1), a(i)
           DECR i
           IF 0 = i THEN
               i = j
               INCR j
           END IF
       END IF
   WEND

END SUB

FUNCTION PBMAIN () AS LONG

   DIM n(9) AS LONG, x AS LONG
   RANDOMIZE TIMER
   OPEN "output.txt" FOR OUTPUT AS 1
   FOR x = 0 TO 9
       n(x) = INT(RND * 9999)
       PRINT #1, n(x); ",";
   NEXT
   PRINT #1,
   gnomeSort n()
   FOR x = 0 TO 9
       PRINT #1, n(x); ",";
   NEXT
   CLOSE 1

END FUNCTION</lang>

Sample output:

7426 , 7887 , 8297 , 2671 , 7586 , 7160 , 1195 , 665 , 9352 , 6199 ,
665 , 1195 , 2671 , 6199 , 7160 , 7426 , 7586 , 7887 , 8297 , 9352 ,

PureBasic

<lang PureBasic>Procedure GnomeSort(Array a(1))

 Protected Size = ArraySize(a()) + 1
 Protected i = 1, j = 2
  
 While i < Size
   If a(i - 1) <= a(i)
     ;for descending SORT, use >= for comparison
     i = j
     j + 1 
   Else
     Swap a(i - 1), a(i)
     i - 1
     If i = 0
       i = j
       j + 1
     EndIf
   EndIf
 Wend

EndProcedure</lang>

Python

<lang python>>>> def gnomesort(a): i,j,size = 1,2,len(a) while i < size: if a[i-1] <= a[i]: i,j = j, j+1 else: a[i-1],a[i] = a[i],a[i-1] i -= 1 if i == 0: i,j = j, j+1 return a

>>> gnomesort([3,4,2,5,1,6]) [1, 2, 3, 4, 5, 6] >>></lang>

R

<lang r>gnomesort <- function(x) {

  i <- 1
  j <- 1
  while(i < length(x))
  {
     if(x[i] <= x[i+1])
     {
        i <- j
        j <- j+1
     } else
     {
        temp <- x[i]
        x[i] <- x[i+1]
        x[i+1]  <- temp
        i <- i - 1
        if(i == 0)
        {
           i <- j
           j <- j+1
        } 
     }
  }
  x

} gnomesort(c(4, 65, 2, -31, 0, 99, 83, 782, 1)) # -31 0 1 2 4 65 83 99 782</lang>

Racket

<lang racket>

  1. lang racket
Translation of the pseudo code

(define (gnome-sort1 a <=?)

 (define size (vector-length a))
 (define (swap i j)
   (define t (vector-ref a i))
   (vector-set! a i (vector-ref a j))
   (vector-set! a j t))
 (let loop ([i 1] [j 2])
   (when (< i size)
     (if (<=? (vector-ref a (sub1 i)) (vector-ref a i))
       (loop j (add1 j))
       (begin (swap (sub1 i) i)
              (let ([i (sub1 i)])
                (if (zero? i)
                  (loop j (add1 j))
                  (loop i j)))))))
 a)

(gnome-sort1 (vector 3 2 1 4 5 6) <=)

a functional version, roughly like the Scheme entry

(define (gnome-sort2 l <=?)

 (match l
   [(list) l]
   [(list x xs ...)
    (let loop ([x `((,x) . ,xs)])
      (match x
        [`(,ps) ps]
        [`((,p . ,ps) ,n . ,ns)
         (loop (cond [(<=? n p)  `((,n ,p . ,ps) . ,ns)]
                     [(null? ps) `((,n) ,p . ,ns)]
                     [else       `(,ps ,n ,p . ,ns)]))]))]))

(gnome-sort2 '(3 2 1 4 5 6) <=) </lang>

Rascal

<lang rascal>import List;

public list[int] gnomeSort(a){ i = 1; j = 2; while(i < size(a)){ if(a[i-1] <= a[i]){ i = j; j += 1;} else{ temp = a[i-1]; a[i-1] = a[i]; a[i] = temp; i = i - 1; if(i == 0){ i = j; j += 1;}}} return a; }</lang>

An example output:

<lang rascal>gnomeSort([4, 65, 2, -31, 0, 99, 83, 782, 1]) list[int]: [-31,0,1,2,4,65,83,99,782]</lang>

REXX

version 1

This REXX version used a one-based stemmed array (instead of a zero-based array).

This version allows the use of a null valued element in the array as a value. <lang rexx>/*REXX program sorts a stemmed array using the gnome-sort algorithm.*/ call gen@ /*generate the @. array elements.*/ call show@ 'before sort' /*show "before" array elements.*/ call gnomeSort # /*invoke the infamous gnome sort.*/ call show@ ' after sort' /*show "after" array elements.*/ exit /*stick a fork in it, we're done.*/ /*──────────────────────────────────GNOMESORT subroutine────────────────*/ gnomeSort: procedure expose @.; parse arg n; k=2 /*n=num items.*/

       do j=3  while k<=n;                     km=k-1    /*KM=prev item*/
       if @.km<<=@.k  then do;  k=j;  iterate;  end      /*OK so far···*/
       _=@.km;  @.km=@.k;  @.k=_      /*swap 2 entries in the @. array.*/
       k=k-1;   if k==1  then k=j;  else j=j-1           /*test index 1*/
       end    /*j*/                   /* [↑]   perform gnome sort on @.*/

return /*──────────────────────────────────GEN@ subroutine─────────────────────*/ gen@: !=... 'deadbeef'x ...; @.=! /*default none-value; allows null*/ @.1 = '---the seven virtues---' /* [↓] indent the seven virtues.*/ @.2 = '=======================' ; @.6 = 'Fortitude' @.3 = 'Faith'  ; @.7 = 'Justice' @.4 = 'Hope'  ; @.8 = 'Prudence' @.5 = 'Charity [Love]'  ; @.9 = 'Temperance'

          do #=1  while @.#\==!; end  /*find the # of items in @ array.*/
  1. =#-1 /*adjust the numer of items by 1.*/

return /*──────────────────────────────────SHOW@ subroutine────────────────────*/ show@: do j=1 for # /* [↓] display all items for @. */

                  say '      element'  right(j,length(#))  arg(1)":"  @.j
                  end   /*j*/         /* [↑]   right justify the J num.*/

say copies('■',60) /*show a separator line that fits*/ return</lang> output

      element 1 before sort: ---the seven virtues---
      element 2 before sort: =======================
      element 3 before sort: Faith
      element 4 before sort: Hope
      element 5 before sort: Charity  [Love]
      element 6 before sort: Fortitude
      element 7 before sort: Justice
      element 8 before sort: Prudence
      element 9 before sort: Temperance
■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
      element 1  after sort: ---the seven virtues---
      element 2  after sort: =======================
      element 3  after sort: Charity  [Love]
      element 4  after sort: Faith
      element 5  after sort: Fortitude
      element 6  after sort: Hope
      element 7  after sort: Justice
      element 8  after sort: Prudence
      element 9  after sort: Temperance
■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■

version 2

<lang rexx>/* REXX ---------------------------------------------------------------

  • 28.06.2014 Walter Pachl cf ooRexx version 2
  • only style changes (reformatting) and adapt for ooRexx compatibility
  • NOTE that leading blanks are ignored in the comparison (' Justice')
  • unless strict comparison is used (i.e., 'If x.km<<=x.k Then')
  • 30.06.2014 WP added the missing else clause
  • --------------------------------------------------------------------*/
                                  /* generate the array elements.   */
 Call gen '---the seven virtues---','=======================',,
          'Faith','Hope','Charity  [Love]','Fortitude','  Justice',,
          'Prudence','Temperance'
 Call show 'before sort'          /* show  "before"  array elements.*/
 Call gnomeSort                   /* invoke the infamous gnome sort.*/
 Call show ' after sort'          /* show  "after"   array elements.*/
 Exit                             /* done.                          */

gnomesort: Procedure Expose x.

 k=2
 Do j=3 While k<=x.0
   km=k-1
   If x.km<=x.k Then
     k=j
   Else Do
     t=x.km; x.km=x.k; x.k=t      /* swap two entries in the array. */
     k=k-1
     If k==1 Then
       k=j
     Else
       j=j-1
     End
   End
 Return

gen: Procedure Expose x.

 Do i=1 To arg()
   x.i=arg(i)
   End
 x.0=arg()
 Return

show: Procedure Expose x.

 Say arg(1)
 Do i=1 To x.0
   Say 'element' right(i,2) x.i
   End
 Return

</lang> output

before sort
element  1 ---the seven virtues---
element  2 =======================
element  3 Faith
element  4 Hope
element  5 Charity  [Love]
element  6 Fortitude
element  7   Justice
element  8 Prudence
element  9 Temperance
 after sort
element  1 ---the seven virtues---
element  2 =======================
element  3 Charity  [Love]
element  4 Faith
element  5 Fortitude
element  6 Hope
element  7   Justice
element  8 Prudence
element  9 Temperance

Ruby

<lang ruby>class Array

 def gnomesort!
   i, j = 1, 2
   while i < length
     if self[i-1] <= self[i]
       i, j = j, j+1
     else
       self[i-1], self[i] = self[i], self[i-1]
       i -= 1
       if i == 0
         i, j = j, j+1
       end
     end
   end
   self
 end

end ary = [7,6,5,9,8,4,3,1,2,0] ary.gnomesort!

  1. => [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]</lang>

Scheme

<lang scheme>

supply comparison function, which returns true if first and second
arguments are in order or equal.

(define (gnome-sort-compar in-order input-list)

 (let gnome ((p (list (car input-list)))
             (n (cdr input-list)))
   (if (null? n) ; no more flowerpots?
       p ; we're done
       (let ((prev-pot (car p))
             (next-pot (car n)))
         (if (in-order next-pot prev-pot)
             ; if the pots are in order, step forwards.
             ; otherwise, exchange the two pots, and step backwards.
             (gnome (cons next-pot p) ; Prev list grows
                    (cdr n)) ; Next list shorter by one
             (if (null? (cdr p)) ; are we at the beginning?
                 (gnome                    ; if so, we can't step back
                  (list next-pot)          ; simply exchange the pots without
                  (cons prev-pot (cdr n))) ; changing lengths of lists
                 (gnome
                  (cdr p) ; Prev list shorter by one
                  (cons next-pot (cons prev-pot (cdr n))))))))))

</lang>

#;1> (gnome-sort-compar <= '(98 36 2 78 5 81 32 90 73 21 94 28 53 25 10 99))
(2 5 10 21 25 28 32 36 53 73 78 81 90 94 98 99)

Sidef

<lang ruby>class Array {

   method gnomesort {
       var (i=1, j=2);
       var len = self.len;
       while (i < len) {
           if (self[i-1] <= self[i]) {
               [j, j+1] » (\i, \j);
           }
           else {
               [self[i], self[i-1]] » (\self[i-1], \self[i]);
               if (--i == 0) {
                   [j, j+1] » (\i, \j);
               }
           }
       };
       return self;
   }

}

var ary = [7,6,5,9,8,4,3,1,2,0]; say ary.gnomesort.dump;</lang>

Output:
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

Smalltalk

<lang smalltalk>Smalltalk at: #gnomesort put: nil.

"Utility" OrderedCollection extend [

 swap: a with: b [ |t|
     t := self at: a.
     self at: a put: b.
     self at: b put: t
 ]

].

"Gnome sort as block closure" gnomesort := [ :c |

 |i j|
 i := 2. j := 3.
 [ i <= (c size) ]
   whileTrue: [
      (c at: (i-1)) <= (c at: i)
         ifTrue: [
            i := j copy.
            j := j + 1.
         ]
         ifFalse: [
            c swap: (i-1) with: i.
            i := i - 1.
            i == 1
              ifTrue: [
                 i := j copy.
                 j := j + 1
              ]
         ]
   ]

].</lang>

Testing

<lang smalltalk>|r o| r := Random new. o := OrderedCollection new.

1 to: 10 do: [ :i | o add: (r between: 0 and: 50) ].

gnomesort value: o.

1 to: 10 do: [ :i | (o at: i) displayNl ].</lang>

Tcl

Library: Tcllib (Package: struct::list)

<lang tcl>package require Tcl 8.5 package require struct::list

proc gnomesort {a} {

   set i 1
   set j 2
   set size [llength $a]
   while {$i < $size} {
       if {[lindex $a [expr {$i - 1}]] <= [lindex $a $i]} {
           set i $j
           incr j
       } else {
           struct::list swap a [expr {$i - 1}] $i
           incr i -1
           if {$i == 0} {
               set i $j
               incr j
           }
       }
   }
   return $a

}

puts [gnomesort {8 6 4 2 1 3 5 7 9}] ;# => 1 2 3 4 5 6 7 8 9</lang>

TI-83 BASIC

Store input into L1, run prgmSORTGNOM, output will be in L2.

:1→P
:L1→L2
:While P<dim(L2)
:If PP=1
:Then
:P+1→P
:Else
:If L2(P)≥L2(P-1)
:Then
:P+1→P
:Else
:L2(P)→Q
:L2(P-1)→L2(P)
:Q→L2(P-1)
:P-1→P
:End
:End
:End
:If L2(dim(L2))<L2(dim(L2)-1)
:Then
:L2(dim(L2))→Q
:L2(dim(L2)-1)→L2(dim(L2))
:Q→L2(dim(L2)-1)
:End
:DelVar P
:DelVar Q
:Return

VBScript

Implementation

<lang vb>function gnomeSort( a ) dim i dim j i = 1 j = 2 do while i < ubound( a ) + 1 if a(i-1) <= a(i) then i = j j = j + 1 else swap a(i-1), a(i) i = i - 1 if i = 0 then i = j j = j + 1 end if end if loop gnomeSort = a end function

sub swap( byref x, byref y ) dim temp temp = x x = y y = temp end sub</lang>

Invocation

<lang vb>dim a dim b

a = array( "zanzibar", "aardvark","ampicillin","zulu","gogodala", "wolverhampton") b = gnomeSort( a ) wscript.echo join(a, ", ")

a = array( 234,567,345,568,2345,89,547,23,649,5769,456,456,567) b = gnomeSort( a ) wscript.echo join(a, ", ")

a = array( true, false, true, true, false, false, true, false) b = gnomeSort( a ) wscript.echo join(a, ", ")

a = array( 1,2,2,4,67789,-3,-45.99) b = gnomeSort( a ) wscript.echo join(a, ", ")

a = array( now(), now()-1,now()+2) b = gnomeSort( a ) wscript.echo join(a, ", ")</lang>

Output

<lang VBScript>aardvark, ampicillin, gogodala, wolverhampton, zanzibar, zulu 23, 89, 234, 345, 456, 456, 547, 567, 567, 568, 649, 2345, 5769 True, True, True, True, False, False, False, False -45.99, -3, 1, 2, 2, 4, 67789 2/02/2010 10:19:51 AM, 3/02/2010 10:19:51 AM, 5/02/2010 10:19:51 AM</lang> Note: All data in VBScript is of type Variant. Thus the code can sort many different types of data without code modification.

Ursala

The function is parameterized by a relational predicate and operates on a list. The algorithm is to scan forward until finding an item out of order, bubble it backwards to its proper position and resume scanning forward from where it was. <lang Ursala>gnome_sort "p" =

@NiX ^=lx -+ # iteration

  ~&r?\~& @lNXrX ->llx2rhPlrPCTxPrtPX~&lltPlhPrCXPrX ~&ll&& @llPrXh not "p",    # backward bubble
  ->~&rhPlCrtPX ~&r&& ~&lZ!| @bh "p"+-                                          # forward scan</lang>

Most of the code is wasted on dull but unavoidable stack manipulations. Here is a test program using the lexical partial order relation. <lang Ursala>#import std

  1. cast %s

t = gnome_sort(lleq) 'dfijhkwlawfkjnksdjnoqwjefgflkdsgioi'</lang> output:

'adddeffffgghiiijjjjkkkkllnnooqsswww'

XPL0

<lang XPL0>code ChOut=8, IntOut=11;

proc GnomeSort(A(0..Size-1)); \Sort array A int A, Size; int I, J, T; [I:= 1; J:= 2; while I < Size do

   if A(I-1) <= A(I) then
       [\ for descending sort, use >= for comparison
       I:= J;
       J:= J+1; 
       ]
   else
       [T:= A(I-1);  A(I-1):= A(I);  A(I):= T; \swap
       I:= I-1;
       if I = 0 then
           [I:= J;
           J:= J+1;
           ];
       ];

];

int A, I; [A:= [3, 1, 4, 1, -5, 9, 2, 6, 5, 4]; GnomeSort(A, 10); for I:= 0 to 10-1 do [IntOut(0, A(I)); ChOut(0, ^ )]; ]</lang>

Output:
-5 1 1 2 3 4 4 5 6 9