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