array-order
Advanced tools
Comparing version 2.1.0 to 2.2.0
/** | ||
* @typedef {Array|Int8Array|Uint8Array|Int16Array|Uint16Array|Int32Array|Uint32Array|Uint8ClampedArray|Float32Array|Float64Array} ArrayLike | ||
* @typedef {Array|Int8Array|Int16Array|Int32Array|Float32Array|Float64Array} SignedArrayLike | ||
*/ | ||
@@ -10,3 +11,3 @@ /** | ||
* | ||
* @param {ArrayLike} src array to be fliped | ||
* @param {SignedArrayLike} src array to be fliped | ||
* @param {ArrayLike} [tgt] destination else inplace | ||
@@ -13,0 +14,0 @@ * @return {ArrayLike} |
@@ -12,2 +12,1 @@ export {default as flip} from './flip.js' | ||
export {default as rotate} from './rotate.js' | ||
export {default as derange} from './derange.js' |
{ | ||
"name": "array-order", | ||
"version": "2.1.0", | ||
"version": "2.2.0", | ||
"type": "module", | ||
@@ -5,0 +5,0 @@ "main": "./index.js", |
@@ -0,36 +1,47 @@ | ||
import swap from './swap.js' | ||
/** | ||
* In place mutation to generate all permutations of a source array | ||
* heap algorithm: most efficient permutation generating algorithm (fewest swaps) | ||
* | ||
* @typedef {Array|Int8Array|Uint8Array|Int16Array|Uint16Array|Int32Array|Uint32Array|Uint8ClampedArray|Float32Array|Float64Array} ArrayLike | ||
* @param {ArrayLike} a source array to be mutated | ||
* @return {()=>ArrayLike} mutation generating function | ||
*/ | ||
import sequence from './sequence.js' | ||
import swap from './swap.js' | ||
export default function(a, n=a.length) { | ||
const c = new Uint16Array(n) | ||
let i= 0 | ||
while (i<n) c[i++] = 0 | ||
return function() { | ||
i = 0 | ||
while (c[i] >= i) { | ||
c[i] = 0 | ||
if (++i===n) { // reset to the initial source sequence | ||
if (!(n&1)) { //even sources require more magic | ||
swap(a, 0, n-2) | ||
left(a, 1, n-2) | ||
} | ||
swap(a, 0, n-1) | ||
return a //same as the initial sequence | ||
} | ||
} | ||
swap(a, i, i&1 ? c[i] : 0) | ||
++c[i] | ||
return a | ||
} | ||
} | ||
/** | ||
* Steinhaus-Johnson-Trotter with Even speedup | ||
* @param {number|ArrayLike} seq if number, generates a sequence, else, in-place permutation | ||
* @param {number} [len] if only part of the array needs to be permuted | ||
* @return {ArrayLike} | ||
* In-place left-shift of array items from i to j | ||
* @typedef {Array|Int8Array|Uint8Array|Int16Array|Uint16Array|Int32Array|Uint32Array|Uint8ClampedArray|Float32Array|Float64Array} ArrayLike | ||
* @param {Array} a | ||
* @param {number} i | ||
* @param {number} j | ||
* @return {void} | ||
*/ | ||
export default function(seq, len) { | ||
const pos = seq.length ? seq : sequence(seq), | ||
N = len ?? pos.length, | ||
dir = Array(N).fill(-1) | ||
/* will generate N!-1 results */ | ||
return function () { | ||
let iM = -1 // largest mobile @ iM | ||
for (let i=0; i<N; ++i) if ( | ||
( pos[i] > pos[i + dir[i]]) /* isMobile */ | ||
&& !( pos[i] < pos[iM]) /* isMax */ | ||
) iM = i | ||
if (iM<0) { | ||
dir.fill(-1) | ||
swap(pos, 0, 1) | ||
} else { | ||
let jM = iM + dir[iM] | ||
swap(pos, iM, jM) | ||
swap(dir, iM, jM) | ||
for (let i=0; i<N; ++i) if (pos[i] > pos[jM]) dir[i] = -dir[i] | ||
} | ||
return pos | ||
export function left(a, i=0, j=a.length-1) { | ||
if (j>i) { | ||
const t = a[i] | ||
while(i<j) a[i]=a[++i] | ||
a[j] = t | ||
} | ||
} |
/** | ||
* @typedef {Array|Int8Array|Uint8Array|Int16Array|Uint16Array|Int32Array|Uint32Array|Uint8ClampedArray|Float32Array|Float64Array} ArrayLike | ||
* @typedef {Array|Int8Array|Int16Array|Int32Array|Float32Array|Float64Array} SignedArrayLike | ||
*/ | ||
@@ -11,3 +12,3 @@ | ||
* | ||
* @param {ArrayLike} ref order to apply to the source array | ||
* @param {SignedArrayLike} ref order to apply to the source array | ||
* @param {ArrayLike} src array to be ordered | ||
@@ -14,0 +15,0 @@ * @param {ArrayLike} [tgt] destination, inplace if absent |
import t from 'assert-op' | ||
import {derange} from '../index.js' | ||
import derange from '../util/derange.js' | ||
@@ -4,0 +4,0 @@ t('uniquely deranged', a => { |
17244
544