Update all new Tasks

This commit is contained in:
Ingy döt Net 2015-02-20 09:02:09 -05:00
parent 00a190b0a6
commit 91df62d461
5697 changed files with 93386 additions and 804 deletions

View file

@ -0,0 +1,5 @@
Use the [[wp:Quickselect|quickselect algorithm]] on the vector
: [9, 8, 7, 6, 5, 0, 1, 2, 3, 4]
To show the first, second, third, ... up to the tenth largest member of the vector, in order, here on this page.
* Note: Quick''sort'' has a separate [[Sorting algorithms/Quicksort|task]].

View file

@ -0,0 +1,39 @@
MyList := [9, 8, 7, 6, 5, 0, 1, 2, 3, 4]
Loop, 10
Out .= Select(MyList, 1, MyList.MaxIndex(), A_Index) (A_Index = MyList.MaxIndex() ? "" : ", ")
MsgBox, % Out
return
Partition(List, Left, Right, PivotIndex) {
PivotValue := List[PivotIndex]
, Swap(List, pivotIndex, Right)
, StoreIndex := Left
, i := Left - 1
Loop, % Right - Left
if (List[j := i + A_Index] <= PivotValue)
Swap(List, StoreIndex, j)
, StoreIndex++
Swap(List, Right, StoreIndex)
return StoreIndex
}
Select(List, Left, Right, n) {
if (Left = Right)
return List[Left]
Loop {
PivotIndex := (Left + Right) // 2
, PivotIndex := Partition(List, Left, Right, PivotIndex)
if (n = PivotIndex)
return List[n]
else if (n < PivotIndex)
Right := PivotIndex - 1
else
Left := PivotIndex + 1
}
}
Swap(List, i1, i2) {
t := List[i1]
, List[i1] := List[i2]
, List[i2] := t
}

View file

@ -0,0 +1,14 @@
#include <algorithm>
#include <iostream>
int main() {
for (int i = 0; i < 10; i++) {
int a[] = {9, 8, 7, 6, 5, 0, 1, 2, 3, 4};
std::nth_element(a, a + i, a + sizeof(a)/sizeof(*a));
std::cout << a[i];
if (i < 9) std::cout << ", ";
}
std::cout << std::endl;
return 0;
}

View file

@ -0,0 +1,37 @@
#include <iterator>
#include <algorithm>
#include <functional>
#include <cstdlib>
#include <ctime>
#include <iostream>
template <typename Iterator>
Iterator select(Iterator begin, Iterator end, int n) {
typedef typename std::iterator_traits<Iterator>::value_type T;
while (true) {
Iterator pivotIt = begin + std::rand() % std::distance(begin, end);
std::iter_swap(pivotIt, end-1); // Move pivot to end
pivotIt = std::partition(begin, end-1, std::bind2nd(std::less<T>(), *(end-1)));
std::iter_swap(end-1, pivotIt); // Move pivot to its final place
if (n == pivotIt - begin) {
return pivotIt;
} else if (n < pivotIt - begin) {
end = pivotIt;
} else {
n -= pivotIt+1 - begin;
begin = pivotIt+1;
}
}
}
int main() {
std::srand(std::time(NULL));
for (int i = 0; i < 10; i++) {
int a[] = {9, 8, 7, 6, 5, 0, 1, 2, 3, 4};
std::cout << *select(a, a + sizeof(a)/sizeof(*a), i);
if (i < 9) std::cout << ", ";
}
std::cout << std::endl;
return 0;
}

View file

@ -0,0 +1,35 @@
#include <stdio.h>
#include <string.h>
int qselect(int *v, int len, int k)
{
# define SWAP(a, b) { tmp = v[a]; v[a] = v[b]; v[b] = tmp; }
int i, st, tmp;
for (st = i = 0; i < len - 1; i++) {
if (v[i] > v[len-1]) continue;
SWAP(i, st);
st++;
}
SWAP(len-1, st);
return k == st ?v[st]
:st > k ? qselect(v, st, k)
: qselect(v + st, len - st, k - st);
}
int main(void)
{
# define N (sizeof(x)/sizeof(x[0]))
int x[] = {9, 8, 7, 6, 5, 0, 1, 2, 3, 4};
int y[N];
int i;
for (i = 0; i < 10; i++) {
memcpy(y, x, sizeof(x)); // qselect modifies array
printf("%d: %d\n", i, qselect(y, 10, i));
}
return 0;
}

View file

@ -0,0 +1,95 @@
CLASS-ID MainProgram.
METHOD-ID Partition STATIC USING T.
CONSTRAINTS.
CONSTRAIN T IMPLEMENTS type IComparable.
DATA DIVISION.
LOCAL-STORAGE SECTION.
01 pivot-val T.
PROCEDURE DIVISION USING VALUE arr AS T OCCURS ANY,
left-idx AS BINARY-LONG, right-idx AS BINARY-LONG,
pivot-idx AS BINARY-LONG
RETURNING ret AS BINARY-LONG.
MOVE arr (pivot-idx) TO pivot-val
INVOKE self::Swap(arr, pivot-idx, right-idx)
DECLARE store-idx AS BINARY-LONG = left-idx
PERFORM VARYING i AS BINARY-LONG FROM left-idx BY 1
UNTIL i > right-idx
IF arr (i) < pivot-val
INVOKE self::Swap(arr, i, store-idx)
ADD 1 TO store-idx
END-IF
END-PERFORM
INVOKE self::Swap(arr, right-idx, store-idx)
MOVE store-idx TO ret
END METHOD.
METHOD-ID Quickselect STATIC USING T.
CONSTRAINTS.
CONSTRAIN T IMPLEMENTS type IComparable.
PROCEDURE DIVISION USING VALUE arr AS T OCCURS ANY,
left-idx AS BINARY-LONG, right-idx AS BINARY-LONG,
n AS BINARY-LONG
RETURNING ret AS T.
IF left-idx = right-idx
MOVE arr (left-idx) TO ret
GOBACK
END-IF
DECLARE rand AS TYPE Random = NEW Random()
DECLARE pivot-idx AS BINARY-LONG = rand::Next(left-idx, right-idx)
DECLARE pivot-new-idx AS BINARY-LONG
= self::Partition(arr, left-idx, right-idx, pivot-idx)
DECLARE pivot-dist AS BINARY-LONG = pivot-new-idx - left-idx + 1
EVALUATE TRUE
WHEN pivot-dist = n
MOVE arr (pivot-new-idx) TO ret
WHEN n < pivot-dist
INVOKE self::Quickselect(arr, left-idx, pivot-new-idx - 1, n)
RETURNING ret
WHEN OTHER
INVOKE self::Quickselect(arr, pivot-new-idx + 1, right-idx,
n - pivot-dist) RETURNING ret
END-EVALUATE
END METHOD.
METHOD-ID Swap STATIC USING T.
CONSTRAINTS.
CONSTRAIN T IMPLEMENTS type IComparable.
DATA DIVISION.
LOCAL-STORAGE SECTION.
01 temp T.
PROCEDURE DIVISION USING arr AS T OCCURS ANY,
VALUE idx-1 AS BINARY-LONG, idx-2 AS BINARY-LONG.
IF idx-1 <> idx-2
MOVE arr (idx-1) TO temp
MOVE arr (idx-2) TO arr (idx-1)
MOVE temp TO arr (idx-2)
END-IF
END METHOD.
METHOD-ID Main STATIC.
PROCEDURE DIVISION.
DECLARE input-array AS BINARY-LONG OCCURS ANY
= TABLE OF BINARY-LONG(9, 8, 7, 6, 5, 0, 1, 2, 3, 4)
DISPLAY "Loop quick select 10 times."
PERFORM VARYING i AS BINARY-LONG FROM 1 BY 1 UNTIL i > 10
DISPLAY self::Quickselect(input-array, 1, input-array::Length, i)
NO ADVANCING
IF i < 10
DISPLAY ", " NO ADVANCING
END-IF
END-PERFORM
DISPLAY SPACE
END METHOD.
END CLASS.

View file

@ -0,0 +1,9 @@
void main() {
import std.stdio, std.algorithm;
auto a = [9, 8, 7, 6, 5, 0, 1, 2, 3, 4];
foreach (immutable i; 0 .. a.length) {
a.topN(i);
write(a[i], " ");
}
}

View file

@ -0,0 +1,48 @@
import std.stdio, std.random, std.algorithm, std.range;
T quickSelect(T)(T[] arr, size_t n)
in {
assert(n < arr.length);
} body {
static size_t partition(T[] sub, in size_t pivot) pure nothrow
in {
assert(!sub.empty);
assert(pivot < sub.length);
} body {
auto pivotVal = sub[pivot];
sub[pivot].swap(sub.back);
size_t storeIndex = 0;
foreach (ref si; sub[0 .. $ - 1]) {
if (si < pivotVal) {
si.swap(sub[storeIndex]);
storeIndex++;
}
}
sub.back.swap(sub[storeIndex]);
return storeIndex;
}
size_t left = 0;
size_t right = arr.length - 1;
while (right > left) {
assert(left < arr.length);
assert(right < arr.length);
immutable pivotIndex = left + partition(arr[left .. right + 1],
uniform(0U, right - left + 1));
if (pivotIndex - left == n) {
right = left = pivotIndex;
} else if (pivotIndex - left < n) {
n -= pivotIndex - left + 1;
left = pivotIndex + 1;
} else {
right = pivotIndex - 1;
}
}
return arr[left];
}
void main() {
auto a = [9, 8, 7, 6, 5, 0, 1, 2, 3, 4];
a.length.iota.map!(i => a.quickSelect(i)).writeln;
}

View file

@ -0,0 +1,41 @@
package main
import "fmt"
func quickselect(list []int, k int) int {
for {
// partition
px := len(list) / 2
pv := list[px]
last := len(list) - 1
list[px], list[last] = list[last], list[px]
i := 0
for j := 0; j < last; j++ {
if list[j] < pv {
list[i], list[j] = list[j], list[i]
i++
}
}
// select
if i == k {
return pv
}
if k < i {
list = list[:i]
} else {
list[i], list[last] = list[last], list[i]
list = list[i+1:]
k -= i + 1
}
}
}
func main() {
for i := 0; ; i++ {
v := []int{9, 8, 7, 6, 5, 0, 1, 2, 3, 4}
if i == len(v) {
return
}
fmt.Println(quickselect(v, i))
}
}

View file

@ -0,0 +1,55 @@
package main
import (
"fmt"
"sort"
"math/rand"
)
func partition(a sort.Interface, first int, last int, pivotIndex int) int {
a.Swap(first, pivotIndex) // move it to beginning
left := first+1
right := last
for left <= right {
for left <= last && a.Less(left, first) {
left++
}
for right >= first && a.Less(first, right) {
right--
}
if left <= right {
a.Swap(left, right)
left++
right--
}
}
a.Swap(first, right) // swap into right place
return right
}
func quickselect(a sort.Interface, n int) int {
first := 0
last := a.Len()-1
for {
pivotIndex := partition(a, first, last,
rand.Intn(last - first + 1) + first)
if n == pivotIndex {
return pivotIndex
} else if n < pivotIndex {
last = pivotIndex-1
} else {
first = pivotIndex+1
}
}
panic("bad index")
}
func main() {
for i := 0; ; i++ {
v := []int{9, 8, 7, 6, 5, 0, 1, 2, 3, 4}
if i == len(v) {
return
}
fmt.Println(v[quickselect(sort.IntSlice(v), i)])
}
}

View file

@ -0,0 +1,13 @@
import Data.List (partition)
quickselect :: Ord a => Int -> [a] -> a
quickselect k (x:xs) | k < l = quickselect k ys
| k > l = quickselect (k-l-1) zs
| otherwise = x
where (ys, zs) = partition (< x) xs
l = length ys
main :: IO ()
main = do
let v = [9, 8, 7, 6, 5, 0, 1, 2, 3, 4]
print $ map (\i -> quickselect i v) [0 .. length v-1]

View file

@ -0,0 +1,21 @@
procedure main(A)
every writes(" ",select(1 to *A, A, 1, *A)|"\n")
end
procedure select(k,A,min,max)
repeat {
pNI := partition(?(max-min)+min, A, min, max)
pD := pNI - min + 1
if pD = k then return A[pNI]
if k < pD then max := pNI-1
else (k -:= pD, min := pNI+1)
}
end
procedure partition(pivot,A,min,max)
pV := (A[max] :=: A[pivot])
sI := min
every A[i := min to max-1] <= pV do (A[sI] :=: A[i], sI +:= 1)
A[max] :=: A[sI]
return sI
end

View file

@ -0,0 +1,14 @@
quickselect=:4 :0
if. 0=#y do. _ return. end.
n=.?#y
m=.n{y
if. x < m do.
x quickselect (m>y)#y
else.
if. x > m do.
x quickselect (m<y)#y
else.
m
end.
end.
)

View file

@ -0,0 +1,2 @@
8 quickselect 9, 8, 7, 6, 5, 0, 1, 2, 3, 4
8

View file

@ -0,0 +1,2 @@
((10 {./:~) quickselect"0 1 ]) 9, 8, 7, 6, 5, 0, 1, 2, 3, 4
0 1 2 3 4 5 6 7 8 9

View file

@ -0,0 +1,53 @@
import java.util.Random;
public class QuickSelect {
private static <E extends Comparable<? super E>> int partition(E[] arr, int left, int right, int pivot) {
E pivotVal = arr[pivot];
swap(arr, pivot, right);
int storeIndex = left;
for (int i = left; i < right; i++) {
if (arr[i].compareTo(pivotVal) < 0) {
swap(arr, i, storeIndex);
storeIndex++;
}
}
swap(arr, right, storeIndex);
return storeIndex;
}
private static <E extends Comparable<? super E>> E select(E[] arr, int n) {
int left = 0;
int right = arr.length - 1;
Random rand = new Random();
while (right >= left) {
int pivotIndex = partition(arr, left, right, rand.nextInt(right - left + 1) + left);
if (pivotIndex == n) {
return arr[pivotIndex];
} else if (pivotIndex < n) {
left = pivotIndex + 1;
} else {
right = pivotIndex - 1;
}
}
return null;
}
private static void swap(Object[] arr, int i1, int i2) {
if (i1 != i2) {
Object temp = arr[i1];
arr[i1] = arr[i2];
arr[i2] = temp;
}
}
public static void main(String[] args) {
for (int i = 0; i < 10; i++) {
Integer[] input = {9, 8, 7, 6, 5, 0, 1, 2, 3, 4};
System.out.print(select(input, i));
if (i < 9) System.out.print(", ");
}
System.out.println();
}
}

View file

@ -0,0 +1,97 @@
/* NetRexx */
options replace format comments java crossref symbols nobinary
/** @see <a href="http://en.wikipedia.org/wiki/Quickselect">http://en.wikipedia.org/wiki/Quickselect</a> */
runSample(arg)
return
-- ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
method qpartition(list, ileft, iright, pivotIndex) private static
pivotValue = list[pivotIndex]
list = swap(list, pivotIndex, iright) -- Move pivot to end
storeIndex = ileft
loop i_ = ileft to iright - 1
if list[i_] <= pivotValue then do
list = swap(list, storeIndex, i_)
storeIndex = storeIndex + 1
end
end i_
list = swap(list, iright, storeIndex) -- Move pivot to its final place
return storeIndex
-- ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
method qselectInPlace(list, k_, ileft = -1, iright = -1) public static
if ileft = -1 then ileft = 1
if iright = -1 then iright = list[0]
loop label inplace forever
pivotIndex = Random().nextInt(iright - ileft + 1) + ileft -- select pivotIndex between left and right
pivotNewIndex = qpartition(list, ileft, iright, pivotIndex)
pivotDist = pivotNewIndex - ileft + 1
select
when pivotDist = k_ then do
returnVal = list[pivotNewIndex]
leave inplace
end
when k_ < pivotDist then
iright = pivotNewIndex - 1
otherwise do
k_ = k_ - pivotDist
ileft = pivotNewIndex + 1
end
end
end inplace
return returnVal
-- ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
method swap(list, i1, i2) private static
if i1 \= i2 then do
t1 = list[i1]
list[i1] = list[i2]
list[i2] = t1
end
return list
-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
method runSample(arg) private static
parse arg samplelist
if samplelist = '' | samplelist = '.' then samplelist = 9 8 7 6 5 0 1 2 3 4
items = samplelist.words
say 'Input:'
say ' 'samplelist.space(1, ',').changestr(',', ', ')
say
say 'Using in-place version of the algorithm:'
iv = ''
loop k_ = 1 to items
iv = iv qselectInPlace(buildIndexedString(samplelist), k_)
end k_
say ' 'iv.space(1, ',').changestr(',', ', ')
say
say 'Find the 4 smallest:'
iv = ''
loop k_ = 1 to 4
iv = iv qselectInPlace(buildIndexedString(samplelist), k_)
end k_
say ' 'iv.space(1, ',').changestr(',', ', ')
say
say 'Find the 3 largest:'
iv = ''
loop k_ = items - 2 to items
iv = iv qselectInPlace(buildIndexedString(samplelist), k_)
end k_
say ' 'iv.space(1, ',').changestr(',', ', ')
say
return
-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
method buildIndexedString(samplelist) private static
list = 0
list[0] = samplelist.words()
loop k_ = 1 to list[0]
list[k_] = samplelist.word(k_)
end k_
return list

View file

@ -0,0 +1,10 @@
let rec quickselect k = function
[] -> failwith "empty"
| x :: xs -> let ys, zs = List.partition ((>) x) xs in
let l = List.length ys in
if k < l then
quickselect k ys
else if k > l then
quickselect (k-l-1) zs
else
x

View file

@ -0,0 +1,28 @@
part(list, left, right, pivotIndex)={
my(pivotValue=list[pivotIndex],storeIndex=left,t);
t=list[pivotIndex];
list[pivotIndex]=list[right];
list[right]=t;
for(i=left,right-1,
if(list[i] <= pivotValue,
t=list[storeIndex];
list[storeIndex]=list[i];
list[i]=t;
storeIndex++
)
);
t=list[right];
list[right]=list[storeIndex];
list[storeIndex]=t;
storeIndex
};
quickselect(list, left, right, n)={
if(left==right,return(list[left]));
my(pivotIndex=part(list, left, right, random(right-left)+left));
if(pivotIndex==n,return(list[n]));
if(n < pivotIndex,
quickselect(list, left, pivotIndex - 1, n)
,
quickselect(list, pivotIndex + 1, right, n)
)
};

View file

@ -0,0 +1,59 @@
quick: procedure options (main); /* 4 April 2014 */
partition: procedure (list, left, right, pivot_Index) returns (fixed binary);
declare list (*) fixed binary;
declare (left, right, pivot_index) fixed binary;
declare (store_index, pivot_value) fixed binary;
declare I fixed binary;
pivot_Value = list(pivot_Index);
call swap (pivot_Index, right); /* Move pivot to end */
store_Index = left;
do i = left to right-1;
if list(i) < pivot_Value then
do;
call swap (store_Index, i);
store_Index = store_index + 1;
end;
end;
call swap (right, store_Index); /* Move pivot to its final place */
return (store_Index);
swap: procedure (i, j);
declare (i, j) fixed binary; declare t fixed binary;
t = list(i); list(i) = list(j); list(j) = t;
end swap;
end partition;
/* Returns the n-th smallest element of list within left..right inclusive */
/* (i.e. left <= n <= right). */
quick_select: procedure (list, left, right, n) recursive returns (fixed binary);
declare list(*) fixed binary;
declare (left, right, n) fixed binary;
declare pivot_index fixed binary;
if left = right then /* If the list contains only one element */
return ( list(left) ); /* Return that element */
pivot_Index = (left+right)/2;
/* select a pivot_Index between left and right, */
/* e.g. left + Math.floor(Math.random() * (right - left + 1)) */
pivot_Index = partition(list, left, right, pivot_Index);
/* The pivot is in its final sorted position. */
if n = pivot_Index then
return ( list(n) );
else if n < pivot_Index then
return ( quick_select(list, left, pivot_Index - 1, n) );
else
return ( quick_select(list, pivot_Index + 1, right, n) );
end quick_select;
declare a(10) fixed binary static initial (9, 8, 7, 6, 5, 0, 1, 2, 3, 4);
declare I fixed binary;
do i = 1 to 10;
put skip edit ('The ', trim(i), '-th element is ', quick_select((a), 1, 10, (i) )) (a);
end;
end quick;

View file

@ -0,0 +1,42 @@
my @v = <9 8 7 6 5 0 1 2 3 4>;
say map { select(@v, $_) }, 1 .. 10;
sub partition(@vector, $left, $right, $pivot-index) {
my $pivot-value = @vector[$pivot-index];
@vector[$pivot-index, $right] = @vector[$right, $pivot-index];
my $store-index = $left;
for $left ..^ $right -> $i {
if @vector[$i] < $pivot-value {
@vector[$store-index, $i] = @vector[$i, $store-index];
$store-index++;
}
}
@vector[$right, $store-index] = @vector[$store-index, $right];
return $store-index;
}
sub select( @vector,
\k where 1 .. @vector,
\l where 0 .. @vector = 0,
\r where l .. @vector = @vector.end ) {
my ($k, $left, $right) = k, l, r;
loop {
my $pivot-index = ($left..$right).pick;
my $pivot-new-index = partition(@vector, $left, $right, $pivot-index);
my $pivot-dist = $pivot-new-index - $left + 1;
given $pivot-dist <=> $k {
when Same {
return @vector[$pivot-new-index];
}
when Decrease {
$right = $pivot-new-index - 1;
}
when Increase {
$k -= $pivot-dist;
$left = $pivot-new-index + 1;
}
}
}
}

View file

@ -0,0 +1,19 @@
my @list = qw(9 8 7 6 5 0 1 2 3 4);
print join ' ', map { qselect(\@list, $_) } 1 .. 10 and print "\n";
sub qselect
{
my ($list, $k) = @_;
my $pivot = @$list[int rand @{ $list } - 1];
my @left = grep { $_ < $pivot } @$list;
my @right = grep { $_ > $pivot } @$list;
if ($k <= @left)
{
return qselect(\@left, $k);
}
elsif ($k > @left + 1)
{
return qselect(\@right, $k - @left - 1);
}
else { $pivot }
}

View file

@ -0,0 +1,45 @@
import random
def partition(vector, left, right, pivotIndex):
pivotValue = vector[pivotIndex]
vector[pivotIndex], vector[right] = vector[right], vector[pivotIndex] # Move pivot to end
storeIndex = left
for i in range(left, right):
if vector[i] < pivotValue:
vector[storeIndex], vector[i] = vector[i], vector[storeIndex]
storeIndex += 1
vector[right], vector[storeIndex] = vector[storeIndex], vector[right] # Move pivot to its final place
return storeIndex
def _select(vector, left, right, k):
"Returns the k-th smallest, (k >= 0), element of vector within vector[left:right+1] inclusive."
while True:
pivotIndex = random.randint(left, right) # select pivotIndex between left and right
pivotNewIndex = partition(vector, left, right, pivotIndex)
pivotDist = pivotNewIndex - left
if pivotDist == k:
return vector[pivotNewIndex]
elif k < pivotDist:
right = pivotNewIndex - 1
else:
k -= pivotDist + 1
left = pivotNewIndex + 1
def select(vector, k, left=None, right=None):
"""\
Returns the k-th smallest, (k >= 0), element of vector within vector[left:right+1].
left, right default to (0, len(vector) - 1) if omitted
"""
if left is None:
left = 0
lv1 = len(vector) - 1
if right is None:
right = lv1
assert vector and k >= 0, "Either null vector or k < 0 "
assert 0 <= left <= lv1, "left is out of range"
assert left <= right <= lv1, "right is out of range"
return _select(vector, left, right, k)
if __name__ == '__main__':
v = [9, 8, 7, 6, 5, 0, 1, 2, 3, 4]
print([select(v, i) for i in range(10)])

View file

@ -0,0 +1 @@
Data source: http://rosettacode.org/wiki/Quickselect_algorithm

View file

@ -0,0 +1,30 @@
/*REXX program sorts a list (which may be numbers) using quick select.*/
parse arg list; if list='' then list=9 8 7 6 5 0 1 2 3 4 /*default?*/
do #=1 for words(list); @.#=word(list,#); end /*#*/; #=#-1
/* [↓] #=number of items in list*/
do j=1 for # /*show 1 ──► # place and value.*/
say ' item' right(j,length(#))", value: " qSel(1,#,j)
end /*j*/
exit /*stick a fork in it, we're done.*/
/*──────────────────────────────────QPART subroutine────────────────────*/
qPart: procedure expose @.; parse arg L 1 ?,R,pivotIndex;pVal=@.pivotIndex
parse value @.pivotIndex @.R with @.R @.pivotIndex /*swap 2 items*/
do k=L to R-1 /*process the left side of list. */
if @.k>pVal then iterate /*when item>pivotValue, skip it. */
parse value @.? @.k with @.k @.? /*swap 2 items*/
?=?+1 /*next item. */
end /*k*/
parse value @.R @.? with @.? @.R /*swap 2 items*/
return ?
/*──────────────────────────────────QSEL subroutine─────────────────────*/
qSel: procedure expose @.; parse arg L,R,z; if L==R then return @.L
do forever /*keep looping until all done. */
pivotNewIndex=qPart(L, R, (L+R)%2) /*partition the list into ≈ ½. */
pivotDist=pivotNewIndex-L+1
if pivotDist==z then return @.pivotNewIndex
else if z<pivotDist then R=pivotNewIndex-1
else do
z=z-pivotDist
L=pivotNewindex+1
end
end /*forever*/

View file

@ -0,0 +1,11 @@
(define (quickselect A k)
(define pivot (list-ref A (random (length A))))
(define A1 (filter (curry > pivot) A))
(define A2 (filter (curry < pivot) A))
(cond
[(<= k (length A1)) (quickselect A1 k)]
[(> k (- (length A) (length A2))) (quickselect A2 (- k (- (length A) (length A2))))]
[else pivot]))
(define a '(9 8 7 6 5 0 1 2 3 4))
(display (string-join (map number->string (for/list ([k 10]) (quickselect a (+ 1 k)))) ", "))

View file

@ -0,0 +1,18 @@
def quickselect(a, k)
arr = a.dup # we will be modifying it
loop do
pivot = arr.delete_at(rand(arr.length))
left, right = arr.partition { |x| x < pivot }
if k == left.length
return pivot
elsif k < left.length
arr = left
else
k = k - left.length - 1
arr = right
end
end
end
v = [9, 8, 7, 6, 5, 0, 1, 2, 3, 4]
p v.each_index.map { |i| quickselect(v, i) }

View file

@ -0,0 +1,20 @@
import scala.util.Random
object QuickSelect {
def quickSelect[A <% Ordered[A]](seq: Seq[A], n: Int, rand: Random = new Random): A = {
val pivot = rand.nextInt(seq.length);
val (left, right) = seq.partition(_ < seq(pivot))
if (left.length == n) {
seq(pivot)
} else if (left.length < n) {
quickSelect(right, n - left.length, rand)
} else {
quickSelect(left, n, rand)
}
}
def main(args: Array[String]): Unit = {
val v = Array(9, 8, 7, 6, 5, 0, 1, 2, 3, 4)
println((0 until v.length).map(quickSelect(v, _)).mkString(", "))
}
}

View file

@ -0,0 +1,12 @@
fun quickselect (_, _, []) = raise Fail "empty"
| quickselect (k, cmp, x :: xs) = let
val (ys, zs) = List.partition (fn y => cmp (y, x) = LESS) xs
val l = length ys
in
if k < l then
quickselect (k, cmp, ys)
else if k > l then
quickselect (k-l-1, cmp, zs)
else
x
end

View file

@ -0,0 +1,50 @@
# Swap the values at two indices of a list
proc swap {list i j} {
upvar 1 $list l
set tmp [lindex $l $i]
lset l $i [lindex $l $j]
lset l $j $tmp
}
proc quickselect {vector k {left 0} {right ""}} {
set last [expr {[llength $vector] - 1}]
if {$right eq ""} {
set right $last
}
# Sanity assertions
if {![llength $vector] || $k <= 0} {
error "Either empty vector, or k <= 0"
} elseif {![tcl::mathop::<= 0 $left $last]} {
error "left is out of range"
} elseif {![tcl::mathop::<= $left $right $last]} {
error "right is out of range"
}
# the _select core, inlined
while 1 {
set pivotIndex [expr {int(rand()*($right-$left))+$left}]
# the partition core, inlined
set pivotValue [lindex $vector $pivotIndex]
swap vector $pivotIndex $right
set storeIndex $left
for {set i $left} {$i <= $right} {incr i} {
if {[lindex $vector $i] < $pivotValue} {
swap vector $storeIndex $i
incr storeIndex
}
}
swap vector $right $storeIndex
set pivotNewIndex $storeIndex
set pivotDist [expr {$pivotNewIndex - $left + 1}]
if {$pivotDist == $k} {
return [lindex $vector $pivotNewIndex]
} elseif {$k < $pivotDist} {
set right [expr {$pivotNewIndex - 1}]
} else {
set k [expr {$k - $pivotDist}]
set left [expr {$pivotNewIndex + 1}]
}
}
}

View file

@ -0,0 +1,4 @@
set v {9 8 7 6 5 0 1 2 3 4}
foreach i {1 2 3 4 5 6 7 8 9 10} {
puts "$i => [quickselect $v $i]"
}