September 2017 Update

This commit is contained in:
Ingy döt Net 2017-09-23 10:01:46 +02:00
parent bba7bfd280
commit ba8067c3b7
14570 changed files with 153136 additions and 63871 deletions

View file

@ -0,0 +1,26 @@
% Quicksorts in-place the array of integers v, from lb to ub %
procedure quicksort ( integer array v( * )
; integer value lb, ub
) ;
if ub > lb then begin
% more than one element, so must sort %
integer left, right, pivot;
left := lb;
right := ub;
% choosing the middle element of the array as the pivot %
pivot := v( left + ( ( right + 1 ) - left ) div 2 );
while begin
while left <= ub and v( left ) < pivot do left := left + 1;
while right >= lb and v( right ) > pivot do right := right - 1;
left <= right
end do begin
integer swap;
swap := v( left );
v( left ) := v( right );
v( right ) := swap;
left := left + 1;
right := right - 1
end while_left_le_right ;
quicksort( v, lb, right );
quicksort( v, left, ub )
end quicksort ;

View file

@ -5,9 +5,9 @@ on quickSort(xs)
-- lessOrEqual :: a -> Bool
script lessOrEqual
on lambda(x)
on |λ|(x)
x h
end lambda
end |λ|
end script
set {less, more} to partition(lessOrEqual, t)
@ -19,7 +19,7 @@ on quickSort(xs)
end quickSort
-- TEST
-- TEST -----------------------------------------------------------------------
on run
quickSort([11.8, 14.1, 21.3, 8.5, 16.7, 5.7])
@ -29,8 +29,7 @@ on run
end run
-- GENERIC FUNCTIONS
-- GENERIC FUNCTIONS ----------------------------------------------------------
-- partition :: predicate -> List -> (Matches, nonMatches)
-- partition :: (a -> Bool) -> [a] -> ([a], [a])
@ -39,7 +38,7 @@ on partition(f, xs)
set lst to {{}, {}}
repeat with x in xs
set v to contents of x
set end of item ((lambda(v) as integer) + 1) of lst to v
set end of item ((|λ|(v) as integer) + 1) of lst to v
end repeat
return {item 2 of lst, item 1 of lst}
end tell
@ -61,7 +60,7 @@ on mReturn(f)
f
else
script
property lambda : f
property |λ| : f
end script
end if
end mReturn

View file

@ -0,0 +1,44 @@
#include <stdio.h>
void quicksort(int *A, int len);
int main (void) {
int a[] = {4, 65, 2, -31, 0, 99, 2, 83, 782, 1};
int n = sizeof a / sizeof a[0];
int i;
for (i = 0; i < n; i++) {
printf("%d ", a[i]);
}
printf("\n");
quicksort(a, n);
for (i = 0; i < n; i++) {
printf("%d ", a[i]);
}
printf("\n");
return 0;
}
void quicksort(int *A, int len) {
if (len < 2) return;
int pivot = A[len / 2];
int i, j;
for (i = 0, j = len - 1; ; i++, j--) {
while (A[i] < pivot) i++;
while (A[j] > pivot) j--;
if (i >= j) break;
int temp = A[i];
A[i] = A[j];
A[j] = temp;
}
quicksort(A, i);
quicksort(A + i, len - i);
}

View file

@ -0,0 +1,29 @@
#include <stdlib.h> // REQ: rand()
void swap(int *a, int *b) {
int c = *a;
*a = *b;
*b = c;
}
int partition(int A[], int p, int q) {
swap(&A[p + (rand() % (q - p + 1))], &A[q]); // PIVOT = A[q]
int i = p - 1;
for(int j = p; j <= q; j++) {
if(A[j] <= A[q]) {
swap(&A[++i], &A[j]);
}
}
return i;
}
void quicksort(int A[], int p, int q) {
if(p < q) {
int pivotIndx = partition(A, p, q);
quicksort(A, p, pivotIndx - 1);
quicksort(A, pivotIndx + 1, q);
}
}

View file

@ -1,33 +0,0 @@
#include <stdio.h>
void quick_sort (int *a, int n) {
int i, j, p, t;
if (n < 2)
return;
p = a[n / 2];
for (i = 0, j = n - 1;; i++, j--) {
while (a[i] < p)
i++;
while (p < a[j])
j--;
if (i >= j)
break;
t = a[i];
a[i] = a[j];
a[j] = t;
}
quick_sort(a, i);
quick_sort(a + i, n - i);
}
int main (void) {
int a[] = {4, 65, 2, -31, 0, 99, 2, 83, 782, 1};
int n = sizeof a / sizeof a[0];
int i;
for (i = 0; i < n; i++)
printf("%d%s", a[i], i == n - 1 ? "\n" : " ");
quick_sort(a, n);
for (i = 0; i < n; i++)
printf("%d%s", a[i], i == n - 1 ? "\n" : " ");
return 0;
}

View file

@ -1,9 +1,12 @@
defmodule QuickSort do
def qsort([]) do
[]
def qsort([]), do: []
def qsort([_|_] = list) do
List.flatten do_qsort(list)
end
def qsort([pivot | rest]) do
{ left, right } = Enum.partition(rest, fn(x) -> x < pivot end)
qsort(left) ++ [pivot] ++ qsort(right)
defp do_qsort([pivot | rest]) do
{left, right} = Enum.split_with(rest, &(&1 < pivot))
[qsort(left), pivot, qsort(right)]
end
end

View file

@ -1,10 +1,10 @@
quick_sort(L) -> qs(L, erlang:system_info(schedulers)).
quick_sort(L) -> qs(L, trunc(math:log2(erlang:system_info(schedulers)))).
qs([],_) -> [];
qs([H|T], N) when N > 1 ->
qs([H|T], N) when N > 0 ->
{Parent, Ref} = {self(), make_ref()},
spawn(fun()-> Parent ! {l1, Ref, qs([E||E<-T, E<H], N-2)} end),
spawn(fun()-> Parent ! {l2, Ref, qs([E||E<-T, H =< E], N-2)} end),
spawn(fun()-> Parent ! {l1, Ref, qs([E||E<-T, E<H], N-1)} end),
spawn(fun()-> Parent ! {l2, Ref, qs([E||E<-T, H =< E], N-1)} end),
{L1, L2} = receive_results(Ref, undefined, undefined),
L1 ++ [H] ++ L2;
qs([H|T],_) ->

View file

@ -1,4 +1,7 @@
import Data.List
import Data.List (partition)
qsort :: Ord a => [a] -> [a]
qsort [] = []
qsort (x:xs) = qsort ys ++ x : qsort zs where (ys, zs) = partition (< x) xs
qsort (x:xs) = qsort ys ++ x : qsort zs
where
(ys, zs) = partition (< x) xs

View file

@ -1,33 +1,31 @@
(function () {
(() => {
'use strict';
// QUICKSORT --------------------------------------------------------------
// quickSort :: (Ord a) => [a] -> [a]
function quickSort(xs) {
if (xs.length) {
var h = xs[0],
[less, more] = partition(
x => x <= h,
xs.slice(1)
);
const quickSort = xs =>
xs.length > 1 ? (() => {
const
h = xs[0],
[less, more] = partition(x => x <= h, xs.slice(1));
return [].concat.apply(
[], [quickSort(less), h, quickSort(more)]
);
})() : xs;
} else return [];
}
// GENERIC ----------------------------------------------------------------
// partition :: Predicate -> List -> (Matches, nonMatches)
// partition :: (a -> Bool) -> [a] -> ([a], [a])
function partition(p, xs) {
return xs.reduce((a, x) => (
a[p(x) ? 0 : 1].push(x),
a
), [[], []]);
}
const partition = (p, xs) =>
xs.reduce((a, x) =>
p(x) ? [a[0].concat(x), a[1]] : [a[0], a[1].concat(x)], [
[],
[]
]);
// TEST -------------------------------------------------------------------
return quickSort([11.8, 14.1, 21.3, 8.5, 16.7, 5.7]);
})();

View file

@ -1 +0,0 @@
t@<t:1 3 5 7 9 8 6 4 2

View file

@ -1,13 +1,12 @@
import java.util.*
import java.util.Comparator
import java.util.ArrayList
fun <T> quickSort(a : List<T>, c : Comparator<T>) : ArrayList<T> {
return if (a.size == 0) ArrayList(a)
else {
val boxes = Array<ArrayList<T>>(3, {ArrayList<T>()})
fun normalise(i : Int) = i / Math.max(1, Math.abs(i))
a forEach {boxes[normalise(c.compare(it, a[0])) + 1] add(it)}
array(0, 2) forEach {boxes[it] = quickSort(boxes[it], c)}
boxes.flatMapTo(ArrayList<T>()) {it}
}
fun <T> quickSort(a: List<T>, c: Comparator<T>): ArrayList<T> {
if (a.isEmpty()) return ArrayList(a)
val boxes = Array(3, { ArrayList<T>() })
fun normalise(i: Int) = i / Math.max(1, Math.abs(i))
a.forEach { boxes[normalise(c.compare(it, a[0])) + 1].add(it) }
arrayOf(0, 2).forEach { boxes[it] = quickSort(boxes[it], c) }
return boxes.flatMapTo(ArrayList<T>()) { it }
}

View file

@ -1,15 +1,13 @@
fun quicksort(list: List<Int>): List<Int> {
if (list.size == 0) {
return listOf()
} else {
val head = list.first()
val tail = list.takeLast(list.size - 1)
if (list.isEmpty()) return emptyList()
val less = quicksort(tail.filter { it < head })
val high = quicksort(tail.filter { it >= head })
val head = list.first()
val tail = list.takeLast(list.size - 1)
return less + head + high
}
val less = quicksort(tail.filter { it < head })
val high = quicksort(tail.filter { it >= head })
return less + head + high
}
fun main(args: Array<String>) {

View file

@ -1,17 +0,0 @@
proc QuickSort(list: seq[int]): seq[int] =
if len(list) == 0:
return @[]
var pivot = list[0]
var left: seq[int] = @[]
var right: seq[int] = @[]
for i in low(list)+1..high(list):
if list[i] <= pivot:
left.add(list[i])
elif list[i] > pivot:
right.add(list[i])
result = QuickSort(left)
result.add(pivot)
result.add(QuickSort(right))

View file

@ -1,3 +0,0 @@
var sorted: seq[int] = QuickSort(@[5,2,1,6,2,3,1,2,123,21,54,6,1])
for i in items(sorted):
echo(i)

View file

@ -0,0 +1,27 @@
a = .array~Of(4, 65, 2, -31, 0, 99, 83, 782, 1)
say 'before:' a~toString( ,', ')
a = quickSort(a)
say ' after:' a~toString( ,', ')
exit
::routine quickSort
use arg arr -- the array to be sorted
less = .array~new
pivotList = .array~new
more = .array~new
if arr~items <= 1 then
return arr
else do
pivot = arr[1]
do i over arr
if i < pivot then
less~append(i)
else if i > pivot then
more~append(i)
else
pivotList~append(i)
end
less = quickSort(less)
more = quickSort(more)
return less~~appendAll(pivotList)~~appendAll(more)
end

View file

@ -1,21 +1,21 @@
{ X is array of LongInt }
Procedure QuickSort ( Left, Right : LongInt );
Var
i, j : LongInt;
i, j,
tmp, pivot : LongInt; { tmp & pivot are the same type as the elements of array }
Begin
i:=Left;
j:=Right;
pivot := X[(Left + Right) shr 1]; // pivot := X[(Left + Rigth) div 2]
Repeat
While pivot > X[i] Do i:=i+1;
While pivot < X[j] Do j:=j-1;
While pivot > X[i] Do inc(i); // i:=i+1;
While pivot < X[j] Do dec(j); // j:=j-1;
If i<=j Then Begin
tmp:=X[i];
X[i]:=X[j];
X[j]:=tmp;
j:=j-1;
i:=i+1;
dec(j); // j:=j-1;
inc(i); // i:=i+1;
End;
Until i>j;
If Left<j Then QuickSort(Left,j);

View file

@ -5,35 +5,35 @@ call qSort # /*invoke the quicksort subrou
call show@ ' after sort' /*show the after array elements. */
exit /*stick a fork in it, we're all done. */
/*──────────────────────────────────────────────────────────────────────────────────────*/
qSort: procedure expose @.; a.1=1; b.1=arg(1) /*access the caller's local variable. */
qSort: procedure expose @.; a.1=1; parse arg b.1 /*access the caller's local variable. */
$=1
do while $\==0; L=a.$; t=b.$; $=$-1; if t<2 then iterate
h=L+t-1; ?=L+t%2
if @.h<@.L then if @.?<@.h then do; p=@.h; @.h=@.L; end
do while $\==0; L=a.$; t=b.$; $=$-1; if t<2 then iterate
H=L+t-1; ?=L+t%2
if @.H<@.L then if @.?<@.H then do; p=@.H; @.H=@.L; end
else if @.?>@.L then p=@.L
else do; p=@.?; @.?=@.L; end
else if @.?<@.l then p=@.L
else if @.?>@.h then do; p=@.h; @.h=@.L; end
else if @.?<@.L then p=@.L
else if @.?>@.H then do; p=@.H; @.H=@.L; end
else do; p=@.?; @.?=@.L; end
j=L+1; k=h
do forever
do j=j while j<=k & @.j<=p; end /*a tinie-tiny loop.*/
do j=j while j<=k & @.j<=p; end /*a tinietiny loop.*/
do k=k by -1 while j <k & @.k>=p; end /*another " " */
if j>=k then leave /*segment finished? */
_=@.j; @.j=@.k; @.k=_ /*swap J&K elements.*/
end /*forever*/
$=$+1
k=j-1; @.L=@.k; @.k=p
if j<=? then do; a.$=j; b.$=h-j+1; $=$+1; a.$=L; b.$=k-L; end
eLse do; a.$=L; b.$=k-L; $=$+1; a.$=j; b.$=h-j+1; end
end /*whiLe $¬==0*/
if j<=? then do; a.$=j; b.$=H-j+1; $=$+1; a.$=L; b.$=k-L; end
else do; a.$=L; b.$=k-L; $=$+1; a.$=j; b.$=H-j+1; end
end /*while $¬==0*/
return
/*──────────────────────────────────────────────────────────────────────────────────────*/
show@: w=length(#); do j=1 for #; say 'element' right(j,w) arg(1)":" @.j; end
say copies('', maxL + w + 22) /*display a separator (between outputs)*/
return
/*──────────────────────────────────GEN@ subroutine──────────────────────────────────────────────────────────────────────────────────────────────────────*/
gen@: @.=; maxL=0 /*assign default value for array.*/
/*───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────*/
gen@: @.=; maxL=0 /*assign a default value for the array.*/
@.1 = " Rivers that form part of a (USA) state's border " /*this value is adjusted later to include a prefix & suffix.*/
@.2 = '=' /*this value is expanded later. */
@.3 = "Perdido River Alabama, Florida"
@ -97,10 +97,9 @@ gen@: @.=; maxL=0 /*assign default value for arra
@.61 = "Catawba River North Carolina, South Carolina"
@.62 = "Blackwater River North Carolina, Virginia"
@.63 = "Columbia River Oregon, Washington"
do #=1 while @.#\=='' /*find how many entries in array, and */
maxL=max(maxL, length(@.#)) /* also find the maximum width entry.*/
end /*#*/
do #=1 until @.#=='' /*find how many entries in array, and */
maxL=max(maxL, length(@.#)) /* also find the maximum width entry.*/
end /*#*/
#=#-1 /*adjust the highest element number. */
@.1=center(@.1, maxL, '-') /* " " header information. */
@.2=copies(@.2, maxL) /* " " " separator. */

View file

@ -1,6 +0,0 @@
class Array
def quick_sort
h, *t = self
h ? t.partition { |e| e < h }.inject { |l, r| l.quick_sort + [h] + r.quick_sort } : []
end
end

View file

@ -1,46 +1,39 @@
// Type alias for function that returns true if arguments should be swapped
type OrderFunc<T> = Fn(&T, &T) -> bool;
fn main() {
// Sort numbers
println!("Sort numbers in descending order");
let mut numbers = [4, 65, 2, -31, 0, 99, 2, 83, 782, 1];
println!("Before: {:?}", numbers);
quick_sort(&mut numbers, &is_less);
println!("After: {:?}", numbers);
quick_sort(&mut numbers, &|x,y| x > y);
println!("After: {:?}\n", numbers);
// Sort strings
println!("Sort strings alphabetically");
let mut strings = ["beach", "hotel", "airplane", "car", "house", "art"];
println!("Before: {:?}", strings);
quick_sort(&mut strings, &is_less);
println!("After: {:?}", strings);
quick_sort(&mut strings, &|x,y| x < y);
println!("After: {:?}\n", strings);
println!("Sort strings by length");
println!("Before: {:?}", strings);
quick_sort(&mut strings, &|x,y| x.len() < y.len());
println!("After: {:?}", strings);
}
// Example OrderFunc which is used to order items from least to greatest
#[inline(always)]
fn is_less<T: Ord>(x: &T, y: &T) -> bool {
x < y
}
fn quick_sort<T>(v: &mut [T], f: &OrderFunc<T>) {
fn quick_sort<T,F>(v: &mut [T], f: &F)
where F: Fn(&T,&T) -> bool
{
let len = v.len();
if len < 2 {
return;
if len >= 2 {
let pivot_index = partition(v, f);
quick_sort(&mut v[0..pivot_index], f);
quick_sort(&mut v[pivot_index + 1..len], f);
}
let pivot_index = partition(v, f);
// Sort the left side
quick_sort(&mut v[0..pivot_index], f);
// Sort the right side
quick_sort(&mut v[pivot_index + 1..len], f);
}
fn partition<T>(v: &mut [T], f: &OrderFunc<T>) -> usize {
fn partition<T,F>(v: &mut [T], f: &F) -> usize
where F: Fn(&T,&T) -> bool
{
let len = v.len();
let pivot_index = len / 2;

View file

@ -0,0 +1,30 @@
PROCEDURE QUICKSORT(A); REAL ARRAY A;
BEGIN
PROCEDURE QS(A, FIRST, LAST); REAL ARRAY A; INTEGER FIRST, LAST;
BEGIN
INTEGER LEFT, RIGHT;
LEFT := FIRST; RIGHT := LAST;
IF RIGHT - LEFT + 1 > 1 THEN
BEGIN
REAL PIVOT;
PIVOT := A((LEFT + RIGHT) // 2);
WHILE LEFT <= RIGHT DO
BEGIN
WHILE A(LEFT) < PIVOT DO LEFT := LEFT + 1;
WHILE A(RIGHT) > PIVOT DO RIGHT := RIGHT - 1;
IF LEFT <= RIGHT THEN
BEGIN
REAL SWAP;
SWAP := A(LEFT); A(LEFT) := A(RIGHT); A(RIGHT) := SWAP;
LEFT := LEFT + 1; RIGHT := RIGHT - 1;
END;
END;
QS(A, FIRST, RIGHT);
QS(A, LEFT, LAST);
END;
END QS;
QS(A, LOWERBOUND(A, 1), UPPERBOUND(A, 1));
END QUICKSORT;

View file

@ -0,0 +1,8 @@
fcn qtSort(list,cmp=Op("<")){ // sort immutable lists
fcn(list,cmp,N){ // spendy to keep recreating cmp
reg pivot=list[0], rest=list[1,*];
left,right:=rest.filter22(cmp,pivot);
N+=1;
T.extend(self.fcn(left,cmp,N),T(pivot),self.fcn(right,cmp,N));
}(list,cmp,0);
}

View file

@ -0,0 +1,24 @@
fcn qiSort(list,cmp='<){ // in place quick sort
fcn(list,left,right,cmp){
if (left<right){
// partition list
pivotIndex:=(left+right)/2; // or median of first,middle,last
pivot:=list[pivotIndex];
list.swap(pivotIndex,right); // move pivot to end
pivotIndex:=left;
i:=left; do(right-left){ // foreach i in ([left..right-1])
if(cmp(list[i],pivot)){ // not cheap
list.swap(i,pivotIndex);
pivotIndex+=1;
}
i+=1;
}
list.swap(pivotIndex,right); // move pivot to final place
// sort the partitions
self.fcn(list,left,pivotIndex-1,cmp);
return(self.fcn(list,pivotIndex+1,right,cmp));
}
}(list,0,list.len()-1,cmp);
list;
}