Skip to content

Commit

Permalink
🐛 chore: clean TODO
Browse files Browse the repository at this point in the history
  • Loading branch information
wolfram77 committed May 7, 2023
1 parent f552871 commit ac30d7d
Show file tree
Hide file tree
Showing 5 changed files with 146 additions and 94 deletions.
85 changes: 1 addition & 84 deletions TODO
Original file line number Diff line number Diff line change
@@ -1,15 +1,4 @@
SORTS, IN PAIR

Instead of mapFn, provide pair array to define sort mapping.
selectionSort, insertionSort, bubbleSort, mergeSort, (are all stable?)
quickSort, shellSort, radixSort, timSort, heapSort
https://en.wikipedia.org/wiki/Sorting_algorithm
https://www.npmjs.com/package/sort-algorithms-js
https://dl.acm.org/doi/10.5555/1778580.1778601
https://stackoverflow.com/questions/463105/in-place-radix-sort/474040#474040


MINNTH, MAXNTH, SORTEDSLICE (ARRAYVIEW)
MINNTH, MAXNTH

Need only part of sorted array? [bag][nth] ...
Selection algorithm: Quickselect
Expand All @@ -23,75 +12,3 @@ PARSE, OTHERS

INDEX -VE
- moveWithin


OLD SORT ALGORITHMS

/**
* Arrange values in order!
* @param x an array (updated!)
* @param fc compare function (a, b)
* @param fm map function (v, i, x)
* @param fs swap function (x, i, j)
* @returns x | x[i] ≤ x[j] ∀ i ≤ j
*/
function bubbleSort$<T, U=T>(x: T[], fc: CompareFunction<T|U> | null=null, fm: MapFunction<T, T|U> | null=null, fs: SwapFunction<T> | null=null): T[] {
var fc = fc || COMPARE;
var fm = fm || IDENTITY; // TODO: use map function
var fs = fs || swap$;
var X = x.length;
for (var i=0; i<X-1; ++i) {
for (var j=i+1; j<X; ++j)
if (fc(x[i], x[j]) > 0) fs(x, i, j);
}
return x;
}


/**
* Arrange values in order!
* @param x an array (updated!)
* @param fc compare function (a, b)
* @param fm map function (v, i, x)
* @param fs swap function (x, i, j)
* @returns x | x[i] ≤ x[j] ∀ i ≤ j
*/
function selectionSort$<T, U=T>(x: T[], fc: CompareFunction<T|U> | null=null, fm: MapFunction<T, T|U> | null=null, fs: SwapFunction<T> | null=null): T[] {
var fc = fc || COMPARE;
var fm = fm || IDENTITY; // TODO: use map function
var fs = fs || swap$;
var X = x.length;
for (var i=0; i<X-1; ++i) {
var l = i;
for (var j=i+1; j<X; ++j)
if (fc(x[l], x[j]) > 0) l = j;
fs(x, i, l);
}
return x;
}


// TODO: Check if this is correct!
/**
* Arrange values in order!
* @param x an array (updated!)
* @param fc compare function (a, b)
* @param fm map function (v, i, x)
* @param fs swap function (x, i, j)
* @returns x | x[i] ≤ x[j] ∀ i ≤ j
*/
function insertionSortOld$<T, U=T>(x: T[], fc: CompareFunction<T|U> | null=null, fm: MapFunction<T, T|U> | null=null, fs: SwapFunction<T> | null=null): T[] {
var fc = fc || COMPARE;
var fm = fm || IDENTITY; // TODO: use map function
var fs = fs || swap$; // TODO: use swap function
var X = x.length;
for (var i=X-2; i>=0; --i) {
var xv = x[i], mv = x[i];
for (var j=i+1; j<X; j++) {
if (fc(mv, x[j]) <= 0) break;
x[j-1] = x[j];
}
x[j-1] = xv;
}
return x;
}
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "extra-array",
"version": "4.0.1",
"version": "4.0.2",
"description": "An array is a collection of values, stored contiguously.",
"main": "index.js",
"module": "index.mjs",
Expand Down
147 changes: 141 additions & 6 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -673,10 +673,11 @@ export {countEach as countAs}; // DEPRECATED
* @param fm map function (v, i, x)
* @returns v | v ≤ vᵢ; vᵢ ∈ x
*/
export function min<T, U=T>(x: T[], fc: CompareFunction<T|U> | null=null, fm: MapFunction<T, T|U> | null=null): T {
export function minimum<T, U=T>(x: T[], fc: CompareFunction<T|U> | null=null, fm: MapFunction<T, T|U> | null=null): T {
var i = searchMinimumValue(x, fc, fm);
return x[i];
}
export {minimum as min};


/**
Expand All @@ -686,10 +687,11 @@ export function min<T, U=T>(x: T[], fc: CompareFunction<T|U> | null=null, fm: Ma
* @param fm map function (v, i, x)
* @returns [min_index, min_value]
*/
export function minEntry<T, U=T>(x: T[], fc: CompareFunction<T|U> | null=null, fm: MapFunction<T, T|U> | null=null): [number, T] {
export function minimumEntry<T, U=T>(x: T[], fc: CompareFunction<T|U> | null=null, fm: MapFunction<T, T|U> | null=null): [number, T] {
var i = searchMinimumValue(x, fc, fm);
return [i, x[i]];
}
export {minimumEntry as minEntry};


/**
Expand All @@ -699,10 +701,11 @@ export function minEntry<T, U=T>(x: T[], fc: CompareFunction<T|U> | null=null, f
* @param fm map function (v, i, x)
* @returns v | v ≥ vᵢ; vᵢ ∈ x
*/
export function max<T, U=T>(x: T[], fc: CompareFunction<T|U> | null=null, fm: MapFunction<T, T|U> | null=null): T {
export function maximum<T, U=T>(x: T[], fc: CompareFunction<T|U> | null=null, fm: MapFunction<T, T|U> | null=null): T {
var i = searchMaximumValue(x, fc, fm);
return x[i];
}
export {maximum as max};


/**
Expand All @@ -712,10 +715,11 @@ export function max<T, U=T>(x: T[], fc: CompareFunction<T|U> | null=null, fm: Ma
* @param fm map function (v, i, x)
* @returns [max_index, max_value]
*/
export function maxEntry<T, U=T>(x: T[], fc: CompareFunction<T|U> | null=null, fm: MapFunction<T, T|U> | null=null): [number, T] {
export function maximumEntry<T, U=T>(x: T[], fc: CompareFunction<T|U> | null=null, fm: MapFunction<T, T|U> | null=null): [number, T] {
var i = searchMaximumValue(x, fc, fm);
return [i, x[i]];
}
export {maximumEntry as maxEntry};


/**
Expand Down Expand Up @@ -753,6 +757,62 @@ export function rangeEntries<T, U=T>(x: T[], fc: CompareFunction<T|U> | null=nul
}
return [[mi, mv], [ni, nv]];
}


/**
* Find smallest values.
* @param x an array
* @param n number of values
* @param fc compare function (a, b)
* @param fm map function (v, i, x)
* @returns n smallest values in ascending order
*/
export function minimums<T, U=T>(x: T[], n: number, fc: CompareFunction<T|U> | null=null, fm: MapFunction<T, T|U> | null=null): T[] {
var is = searchMinimumValues(x, n, fc, fm);
return is.map(i => x[i]);
}


/**
* Find smallest entries.
* @param x an array
* @param n number of values
* @param fc compare function (a, b)
* @param fm map function (v, i, x)
* @returns n smallest entries in ascending order
*/
export function minimumEntries<T, U=T>(x: T[], n: number, fc: CompareFunction<T|U> | null=null, fm: MapFunction<T, T|U> | null=null): [number, T][] {
var is = searchMinimumValues(x, n, fc, fm);
return is.map(i => [i, x[i]]);
}


/**
* Find largest values.
* @param x an array
* @param n number of values
* @param fc compare function (a, b)
* @param fm map function (v, i, x)
* @returns n largest values in descending order
*/
export function maximums<T, U=T>(x: T[], n: number, fc: CompareFunction<T|U> | null=null, fm: MapFunction<T, T|U> | null=null): T[] {
var is = searchMaximumValues(x, n, fc, fm);
return is.map(i => x[i]);
}


/**
* Find largest entries.
* @param x an array
* @param n number of values
* @param fc compare function (a, b)
* @param fm map function (v, i, x)
* @returns n largest entries in descending order
*/
export function maximumEntries<T, U=T>(x: T[], n: number, fc: CompareFunction<T|U> | null=null, fm: MapFunction<T, T|U> | null=null): [number, T][] {
var is = searchMaximumValues(x, n, fc, fm);
return is.map(i => [i, x[i]]);
}
// #endregion


Expand Down Expand Up @@ -1498,6 +1558,51 @@ export function searchMaximumValue<T, U=T>(x: T[], fc: CompareFunction<T|U> | nu
}


/**
* Find indices of minimum values.
* @param x an array
* @param n number of values
* @param fc compare function (a, b)
* @param fm map function (v, i, x)
* @returns indices of minimum values in ascending order
*/
export function searchMinimumValues<T, U=T>(x: T[], n: number, fc: CompareFunction<T|U> | null=null, fm: MapFunction<T, T|U> | null=null): number[] {
var fc = fc || COMPARE;
var fm = fm || IDENTITY;
var X = x.length;
// Create a max heap of indices.
var IH = Math.min(n, X);
var ih = fromRange(0, IH);
buildMaxHeap$(ih, 0, IH, fc, i => fm(x[i], i, x), swapRaw$);
var wr = fm(x[ih[0]], ih[0], x);
// Search for minimum values, and update heap.
for (var i=n; i<X; ++i) {
var w = fm(x[i], i, x);
if (fc(w, wr) >= 0) continue;
ih[0] = i; wr = w;
maxHeapify$(ih, 0, IH, 0, fc, i => fm(x[i], i, x), swapRaw$);
}
// Sort max heap in ascending order.
ih.sort((i, j) => fc(fm(x[i], i, x), fm(x[j], j, x)));
return ih;
}


/**
* Find indices of maximum values.
* @param x an array
* @param n number of values
* @param fc compare function (a, b)
* @param fm map function (v, i, x)
* @returns indices of maximum values in descending order
*/
export function searchMaximumValues<T, U=T>(x: T[], n: number, fc: CompareFunction<T|U> | null=null, fm: MapFunction<T, T|U> | null=null): number[] {
var fc = fc || COMPARE;
var fd = (a: T|U, b: T|U) => -fc(a, b);
return searchMinimumValues(x, n, fd, fm);
}


/**
* Find first index of an unsorted value.
* @param x an array
Expand Down Expand Up @@ -3272,8 +3377,8 @@ function buildReverseMinHeap$<T, U=T>(x: T[], i: number, I: number, fc: CompareF
*/
function reverseMinHeapify$<T, U=T>(x: T[], i: number, I: number, r: number, fc: CompareFunction<T|U>, fm: MapFunction<T, T|U>, fs: SwapFunction<T>): void {
var s = r; // Index of smallest value
var lt = 2*r - I; // Reverse of lt = 2*r+1
var rt = lt - 1; // Reverse of rt = 2*r+2
var lt = 2*r - I; // Left child, reverse of lt = 2*r+1
var rt = lt - 1; // Right child, reverse of rt = 2*r+2
if (lt>=i && fc(fm(x[lt], lt, x), fm(x[s], s, x)) < 0) s = lt; // Left child is smaller?
if (rt>=i && fc(fm(x[rt], rt, x), fm(x[s], s, x)) < 0) s = rt; // Right child is smaller?
if (s !== r) { // Smallest is not root?
Expand All @@ -3283,6 +3388,36 @@ function reverseMinHeapify$<T, U=T>(x: T[], i: number, I: number, r: number, fc:
}


// Build a max-heap, where root node is the smallest and placed at the beginning.
function buildMaxHeap$<T, U=T>(x: T[], i: number, I: number, fc: CompareFunction<T|U>, fm: MapFunction<T, T|U>, fs: SwapFunction<T>): void {
for (var r=i+Math.floor((I-i)/2)-1; r>=i; --r)
maxHeapify$(x, i, I, r, fc, fm, fs);
}


/**
* Max-heapify values, such that root node is the largest and placed at the beginning.
* @param x an array (updated!)
* @param i start index
* @param I end index (exclusive)
* @param r root index
* @param fc compare function (a, b)
* @param fm map function (v, i, x)
* @param fs swap function (x, i, j)
*/
function maxHeapify$<T, U=T>(x: T[], i: number, I: number, r: number, fc: CompareFunction<T|U>, fm: MapFunction<T, T|U>, fs: SwapFunction<T>): void {
var s = r; // Index of largest value
var lt = 2*r - i + 1; // Left child, like lt = 2*r+1
var rt = lt + 1; // Right child, like rt = 2*r+2
if (lt<I && fc(fm(x[lt], lt, x), fm(x[s], s, x)) > 0) s = lt; // Left child is larger?
if (rt<I && fc(fm(x[rt], rt, x), fm(x[s], s, x)) > 0) s = rt; // Right child is larger?
if (s !== r) { // Largest is not root?
fs(x, s, r); // Swap root with largest
maxHeapify$(x, i, I, s, fc, fm, fs); // Rebuild heap
}
}


/**
* Partially arrange values in order!
* @param x an array (updated!)
Expand Down
2 changes: 1 addition & 1 deletion wiki
Submodule wiki updated from 1706a1 to 934905

0 comments on commit ac30d7d

Please sign in to comment.