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,57 @@
BEGIN
# returns the kth lowest element of list using the quick select algorithm #
PRIO QSELECT = 1;
OP QSELECT = ( INT k, REF[]INT list )INT:
IF LWB list > UPB list THEN
# empty list #
0
ELSE
# non-empty list #
# partitions the subset of list from left to right #
PROC partition = ( REF[]INT list, INT left, right, pivot index )INT:
BEGIN
# swaps elements a and b in list #
PROC swap = ( REF[]INT list, INT a, b )VOID:
BEGIN
INT t = list[ a ];
list[ a ] := list[ b ];
list[ b ] := t
END # swap # ;
INT pivot value = list[ pivot index ];
swap( list, pivot index, right );
INT store index := left;
FOR i FROM left TO right - 1 DO
IF list[ i ] < pivot value THEN
swap( list, store index, i );
store index +:= 1
FI
OD;
swap( list, right, store index );
store index
END # partition # ;
INT left := LWB list, right := UPB list, result := 0;
BOOL found := FALSE;
WHILE NOT found DO
IF left = right THEN
result := list[ left ];
found := TRUE
ELSE
INT pivot index = partition( list, left, right, left + ENTIER ( ( random * ( right - left ) + 1 ) ) );
IF k = pivot index THEN
result := list[ k ];
found := TRUE
ELIF k < pivot index THEN
right := pivot index - 1
ELSE
left := pivot index + 1
FI
FI
OD;
result
FI # QSELECT # ;
# test cases #
FOR i TO 10 DO
[ 1 : 10 ]INT test := []INT( 9, 8, 7, 6, 5, 0, 1, 2, 3, 4 );
print( ( whole( i, -2 ), ": ", whole( i QSELECT test, -3 ), newline ) )
OD
END

View file

@ -0,0 +1,71 @@
// this just helps make partition read better
function swap(items, firstIndex, secondIndex) {
var temp = items[firstIndex];
items[firstIndex] = items[secondIndex];
items[secondIndex] = temp;
};
// many algorithms on this page violate
// the constraint that partition operates in place
function partition(array, from, to) {
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/random
var pivotIndex = getRandomInt(from, to),
pivot = array[pivotIndex];
swap(array, pivotIndex, to);
pivotIndex = from;
for(var i = from; i <= to; i++) {
if(array[i] < pivot) {
swap(array, pivotIndex, i);
pivotIndex++;
}
};
swap(array, pivotIndex, to);
return pivotIndex;
};
// later versions of JS have TCO so this is safe
function quickselectRecursive(array, from, to, statistic) {
if(array.length === 0 || statistic > array.length - 1) {
return undefined;
};
var pivotIndex = partition(array, from, to);
if(pivotIndex === statistic) {
return array[pivotIndex];
} else if(pivotIndex < statistic) {
return quickselectRecursive(array, pivotIndex, to, statistic);
} else if(pivotIndex > statistic) {
return quickselectRecursive(array, from, pivotIndex, statistic);
}
};
function quickselectIterative(array, k) {
if(array.length === 0 || k > array.length - 1) {
return undefined;
};
var from = 0, to = array.length,
pivotIndex = partition(array, from, to);
while(pivotIndex !== k) {
pivotIndex = partition(array, from, to);
if(pivotIndex < k) {
from = pivotIndex;
} else if(pivotIndex > k) {
to = pivotIndex;
}
};
return array[pivotIndex];
};
KthElement = {
find: function(array, element) {
var k = element - 1;
return quickselectRecursive(array, 0, array.length, k);
// you can also try out the Iterative version
// return quickselectIterative(array, k);
}
}

View file

@ -0,0 +1,3 @@
var array = [9, 8, 7, 6, 5, 0, 1, 2, 3, 4],
ks = Array.apply(null, {length: 10}).map(Number.call, Number);
ks.map(k => { KthElement.find(array, k) });

View file

@ -0,0 +1 @@
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9];

View file

@ -0,0 +1,52 @@
(() => {
'use strict';
// QUICKSELECT ------------------------------------------------------------
// quickselect :: Ord a => Int -> [a] -> a
const quickSelect = (k, xxs) => {
const
[x, xs] = uncons(xxs),
[ys, zs] = partition(v => v < x, xs),
l = length(ys);
return (k < l) ? (
quickSelect(k, ys)
) : (k > l) ? (
quickSelect(k - l - 1, zs)
) : x;
};
// GENERIC FUNCTIONS ------------------------------------------------------
// enumFromTo :: Int -> Int -> [Int]
const enumFromTo = (m, n) =>
Array.from({
length: Math.floor(n - m) + 1
}, (_, i) => m + i);
// length :: [a] -> Int
const length = xs => xs.length;
// map :: (a -> b) -> [a] -> [b]
const map = (f, xs) => xs.map(f);
// partition :: Predicate -> List -> (Matches, nonMatches)
// partition :: (a -> Bool) -> [a] -> ([a], [a])
const partition = (p, xs) =>
xs.reduce((a, x) =>
p(x) ? [a[0].concat(x), a[1]] : [a[0], a[1].concat(x)], [
[],
[]
]);
// uncons :: [a] -> Maybe (a, [a])
const uncons = xs => xs.length ? [xs[0], xs.slice(1)] : undefined;
// TEST -------------------------------------------------------------------
const v = [9, 8, 7, 6, 5, 0, 1, 2, 3, 4];
return map(i => quickSelect(i, v), enumFromTo(0, length(v) - 1));
})();

View file

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

View file

@ -0,0 +1,45 @@
// version 1.1.2
const val MAX = Int.MAX_VALUE
val rand = java.util.Random()
fun partition(list:IntArray, left: Int, right:Int, pivotIndex: Int): Int {
val pivotValue = list[pivotIndex]
list[pivotIndex] = list[right]
list[right] = pivotValue
var storeIndex = left
for (i in left until right) {
if (list[i] < pivotValue) {
val tmp = list[storeIndex]
list[storeIndex] = list[i]
list[i] = tmp
storeIndex++
}
}
val temp = list[right]
list[right] = list[storeIndex]
list[storeIndex] = temp
return storeIndex
}
tailrec fun quickSelect(list: IntArray, left: Int, right: Int, k: Int): Int {
if (left == right) return list[left]
var pivotIndex = left + Math.floor((rand.nextInt(MAX) % (right - left + 1)).toDouble()).toInt()
pivotIndex = partition(list, left, right, pivotIndex)
if (k == pivotIndex)
return list[k]
else if (k < pivotIndex)
return quickSelect(list, left, pivotIndex - 1, k)
else
return quickSelect(list, pivotIndex + 1, right, k)
}
fun main(args: Array<String>) {
val list = intArrayOf(9, 8, 7, 6, 5, 0, 1, 2, 3, 4)
val right = list.size - 1
for (k in 0..9) {
print(quickSelect(list, 0, right, k))
if (k < 9) print(", ")
}
println()
}

View file

@ -0,0 +1,30 @@
(seed (in "/dev/urandom" (rd 8)))
(de swapL (Lst X Y)
(let L (nth Lst Y)
(swap
L
(swap (nth Lst X) (car L)) ) ) )
(de partition (Lst L R P)
(let V (get Lst P)
(swapL Lst R P)
(for I (range L R)
(and
(> V (get Lst I))
(swapL Lst L I)
(inc 'L) ) )
(swapL Lst L R)
L ) )
(de quick (Lst N L R)
(default L (inc N) R (length Lst))
(if (= L R)
(get Lst L)
(let P (partition Lst L R (rand L R))
(cond
((= N P) (get Lst N))
((> P N) (quick Lst N L P))
(T (quick Lst N P R)) ) ) ) )
(let Lst (9 8 7 6 5 0 1 2 3 4)
(println
(mapcar
'((N) (quick Lst N))
(range 0 9) ) ) )

View file

@ -1,10 +1,10 @@
/*REXX program sorts a list (which may be numbers) by using the quick select algorithm. */
parse arg list; if list='' then list=9 8 7 6 5 0 1 2 3 4 /*Not given? Use default.*/
say right('list: ', 22) list
#=words(list)
do i=1 for #; @.i=word(list, i) /*assign all the items ──► @. (array). */
end /*i*/ /* [↑] #: number of items in the list.*/
say
do #=1 for words(list); @.#=word(list,#) /*assign all the items ──► @. (array). */
end /*#*/ /* [↑] #: number of items in the list.*/
#=#-1 /*adjust number of items in the list. */
do j=1 for # /*show 1 ──► # items place and value.*/
say right('item', 20) right(j, length(#))", value: " qSel(1, #, j)
end /*j*/

View file

@ -1,10 +1,10 @@
/*REXX program sorts a list (which may be numbers) by using the quick select algorithm. */
parse arg list; if list='' then list=9 8 7 6 5 0 1 2 3 4 /*Not given? Use default.*/
say right('list: ', 22) list
#=words(list)
do i=1 for #; @.i=word(list, i) /*assign all the items ──► @. (array). */
end /*i*/ /* [↑] #: number of items in the list.*/
say
do #=1 for words(list); @.#=word(list,#) /*assign all the items ──► @. (array). */
end /*#*/ /* [↑] #: number of items in the list.*/
#=#-1 /*adjust number of items in the list. */
do j=1 for # /*show 1 ──► # items place and value.*/
say right('item', 20) right(j, length(#))", value: " qSel(1, #, j)
end /*j*/

View file

@ -0,0 +1,23 @@
fcn qselect(list,nth){ // in place quick select
fcn(list,left,right,nth){
if (left==right) return(list[left]);
pivotIndex:=(left+right)/2; // or median of first,middle,last
// partition
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 (list[i] < pivot){
list.swap(i,pivotIndex);
pivotIndex += 1;
}
i += 1;
}
list.swap(pivotIndex,right); // move pivot to final place
if (nth==pivotIndex) return(list[nth]);
if (nth<pivotIndex) return(self.fcn(list,left,pivotIndex-1,nth));
return(self.fcn(list,pivotIndex+1,right,nth));
}(list.copy(),0,list.len()-1,nth);
}

View file

@ -0,0 +1,2 @@
list:=T(10, 9, 8, 7, 6, 1, 2, 3, 4, 5);
foreach nth in (list.len()){ println(nth,": ",qselect(list,nth)) }