Sorting algorithms/Stooge sort: Difference between revisions

From Rosetta Code
Content added Content deleted
(Added a solution for MATLAB)
(→‎{{header|Perl 6}}: Added Perl 6 solution)
Line 224: Line 224:
<pre>Unsorted: 1, 4, 5, 3, -6, 3, 7, 10, -2, -5, 7, 5, 9, -3, 7,
<pre>Unsorted: 1, 4, 5, 3, -6, 3, 7, 10, -2, -5, 7, 5, 9, -3, 7,
Sorted : -6, -5, -3, -2, 1, 3, 3, 4, 5, 5, 7, 7, 7, 9, 10,</pre>
Sorted : -6, -5, -3, -2, 1, 3, 3, 4, 5, 5, 7, 7, 7, 9, 10,</pre>

=={{header|Perl 6}}==
<lang perl6>sub stoogesort( @L is rw, $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;
</lang>


=={{header|PicoLisp}}==
=={{header|PicoLisp}}==

Revision as of 18:59, 9 September 2010

Task
Sorting algorithms/Stooge 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 Stooge 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)

Show the Stooge Sort for an array of integers. The Stooge Sort algorithm is as follows:

algorithm stoogesort(array L, i = 0, j = length(L)-1)
     if L[j] < L[i] then
         L[i]  L[j]
     if j - i > 1 then
         t := (j - i + 1)/3
         stoogesort(L, i  , j-t)
         stoogesort(L, i+t, j  )
         stoogesort(L, i  , j-t)
     return L

C#

<lang C sharp|C#> public static void Sort<T>(List<T> list) where T : IComparable {

       if (list.Count > 1) {
           StoogeSort(list, 0, list.Count - 1);
       }
   }
   private static void StoogeSort<T>(List<T> L, int i, int j) where T : IComparable {
       if (L[j].CompareTo(L[i])<0) {
           T 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);
       }
   }</lang>

D

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

void stoogeSort(T)(T[] seq) {

   if (seq[$-1] < seq[0])
       swap(seq[0], seq[$-1]);
   if (seq.length > 2) {
       int m = seq.length / 3;
       stoogeSort(seq[0 .. $ - m]);
       stoogeSort(seq[m .. $]);
       stoogeSort(seq[0 .. $ - m]);
   }

}

void main() {

   auto data = [1, 4, 5, 3, -6, 3, 7, 10, -2, -5];
   stoogeSort(data);
   writeln(data);

}</lang>

Haskell

<lang haskell>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</lang> Example: <lang haskell>*Main> stoogeSort [1, 4, 5, 3, -6, 3, 7, 10, -2, -5, 7, 5, 9, -3, 7] [-6,-5,-3,-2,1,3,3,4,5,5,7,7,7,9,10]</lang>

J

<lang j>swapElems=: |.@:{`[`]}

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.

)</lang> Example: <lang j> (,: stoogeSort) ?~13 3 10 8 4 7 12 1 2 11 6 5 9 0 0 1 2 3 4 5 6 7 8 9 10 11 12 </lang>

Java

<lang java>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);
       }
   }

}</lang> Output:

[-6, -5, -2, 1, 3, 3, 4, 5, 7, 10]

MATLAB

<lang MATLAB>%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</lang> Sample Output: <lang MATLAB>>> stoogeSort([1 -6 4 -9],1,4)

ans =

   -9    -6     1     4</lang>

OCaml

<lang ocaml>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)</lang>

testing: <lang ocaml>let () =

 let ar = [| 3; 1; 7; 2; 6; 5; 4; 9; 8 |] in
 stoogesort ar;
 Array.iter (Printf.printf " %d") ar;
 print_newline()</lang>

Oz

<lang oz>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</lang>

Output:

Unsorted: 1, 4, 5, 3, -6, 3, 7, 10, -2, -5, 7, 5, 9, -3, 7, 
Sorted  : -6, -5, -3, -2, 1, 3, 3, 4, 5, 5, 7, 7, 7, 9, 10,

Perl 6

<lang perl6>sub stoogesort( @L is rw, $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; </lang>

PicoLisp

<lang PicoLisp>(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 )</lang>

Test:

: (apply < (stoogeSort (make (do 100 (link (rand))))))
-> T

PL/I

<lang PL/I>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;</lang>

PureBasic

<lang PureBasic>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</lang> Implementation may be as<lang PureBasic>Define AmountOfPosts=(?Stop_Data-?Start_data)/SizeOf(Integer) Dim Xyz.i(AmountOfPosts) CopyMemory(?Start_data, @Xyz(), ?Stop_Data-?Start_data)

Stooge_Sort(Xyz())

For i=0 To ArraySize(Xyz())

 Debug Xyz(i)

Next i

DataSection

 Start_data:
 Data.i  1, 4, 5, 3, -6, 3, 7, 10, -2, -5, 7, 5, 9, -3, 7
 Stop_Data:

EndDataSection</lang>

Python

<lang python>>>> data = [1, 4, 5, 3, -6, 3, 7, 10, -2, -5, 7, 5, 9, -3, 7] >>> def stoogesort(L, i=0, j=None): if j is None: j = len(L) - 1 if L[j] < L[i]: L[i], L[j] = L[j], L[i] if j - i > 1: t = (j - i + 1) // 3 stoogesort(L, i , j-t) stoogesort(L, i+t, j ) stoogesort(L, i , j-t) return L

>>> stoogesort(data) [-6, -5, -3, -2, 1, 3, 3, 4, 5, 5, 7, 7, 7, 9, 10]</lang>

This alternate solution uses a wrapper function to compute the initial value of j rather than detecting the sentinel value None. <lang python>>>> def stoogesort(L, i, j): if L[j] < L[i]: L[i], L[j] = L[j], L[i] if j - i > 1: t = (j - i + 1) // 3 stoogesort(L, i , j-t) stoogesort(L, i+t, j ) stoogesort(L, i , j-t) return L

>>> def stooge(L): return stoogesort(L, 0, len(L) - 1)

>>> data = [1, 4, 5, 3, -6, 3, 7, 10, -2, -5, 7, 5, 9, -3, 7] >>> stooge(data) [-6, -5, -3, -2, 1, 3, 3, 4, 5, 5, 7, 7, 7, 9, 10]</lang>

Smalltalk

Works with: GNU Smalltalk

<lang smalltalk>OrderedCollection extend [

   stoogeSortFrom: i to: j [

(self at: j) < (self at: i) ifTrue: [ self swapElement: i with: j ]. j - i > 1

         ifTrue: [

|t| t := (j - i + 1)//3. self stoogeSortFrom: i to: (j-t). self stoogeSortFrom: (i+t) to: j. self stoogeSortFrom: i to: (j-t)

         ]
   ]
   stoogeSort [ self stoogeSortFrom: 1 to: (self size) ]
   swapElement: i with: j [

|t| t := self at: i.

       self at: i put: (self at: j).

self at: j put: t

   ]

].

|test| test := #( 1 4 5 3 -6 3 7 10 -2 -5) asOrderedCollection. test stoogeSort. test printNl.</lang>

Tcl

Works with: Tcl version 8.5

<lang tcl>package require Tcl 8.5

proc stoogesort {L {i 0} {j -42}} {

  if {$j == -42} {# Magic marker
     set j [expr {[llength $L]-1}]
  }
  set Li [lindex $L $i]
  set Lj [lindex $L $j]
  if {$Lj < $Li} {
     lset L $i $Lj
     lset L $j $Li
  }      
  if {$j-$i > 1} {
     set t [expr {($j-$i+1)/3}]
     set L [stoogesort $L $i [expr {$j-$t}]]
     set L [stoogesort $L [expr {$i+$t}] $j]
     set L [stoogesort $L $i [expr {$j-$t}]]
  }
  return $L

}

stoogesort {1 4 5 3 -6 3 7 10 -2 -5}</lang> Output:

-6 -5 -2 1 3 3 4 5 7 10