@gkucmierz/utils 2.3.1 → 3.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gkucmierz/utils",
3
- "version": "2.3.1",
3
+ "version": "3.0.1",
4
4
  "type": "module",
5
5
  "description": "Usefull functions for solving programming tasks",
6
6
  "keywords": [
@@ -55,7 +55,7 @@
55
55
  "test": "jasmine",
56
56
  "watch": "nodemon --exec 'npm test'",
57
57
  "docs": "npm run docs:build; npm run docs:open",
58
- "build:main": "node scripts/generate_main.mjs",
58
+ "build:main": "node scripts/generate_main.mjs && node scripts/generate_instacode_links.mjs",
59
59
  "docs:build": "jsdoc -c jsdoc.json && cp -r docs/@gkucmierz/utils/*/* docs/ && rm -rf docs/@gkucmierz",
60
60
  "docs:open": "open docs/index.html",
61
61
  "lint": "eslint .",
@@ -76,6 +76,7 @@
76
76
  "husky": "^8.0.3",
77
77
  "jasmine": "^4.4.0",
78
78
  "jsdoc": "^4.0.4",
79
+ "lz-string": "^1.5.0",
79
80
  "nodemon": "^3.1.14"
80
81
  }
81
82
  }
package/src/SetCnt.mjs CHANGED
@@ -1,6 +1,7 @@
1
1
  /**
2
2
  * Set-like data structure built using Map with elements counter.
3
3
  * Allows adding multiple occurrences of the same element.
4
+ * @see {@link https://instacode.app/run/FASwtgDg9gTgLgAgN4IMoFM4GEB2iC+CAZjFGAgEQACA5gNYCuAxmCOjAF4D0DcIANgGcKAbmDAM2PGKA|▶ Try it live in Instacode}
4
5
  */
5
6
  export class SetCnt {
6
7
  #map = new Map();
package/src/Trie.mjs CHANGED
@@ -1,6 +1,7 @@
1
1
  /**
2
2
  * Creates a Trie (prefix tree) data structure.
3
3
  * Implemented as a proper ES6 Class to fix prototyping documentation and encapsulate nodes.
4
+ * @see {@link https://instacode.app/run/FASwtgDg9gTgLgAgN4ICoxAUwQXwQMxijAQCIABAcwGsBXAYzCxgC8B6WuEAGwGdSA3MGDosQoA|▶ Try it live in Instacode}
4
5
  */
5
6
  export class Trie {
6
7
  static #HAS = 0;
@@ -5,6 +5,7 @@
5
5
  * @param {Array} arr Target array
6
6
  * @param {function} pick Projection callback (defaults to identity function)
7
7
  * @returns {Map} Histogram mapping
8
+ * @see {@link https://instacode.app/run/FASwtgDg9gTgLgAgN4IIYxqgngCRAZzigHNMwEBfBAMxinICIABYgawFcBjMEAUxgBeAenZwQAG3wMA3MGDpMuAkVKowsoA|▶ Try it live in Instacode}
8
9
  */
9
10
  export const arrayHistogram = (iter, pick = el => el) => {
10
11
  const quant = new Map();
package/src/base64.mjs CHANGED
@@ -4,6 +4,7 @@
4
4
  * Handles Unicode characters correctly.
5
5
  * @param {string} string - The string to encode.
6
6
  * @returns {string} The Base64 encoded string.
7
+ * @see {@link https://instacode.app/run/FASwtgDg9gTgLgAgN4LlAQgQwM4FMBsALAgL4IBmMUYCARAAIDmA1gK4DGYIuMAXgPSs4IADbZaAbmDA0WPESlA|▶ Try it live in Instacode}
7
8
  */
8
9
  export const toBase64 = string => {
9
10
  const codeUnits = new Uint16Array(string.length);
@@ -18,6 +19,7 @@ export const toBase64 = string => {
18
19
  * Handles Unicode characters correctly.
19
20
  * @param {string} encoded - The Base64 encoded string.
20
21
  * @returns {string} The decoded string.
22
+ * @see {@link https://instacode.app/run/FASwtgDg9gTgLgAgN4IGYymAQgQwM4CmAbACwIC+aGYCARAAIDmA1gK4DGYIBMAXgPSs4IADZ5aAbmDB0mXIVJSgA|▶ Try it live in Instacode}
21
23
  */
22
24
  export const fromBase64 = encoded => {
23
25
  const binary = atob(encoded);
@@ -37,6 +39,7 @@ const toUrl = {
37
39
  * Replaces '+' with '-' and '/' with '_'.
38
40
  * @param {string} string - The string to encode.
39
41
  * @returns {string} The Base64Url encoded string.
42
+ * @see {@link https://instacode.app/run/FASwtgDg9gTgLgAgN4LlAQgQwM4FMBsALAKowA2CAvggGYxRgIBEAAgOYDWArgMZgi4YALwD0XOCDLYmAbmDA0WPEVJk5QA|▶ Try it live in Instacode}
40
43
  */
41
44
  export const toBase64Url = string => {
42
45
  return toBase64(string).replace(/[\+\/]/g, c => toUrl[c]);
@@ -51,6 +54,7 @@ const fromUrl = {
51
54
  * Replaces '-' with '+' and '_' with '/'.
52
55
  * @param {string} encoded - The Base64Url encoded string.
53
56
  * @returns {string} The decoded string.
57
+ * @see {@link https://instacode.app/run/FASwtgDg9gTgLgAgN4IGYymAQgQwM4CmAbACwCqMANggL5oZgIBEAAgOYDWArgMZggEYALwD0XOCEp4mAbmDB0mXIVIVKcoA|▶ Try it live in Instacode}
54
58
  */
55
59
  export const fromBase64Url = encoded => {
56
60
  return fromBase64(encoded.replace(/[\-\_]/g, c => fromUrl[c]));
@@ -4,6 +4,7 @@
4
4
  * @param {number} num - The number to convert.
5
5
  * @param {string} [alpha='12'] - The alphabet to use for the conversion.
6
6
  * @returns {string} The bijective base-k string representation.
7
+ * @see {@link https://instacode.app/run/FASwtgDg9gTgLgAgN4IHYFcwCYBGIBWApgMZwgBuhCAvggGYxRgIBEAAgOYDW6xYIhGAC8A9OjIAbAM4sA3MGAZseIqQqF5QA|▶ Try it live in Instacode}
7
8
  */
8
9
  export const num2bijective = (num, alpha = '12') => {
9
10
  const len = alpha.length;
@@ -28,6 +29,7 @@ export const num2bijective = (num, alpha = '12') => {
28
29
  * @param {string} str - The bijective base-k string to convert.
29
30
  * @param {string} [alpha='12'] - The alphabet used for the conversion.
30
31
  * @returns {number} The numeric value of the string.
32
+ * @see {@link https://instacode.app/run/FASwtgDg9gTgLgAgN4IEYgFYFMDGcQBuWATAHYCuYCAvggGYxRUBEAAgOYDW5OYIWMAF4B6cvgA2AZ2YBuYMHTY8hEhTBygA|▶ Try it live in Instacode}
31
33
  */
32
34
  export const bijective2num = (str, alpha = '12') => {
33
35
  const map = new Map([...alpha].map((c, i) => [c, i]));
@@ -43,6 +45,7 @@ export const bijective2num = (str, alpha = '12') => {
43
45
  * @param {bigint} num - The BigInt to convert.
44
46
  * @param {string} [alpha='12'] - The alphabet to use for the conversion.
45
47
  * @returns {string} The bijective base-k string representation.
48
+ * @see {@link https://instacode.app/run/FASwtgDg9gTgLgAgN4IHYFcwCYBGIBWApgMZwgBuhAQgJIIC+CAZjFGAgEQACA5gNbpiYEIRgAvAPToyAGwDOHANzBgGbHiKkK1GsqA|▶ Try it live in Instacode}
46
49
  */
47
50
  export const num2bijectiveBI = (num, alpha = '12') => {
48
51
  const len = BigInt(alpha.length);
@@ -67,6 +70,7 @@ export const num2bijectiveBI = (num, alpha = '12') => {
67
70
  * @param {string} str - The bijective base-k string to convert.
68
71
  * @param {string} [alpha='12'] - The alphabet used for the conversion.
69
72
  * @returns {bigint} The BigInt value of the string.
73
+ * @see {@link https://instacode.app/run/FASwtgDg9gTgLgAgN4IEYgFYFMDGcQBuWATAHYCuYAQgJIIC+CAZjFGAgEQACA5gNbkcYEFhgAvAPTl8AGwDOHANzBg6bHkIkK1GsqA|▶ Try it live in Instacode}
70
74
  */
71
75
  export const bijective2numBI = (str, alpha = '12') => {
72
76
  const map = new Map([...alpha].map((c, i) => [c, BigInt(i)]));
@@ -4,12 +4,13 @@
4
4
  * @param {Array<number>} arr - The sorted array to search in.
5
5
  * @param {number} target - The element to search for.
6
6
  * @returns {number} The index of the element if found, otherwise -1.
7
+ * @see {@link https://instacode.app/run/FASwtgDg9gTgLgAgN4IEYgHYEMYE8DKApjgMYAWAgjDAgL4IBmMUYCARAAIDmA1gK4kwIQjABeAej5wQAGwDObANzBg6bHiKlK1ZUA|▶ Try it live in Instacode}
7
8
  */
8
9
  export const binarySearchArr = (arr, target) => {
9
10
  let [a, b] = [0, arr.length];
10
11
  let lm;
11
12
  while (b - a > 0) {
12
- const mid = (a + b) / 2 | 0;
13
+ const mid = Math.trunc((a + b) / 2);
13
14
  const val = arr[mid];
14
15
  if (target < val) {
15
16
  b = mid;
@@ -29,12 +30,13 @@ export const binarySearchArr = (arr, target) => {
29
30
  * @param {Array<number>} arr - The sorted array to search in.
30
31
  * @param {number} target - The target value.
31
32
  * @returns {number} The index of the found element.
33
+ * @see {@link https://instacode.app/run/FASwtgDg9gTgLgAgN4IEYgHYEMYE8DKApjgMYAWAMgKIIC+CAZjFGAgEQACA5gNYCuJMCEIwAXgHo+cEABsAzmwDcwYOmx4ipSlWVA|▶ Try it live in Instacode}
32
34
  */
33
35
  export const binarySearchLE = (arr, target) => {
34
36
  let [a, b] = [0, arr.length];
35
37
  let lm;
36
38
  while (b - a > 0) {
37
- const mid = (a + b) / 2 | 0;
39
+ const mid = Math.trunc((a + b) / 2);
38
40
  const val = arr[mid];
39
41
  if (target < val) {
40
42
  b = mid;
@@ -52,12 +54,13 @@ export const binarySearchLE = (arr, target) => {
52
54
  * @param {Array<number>} arr - The sorted array to search in.
53
55
  * @param {number} target - The target value.
54
56
  * @returns {number} The index of the found element.
57
+ * @see {@link https://instacode.app/run/FASwtgDg9gTgLgAgN4IEYgHYEMYE8DKApjgMYAWA4gKIIC+CAZjFGAgEQACA5gNYCuJMCEIwAXgHo+cEABsAzmwDcwYOmx4ipSlWVA|▶ Try it live in Instacode}
55
58
  */
56
59
  export const binarySearchGE = (arr, target) => {
57
60
  let [a, b] = [0, arr.length];
58
61
  let lm;
59
62
  while (b - a > 0) {
60
- const mid = (a + b) / 2 | 0;
63
+ const mid = Math.trunc((a + b) / 2);
61
64
  const val = arr[mid];
62
65
  if (target > val) {
63
66
  a = mid;
@@ -76,6 +79,7 @@ export const binarySearchGE = (arr, target) => {
76
79
  * @param {Array<number>} arr - The sorted array to search in.
77
80
  * @param {number} target - The target value.
78
81
  * @returns {Array<number>} An array containing the start and end indices of the range [start, end].
82
+ * @see {@link https://instacode.app/run/FASwtgDg9gTgLgAgN4IEYgHYEMYE8DKApjgMYAWASlhgOaECSGJANggL4IBmMUYCARAAEaAawCuJMCEIwAXgHoxcEMwDO-ANzBg6bHiKlK1OoxZagA|▶ Try it live in Instacode}
79
83
  */
80
84
  export const binarySearchRangeIncl = (arr, target) => {
81
85
  return [
@@ -89,7 +93,7 @@ const binarySearchL = (arr, target) => {
89
93
  let [a, b] = [0, arr.length];
90
94
  let lm;
91
95
  while (b - a > 0) {
92
- const mid = (a + b) / 2 | 0;
96
+ const mid = Math.trunc((a + b) / 2);
93
97
  const val = arr[mid];
94
98
  if (target <= val) {
95
99
  b = mid;
@@ -107,7 +111,7 @@ const binarySearchG = (arr, target) => {
107
111
  let [a, b] = [0, arr.length];
108
112
  let lm;
109
113
  while (b - a > 0) {
110
- const mid = (a + b) / 2 | 0;
114
+ const mid = Math.trunc((a + b) / 2);
111
115
  const val = arr[mid];
112
116
  if (target >= val) {
113
117
  a = mid;
@@ -8,6 +8,7 @@
8
8
  * @param {number} n Size of the combination
9
9
  * @param {number} k Size of the set to choose from (indices 0 to k-1)
10
10
  * @yields {number[]} Array of indices
11
+ * @see {@link https://instacode.app/run/FASwtgDg9gTgLgAgN4IMZTAIxAOwIZwhQ4DOAknAKYwGwIC+CAZjBggEQACA5gNYCuqMCGoAvAPT9CAGxLsA3MGDosuAkVIVqtGIqA|▶ Try it live in Instacode}
11
12
  */
12
13
  export const combinationsIterator = function* (n, k) {
13
14
  if (n > k || n < 0) return;
@@ -35,6 +36,7 @@ export const combinationsIterator = function* (n, k) {
35
36
  * @param {number} n Size of the combination
36
37
  * @param {number} k Size of the set
37
38
  * @returns {Array<number[]>} Array containing all combinations
39
+ * @see {@link https://instacode.app/run/FASwtgDg9gTgLgAgN4IMZTAIxAOwIZwhQ4DOCAvggGYwYIBEAAgOYDWArqmCAKYwBeAenaEANiXoBuYMHRZcBIqWlA|▶ Try it live in Instacode}
38
40
  */
39
41
  export const combinations = (n, k) => {
40
42
  return [...combinationsIterator(n, k)];
@@ -5,6 +5,7 @@
5
5
  * @param {Iterator} iter - Iterator object with .next() method returning {value, done}
6
6
  * @param {function} progressFn - Callback function executed for each iteration Step
7
7
  * @returns {Promise} - Resolves when the iterator is fully consumed
8
+ * @see {@link https://instacode.app/run/FASwtgDg9gTgLgAgN4IMZQHYGcCuYCmAknPjAIZywBymAQgDZSoDWIGA5ggL4IBmMUMAgBEAAXbMcqMCFIAvAPQ44IelmEBuYMHTY8REuUowaGBk1YctQA|▶ Try it live in Instacode}
8
9
  */
9
10
  export const consumeIteratorNonBlocking = (iter, progressFn) => {
10
11
  return new Promise((resolve, reject) => {
package/src/copy-case.mjs CHANGED
@@ -5,6 +5,7 @@
5
5
  * @param {string} word - The string to change the case of.
6
6
  * @param {string} from - The source string providing the case pattern.
7
7
  * @returns {string} The converted string.
8
+ * @see {@link https://instacode.app/run/FASwtgDg9gTgLgAgN4IMZQgTwMIEMDOApggL4IBmMUYCARAAIDmA1gK6pgiEwBeA9KzggANvloBuYMHRY8RSUA|▶ Try it live in Instacode}
8
9
  */
9
10
  export const copyCase = (word, from) => {
10
11
  const isLower = w => w.toLowerCase() === w;
package/src/egcd.mjs CHANGED
@@ -6,12 +6,13 @@
6
6
  * @param {number} a - The first number.
7
7
  * @param {number} b - The second number.
8
8
  * @returns {number[]} An array [gcd, x, y] such that ax + by = gcd.
9
+ * @see {@link https://instacode.app/run/FASwtgDg9gTgLgAgN4IKYHMDGATBBfBAMxijAQCIABdAawFdMwRUYAvAejrhABsBncgG5gwDDmFA|▶ Try it live in Instacode}
9
10
  */
10
11
  export const egcd = (a, b) => {
11
12
  let [x, y] = [0, 1];
12
13
  let [u, v] = [1, 0];
13
14
  while (a !== 0) {
14
- const [q, r] = [b/a | 0, b%a];
15
+ const [q, r] = [Math.trunc(b / a), b % a];
15
16
  const [m, n] = [x - u * q, y - v * q];
16
17
  [b, a, x, y, u, v] = [a, r, u, v, m, n];
17
18
  }
package/src/factors.mjs CHANGED
@@ -3,6 +3,7 @@
3
3
  * Calculates the prime factorization of a number.
4
4
  * @param {number} n - The number to factorize.
5
5
  * @returns {number[]} An array of prime factors.
6
+ * @see {@link https://instacode.app/run/FASwtgDg9gTgLgAgN4IGYEMDGdYGcEC+aMUYCARAAIDmA1gK6ZggCmMAXgPT1wgA2ucgG5gwDNjwigA|▶ Try it live in Instacode}
6
7
  */
7
8
  export const factors = n => {
8
9
  if (n < 2) return [];
@@ -24,6 +25,7 @@ export const factors = n => {
24
25
  * Calculates the prime factorization of a BigInt.
25
26
  * @param {bigint} n - The BigInt to factorize.
26
27
  * @returns {bigint[]} An array of prime factors as BigInts.
28
+ * @see {@link https://instacode.app/run/FASwtgDg9gTgLgAgN4IGYEMDGdYGcBCAkggL5oxRgIBEAAgOYDWArpmCAKYwBeA9M3BAAbXNQDcwYBmx4iEoA|▶ Try it live in Instacode}
27
29
  */
28
30
  export const factorsBI = n => {
29
31
  if (n < 2n) return [];
@@ -26,6 +26,7 @@ const formatBigNumberBoth = (num, separator = '', wrapFn = _ => _) => {
26
26
  * @param {string} [separator=''] - The string to use as a thousand separator.
27
27
  * @param {function(string): string} [wrapFn=_=>_] - Optional function to wrap each part of the number.
28
28
  * @returns {string} The formatted number.
29
+ * @see {@link https://instacode.app/run/FASwtgDg9gTgLgAgN4IGazAQzgIRAcwDkBXMAIwFMYEBfNGKMBAIgAF8BrYgYzBCoBeAemJwQAGwDOzANzBg6GFlwES5KnKA|▶ Try it live in Instacode}
29
30
  */
30
31
  export const formatBigNumber = formatBigNumberBoth;
31
32
 
@@ -36,6 +37,7 @@ export const formatBigNumber = formatBigNumberBoth;
36
37
  * @param {string} [separator=''] - The string to use as a thousand separator.
37
38
  * @param {function(string): string} [wrapFn=_=>_] - Optional function to wrap each part of the number.
38
39
  * @returns {string} The formatted number.
40
+ * @see {@link https://instacode.app/run/FASwtgDg9gTgLgAgN4IGazAQzgIRAcwDkBXMAIwFMYcBJBAXzRijAQCIABfAa2IGMwIKgC8A9MTggANgGc2AbmDB0MLLgIlyVWoqA|▶ Try it live in Instacode}
39
41
  */
40
42
  export const formatBigNumberBI = formatBigNumberBoth;
41
43
 
package/src/gcd.mjs CHANGED
@@ -20,6 +20,7 @@ const getGCD = ZERO => {
20
20
  * @param {number} a - The first number.
21
21
  * @param {number} b - The second number.
22
22
  * @returns {number} The GCD of a and b.
23
+ * @see {@link https://instacode.app/run/FASwtgDg9gTgLgAgN4IOYGMAmCC+CBmMUYCARAAKoDWArumCAKYwBeA9DXCADYDOpAbmDAMmIUA|▶ Try it live in Instacode}
23
24
  */
24
25
  export const gcd = getGCD(0);
25
26
 
@@ -28,5 +29,6 @@ export const gcd = getGCD(0);
28
29
  * @param {bigint} a - The first BigInt.
29
30
  * @param {bigint} b - The second BigInt.
30
31
  * @returns {bigint} The GCD of a and b.
32
+ * @see {@link https://instacode.app/run/FASwtgDg9gTgLgAgN4IOYGMAmAhAkggXwQDMYowEAiAAVQGsBXdMEAUxgC8B6BuEAGwDOlANzBgGHLjFA|▶ Try it live in Instacode}
31
33
  */
32
34
  export const gcdBI = getGCD(0n);
package/src/get-type.mjs CHANGED
@@ -4,6 +4,7 @@
4
4
  * More specific than the typeof operator (e.g., distinguishes 'array', 'null', 'date').
5
5
  * @param {*} val - The value to check.
6
6
  * @returns {string} The type of the value.
7
+ * @see {@link https://instacode.app/run/FASwtgDg9gTgLgAgN4IOYFM4BUCeF0IC+CAZjFGAgEQACqA1gK4DGYI6MAXgPSNwgAbAM5UA3MGAZsedOKA|▶ Try it live in Instacode}
7
8
  */
8
9
  export const getType = val => {
9
10
  const str = Object.prototype.toString.call(val);
@@ -3,6 +3,7 @@ import { squareRootBI } from './square-root.mjs';
3
3
  /**
4
4
  * The standard float approximation of the Golden Ratio (phi).
5
5
  * @constant {number}
6
+ * @see {@link https://instacode.app/run/FASwtgDg9gTgLgAgN4IOZQDYBMCmA7AJQEM4QoEBfBAMxijAQCIABVAawFcBjMEHGAF4B6DqQwBnRgG5gwdNnzFSUGUA|▶ Try it live in Instacode}
6
7
  */
7
8
  export const goldenRatio = ((5 ** 0.5) + 1) / 2;
8
9
 
@@ -14,6 +15,7 @@ export const goldenRatio = ((5 ** 0.5) + 1) / 2;
14
15
  * @param {number|bigint} precision - The number of decimal places to calculate.
15
16
  * @returns {BigInt} A boxed BigInt representing the Golden Ratio scaled by 10^precision.
16
17
  * @throws {Error} If precision is negative.
18
+ * @see {@link https://instacode.app/run/FASwtgDg9gTgLgAgN4IOZQDYBMCmA7AJQEM4QoAhASQQF8EAzGKMBAIgAFUBrAVwGMwIHDABeAeh6kMAZ1YBuYMHTZ8xUhUoKgA|▶ Try it live in Instacode}
17
19
  */
18
20
  export const goldenRatioBI = precision => {
19
21
  if (precision < 0) throw new Error('Precision cannot be negative');
package/src/gpn.mjs CHANGED
@@ -17,6 +17,7 @@ const getGpn = (zero, one, two, three) => {
17
17
  * https://oeis.org/A001318
18
18
  * @param {number} n - The index of the sequence (0-based).
19
19
  * @returns {number} The n-th generalized pentagonal number.
20
+ * @see {@link https://instacode.app/run/FASwtgDg9gTgLgAgN4IOYQHYIL4IGYxRgIBEAAqgNYCuAxmCAKYwBeA9NXCADYDOJAbmDB0GIUA|▶ Try it live in Instacode}
20
21
  */
21
22
  export const gpn = getGpn(0, 1, 2, 3);
22
23
 
@@ -24,5 +25,6 @@ export const gpn = getGpn(0, 1, 2, 3);
24
25
  * Generalized Pentagonal Numbers (GPN) - BigInt version.
25
26
  * @param {bigint} n - The index of the sequence (0-based).
26
27
  * @returns {bigint} The n-th generalized pentagonal number.
28
+ * @see {@link https://instacode.app/run/FASwtgDg9gTgLgAgN4IOYQHYCECSCC+CAZjFGAgEQACqA1gK4DGYIApjAF4D09cIANgGcKAbmDB02HGKA|▶ Try it live in Instacode}
27
29
  */
28
30
  export const gpnBI = getGpn(0n, 1n, 2n, 3n);
package/src/gray-code.mjs CHANGED
@@ -11,6 +11,7 @@ const convertBit = (p, v, i) => {
11
11
  *
12
12
  * @param {Array<number|boolean>} bits Binary representation (MSB at index 0)
13
13
  * @returns {Array<number>} Array of Gray code bits
14
+ * @see {@link https://instacode.app/run/FASwtgDg9gTgLgAgN4IEYgHYCYDmMCGAnggL4IBmMUYCARAAI4DWArgMZggCmMAXgPQs4IADYBnWgG5gwdNjxFpQA|▶ Try it live in Instacode}
14
15
  */
15
16
  export const bin2gray = (bits) => {
16
17
  // Cloning array mathematically to prevent pure-function reference mutation
@@ -22,6 +23,7 @@ export const bin2gray = (bits) => {
22
23
  *
23
24
  * @param {Array<number|boolean>} gray Gray Code representation
24
25
  * @returns {Array<number>} Decoded original binary bits
26
+ * @see {@link https://instacode.app/run/FASwtgDg9gTgLgAgN4IOYwIYE8BMAjEAOwQF8EAzGKMBAIgAFUBrAVwGMwQBTGALwHoWcEABsAzrQDcwYOmz4i0oA|▶ Try it live in Instacode}
25
27
  */
26
28
  export const gray2bin = (gray) => {
27
29
  return [...gray].reduce(convertBit, [...gray]);
package/src/heap.mjs CHANGED
@@ -2,6 +2,7 @@
2
2
  * Creates a Min Heap data structure.
3
3
  * Implemented as a ES6 Class to fix prototyping documentation
4
4
  * and properly encapsulate internal mechanics.
5
+ * @see {@link https://instacode.app/run/FASwtgDg9gTgLgAgN4IBIFMCGEEF8EBmMUYCARAAIDmA1gK4DGYI6MAXgPR1wgA2AzmQDcwYBmwigA|▶ Try it live in Instacode}
5
6
  */
6
7
  export class Heap {
7
8
  #arr = [-1];
@@ -17,7 +18,7 @@ export class Heap {
17
18
 
18
19
  #up(idx) {
19
20
  while (idx > 1) {
20
- const ni = idx / 2 | 0;
21
+ const ni = Math.trunc(idx / 2);
21
22
  if (this.#valFn(this.#arr[idx]) < this.#valFn(this.#arr[ni])) {
22
23
  [this.#arr[idx], this.#arr[ni]] = [this.#arr[ni], this.#arr[idx]];
23
24
  }
@@ -16,6 +16,7 @@ const getHeronsFormula = (four, sq) => (a, b, c) => {
16
16
  * @param {number} b - Length of side b.
17
17
  * @param {number} c - Length of side c.
18
18
  * @returns {number} The area of the triangle.
19
+ * @see {@link https://instacode.app/run/FASwtgDg9gTgLgAgN4IBYFMZQHYGcBisYArgDYCGCAvggGZZgIBEAAgOYDWxAxmCJgC8A9MTghSuJgG5gwDFjyEYJCjKA|▶ Try it live in Instacode}
19
20
  */
20
21
  export const heronsFormula = getHeronsFormula(4, n => n ** 0.5);
21
22
 
@@ -26,5 +27,6 @@ export const heronsFormula = getHeronsFormula(4, n => n ** 0.5);
26
27
  * @param {bigint} b - Length of side b.
27
28
  * @param {bigint} c - Length of side c.
28
29
  * @returns {bigint} The area of the triangle.
30
+ * @see {@link https://instacode.app/run/FASwtgDg9gTgLgAgN4IBYFMZQHYGcBisYArgDYCGAQgJIIC+CAZlmAgEQACA5gNbEDGYEJgBeAemJwQpXGwDcwYBix5CMEhRoKgA|▶ Try it live in Instacode}
29
31
  */
30
32
  export const heronsFormulaBI = getHeronsFormula(4n, squareRootBI);
@@ -3,6 +3,7 @@
3
3
  * Ideal for sparse matrices or algorithms operating on an infinite plane (e.g., Langton's Ant, Game of Life).
4
4
  *
5
5
  * @returns {Object} An object containing `get(x, y)` and `set(x, y, val)` methods.
6
+ * @see {@link https://instacode.app/run/FASwtgDg9gTgLgAgN4IMYwKYEM4YKoB2ANuCLgCYDiMI5CAvggGYxRgIBEAAgOYDWAV1RgQGGAC8A9ALggiAZw4BuYMHTZchEiIrVaKoA|▶ Try it live in Instacode}
6
7
  */
7
8
  export const createUnlimitedGrid = () => {
8
9
  const grid = new Map();
@@ -38,6 +39,7 @@ export const createUnlimitedGrid = () => {
38
39
  * @param {number} startY - The initial Y coordinate of the ant.
39
40
  * @param {number} [initialDir=-1] - The initial direction (0: TOP, 1: RIGHT, 2: BOTTOM, 3: LEFT). If -1, a random direction is chosen.
40
41
  * @returns {Object} An object containing a `step()` method which advances the simulation by one tick and returns `{x, y, state}` of the modified cell.
42
+ * @see {@link https://instacode.app/run/FASwtgDg9gTgLgAgN4IMYwKYEM4YDJYB2A5nFIQM4CChiAvggGYxRgIBEAAsQNYCuqMCAwwAXgHo+cEABsK7ANzBg6bLgIkylGnCVA|▶ Try it live in Instacode}
41
43
  */
42
44
  export const createLangtonsAnt = (grid, startX, startY, initialDir = -1) => {
43
45
  const [X, Y] = [0, 1];
package/src/lcm.mjs CHANGED
@@ -15,6 +15,7 @@ const getLcm = gcd => {
15
15
  * @param {number} a - The first number.
16
16
  * @param {number} b - The second number.
17
17
  * @returns {number} The LCM of a and b.
18
+ * @see {@link https://instacode.app/run/FASwtgDg9gTgLgAgN4IDYGMwIL4IGYxRYBEAAgOYDWArpiAKYwBeA9NXCKgM7EDcwwDGH5A|▶ Try it live in Instacode}
18
19
  */
19
20
  export const lcm = getLcm(gcd);
20
21
 
@@ -23,5 +24,6 @@ export const lcm = getLcm(gcd);
23
24
  * @param {bigint} a - The first BigInt.
24
25
  * @param {bigint} b - The second BigInt.
25
26
  * @returns {bigint} The LCM of a and b.
27
+ * @see {@link https://instacode.app/run/FASwtgDg9gTgLgAgN4IDYGMwCECSCC+CAZjFGAgEQACA5gNYCumIApjAF4D0DcIqAzhQDcwYBmw4RQA|▶ Try it live in Instacode}
26
28
  */
27
29
  export const lcmBI = getLcm(gcdBI);
package/src/list-node.mjs CHANGED
@@ -2,6 +2,7 @@
2
2
 
3
3
  /**
4
4
  * Represents a node in a singly linked list.
5
+ * @see {@link https://instacode.app/run/FASwtgDg9gTgLgAgN4IDIgM5wHJQCYCmCAvggGYxRgIBEAAgOYDWArgMZggEwBeA9CzggANhhoBuYMHRZchSUA|▶ Try it live in Instacode}
5
6
  */
6
7
  export class ListNode {
7
8
  /**
@@ -4,6 +4,7 @@
4
4
  * @param {number|bigint} exp - The exponent p of the Mersenne number M_p.
5
5
  * @param {boolean} [verbose=false] - If true, logs the calculation progress.
6
6
  * @returns {boolean} True if the Mersenne number is prime, false otherwise.
7
+ * @see {@link https://instacode.app/run/FASwtgDg9gTgLgAgN4IDYFcDGBDAzgGQFMALMQmAIQEkEBfBAMxijAQCIABAcwGsswQ5AF4B6dHBCpcbANzBgGHARJlKVOUA|▶ Try it live in Instacode}
7
8
  */
8
9
  export const lucasLehmerBI = (exp, verbose = false) => {
9
10
  const steps = exp - 2;
package/src/math3d.mjs CHANGED
@@ -1,5 +1,6 @@
1
1
  /**
2
2
  * Pure 3D Math Engine for Arcball/Trackball raw matrix transformations
3
+ * @see {@link https://instacode.app/run/FASwtgDg9gTgLgAgN4IMYygZ0wBQwEwFdVEBfBAMwzAQCIABAcwGtiwQBTGALwHpC4IADaZaAbmDB0WXAWJwJQA|▶ Try it live in Instacode}
3
4
  */
4
5
 
5
6
  export const crossProduct = (u, v) => [
package/src/matrix.mjs CHANGED
@@ -5,6 +5,7 @@
5
5
  * Allows accessing elements using a single index (row-major order).
6
6
  * @param {Array<Array<*>>} matrix - The 2D matrix to wrap.
7
7
  * @returns {Proxy} A proxy that behaves like a flat array.
8
+ * @see {@link https://instacode.app/run/FASwtgDg9gTgLgAgN4LAQzjEAPAggZ1xhjQE8EBfBAMxijAQCIABAcwGsBXAYzBAFMYALwD0nOCAA2+RgG5gwdJhwEiJUvKA|▶ Try it live in Instacode}
8
9
  */
9
10
  export const matrixAsArray = matrix => {
10
11
  const [h, w] = [matrix.length, matrix[0].length];
@@ -2,10 +2,12 @@
2
2
  * Measures the execution time of a given function by running it multiple times.
3
3
  * Useful for micro-benchmarking and performance comparison.
4
4
  *
5
+ *
5
6
  * @param {Function} fn - The function to benchmark.
6
7
  * @param {number} [steps=1e8] - The number of iterations to run the function.
7
8
  * @param {string} [memo='noop'] - A descriptive label for the benchmark result.
8
9
  * @returns {Object} An object containing the `memo` and the `duration` (in milliseconds).
10
+ * @see {@link https://instacode.app/run/FASwtgDg9gTgLgAgN4LAUwIYGcCuM0AKaMAZrGBgHYDGaCAvgiTFGAgEQACA5gNY7UwIYgC8A9DjggANlnYBuYMHTY8hYmRgUaaRUA|▶ Try it live in Instacode}
9
11
  */
10
12
  export const measurePerformance = (fn, steps = 1e8, memo = 'noop') => {
11
13
  const t1 = Date.now();
package/src/memoize.mjs CHANGED
@@ -5,6 +5,7 @@
5
5
  * Compares arguments by reference.
6
6
  * @param {Function} fn - The function to memoize.
7
7
  * @returns {Function} The memoized function.
8
+ * @see {@link https://instacode.app/run/FASwtgDg9gTgLgAgN4LAUzFEAvNCC+CAZjFGAgEQACA5gNYCuAxmCGjNgPQNwgA2AZwoBuYMHSYcaUUA|▶ Try it live in Instacode}
8
9
  */
9
10
  export const memoize = fn => {
10
11
  const maps = [];
package/src/mod.mjs CHANGED
@@ -14,6 +14,7 @@ const getMod = ZERO => {
14
14
  * @param {number} dividend - The dividend.
15
15
  * @param {number} divisor - The divisor.
16
16
  * @returns {number} The result of the modulo operation.
17
+ * @see {@link https://instacode.app/run/FASwtgDg9gTgLgAgN4LFAJggvggZjKMBAIgAEBzAawFcBjMEAUxgC8B6auEAGwGdiA3MGBp0QoA|▶ Try it live in Instacode}
17
18
  */
18
19
  export const mod = getMod(0);
19
20
 
@@ -22,5 +23,6 @@ export const mod = getMod(0);
22
23
  * @param {bigint} dividend - The dividend.
23
24
  * @param {bigint} divisor - The divisor.
24
25
  * @returns {bigint} The result of the modulo operation.
26
+ * @see {@link https://instacode.app/run/FASwtgDg9gTgLgAgN4LFAJgIQJIIL4IBmMUYCARAAIDmA1gK4DGYIApjAF4D09cIANgGdyAbmDA0WbGKA|▶ Try it live in Instacode}
25
27
  */
26
28
  export const modBI = getMod(0n);
@@ -7,6 +7,7 @@
7
7
  * @param {number|bigint|string} n Total elements
8
8
  * @param {number|bigint|string} k Elements to pick
9
9
  * @returns {bigint} Total possible subset combinations
10
+ * @see {@link https://instacode.app/run/FASwtgDg9gTgLgAgN4IHYGEAWUoGcCmA0ggL4IBmMUYCARAAIDmA1gK4DGYI+MAXgPSs4IADa5aAbmDAM2PESlA|▶ Try it live in Instacode}
10
11
  */
11
12
  export const nChooseK = (n, k) => {
12
13
  const bigN = BigInt(n);
@@ -5,6 +5,7 @@
5
5
  * @param {Function} cond - The condition evaluator function.
6
6
  * @param {Boolean} [retFirstTrue=true] - If true, returns the first match bounding condition true.
7
7
  * @returns {Number} The optimized integer step boundary that satisfies the condition structure.
8
+ * @see {@link https://instacode.app/run/FASwtgDg9gTgLgAgN4IHYEM4FcboDYDKApujAMYAWCAvggGYxRgIBEAAgOYDWWZYIRGAC8A9Fjgg8AZxYBuYMAzZchEuQrygA|▶ Try it live in Instacode}
8
9
  */
9
10
  export const naturalSearch = (cond, retFirstTrue = true) => {
10
11
  let min = 1;
@@ -6,6 +6,7 @@
6
6
  * @param {Array<Array<Number>>} bounds - [[min1, max1], ... ] bounds per dimension
7
7
  * @param {Object} options - { steps: 30, onProgress: async (state) => {} }
8
8
  * @returns {Promise<{bestParams: Array<Number>, bestScore: Number}>}
9
+ * @see {@link https://instacode.app/run/FASwtgDg9gTgLgAgN4IHYFMA2ATdMCy6AhtggL4IBmMUYCARAAIDmA1gK4DGYIeAXgHp2cEJgDO9ANzBgGHHkIlpQA|▶ Try it live in Instacode}
9
10
  */
10
11
  export const nelderMead = async (evaluate, bounds, options = {}) => {
11
12
  const steps = options.steps || 30;
@@ -6,6 +6,7 @@
6
6
  * @param {Array<Array<Number>>} bounds - [[min1, max1], [min2, max2], ...] bounds per dimension
7
7
  * @param {Object} options - { particles: 10, steps: 30, w: 0.5, c1: 1.5, c2: 1.5, onProgress: async (state) => {} }
8
8
  * @returns {Promise<{bestParams: Array<Number>, bestScore: Number}>}
9
+ * @see {@link https://instacode.app/run/FASwtgDg9gTgLgAgN4IgQ3iAxgGwKYDKA7hmAPIRzggBeaVUAdggL4IBmMUYCARAAIBzANYBXLGBB4YNAPSiqOAM68A3MGDpMuQiRjlK1Og0bqgA|▶ Try it live in Instacode}
9
10
  */
10
11
  export const particleSwarmOptimization = async (evaluate, bounds, options = {}) => {
11
12
  const numParticles = options.particles || 12;
@@ -3,6 +3,7 @@
3
3
  *
4
4
  * @param {number|Array} sizeOrArr Integer size or an array of items
5
5
  * @yields {Array} Re-arranged array of items/indices
6
+ * @see {@link https://instacode.app/run/FASwtgDg9gTgLgAgN4IgUxmArnAhnEKAOwGcBJODfWBAXwQDMYowEAiAAQHMBrLAYzAgMALwD0OEABsSbANzBg6TDnyFSFKnFgKgA|▶ Try it live in Instacode}
6
7
  */
7
8
  export const permutationsIterator = function*(sizeOrArr) {
8
9
  const arr = Array.isArray(sizeOrArr) ? [...sizeOrArr] : new Array(sizeOrArr).fill(0).map((_, i) => i);
@@ -28,6 +29,7 @@ export const permutationsIterator = function*(sizeOrArr) {
28
29
  *
29
30
  * @param {number|Array} sizeOrArr
30
31
  * @returns {Array<Array>} Array of permutation sets
32
+ * @see {@link https://instacode.app/run/FASwtgDg9gTgLgAgN4IgUxmArnAhnEKAOwGcEBfBAMxijAQCIABAcwGssBjMEDALwD0OEABsSDANzBg6TDnyFSUoA|▶ Try it live in Instacode}
31
33
  */
32
34
  export const permutations = (sizeOrArr) => {
33
35
  return [...permutationsIterator(sizeOrArr)];
package/src/phi.mjs CHANGED
@@ -37,6 +37,7 @@ const getPhiEuler = factors => {
37
37
  * Uses Euler's product formula based on prime factorization.
38
38
  * @param {number} n - The number to calculate phi for.
39
39
  * @returns {number} The value of phi(n).
40
+ * @see {@link https://instacode.app/run/FASwtgDg9gTgLgAgN4IgCxAgvggZjKMBAIgAEBzAawFcBjMEAUxgC8B6auEAGwGdiA3MGDoQQoA|▶ Try it live in Instacode}
40
41
  */
41
42
  export const phi = getPhiEuler(factors);
42
43
 
@@ -44,6 +45,7 @@ export const phi = getPhiEuler(factors);
44
45
  * Euler's Totient Function (Phi) - BigInt version.
45
46
  * @param {bigint} n - The BigInt to calculate phi for.
46
47
  * @returns {bigint} The value of phi(n).
48
+ * @see {@link https://instacode.app/run/FASwtgDg9gTgLgAgN4IgCxAIQJIIL4IBmMUYCARAAIDmA1gK4DGYIApjAF4D09cIANgGdyAbmDB0WbGKA|▶ Try it live in Instacode}
47
49
  */
48
50
  export const phiBI = getPhiEuler(factorsBI);
49
51
 
package/src/pow-mod.mjs CHANGED
@@ -3,6 +3,7 @@
3
3
 
4
4
  const getPowMod = (ZERO, ONE, TWO, floor) => {
5
5
  return (base, exponent, modulus = null) => {
6
+ if (exponent < ZERO) throw new RangeError('Negative exponent is not supported');
6
7
  if (modulus === null) return base ** exponent;
7
8
  if (modulus === ONE) return ZERO;
8
9
  let result = ONE;
@@ -25,6 +26,7 @@ const getPowMod = (ZERO, ONE, TWO, floor) => {
25
26
  * @param {number} exponent - The exponent.
26
27
  * @param {number} [modulus] - The optional modulus.
27
28
  * @returns {number} The result of (base ** exponent) % modulus.
29
+ * @see {@link https://instacode.app/run/FASwtgDg9gTgLgAgN4OgdwLJQCYIL4IBmMUYCARAAIDmA1gK4DGYIApjAF4D09cIANgGdyAbmDB0WbGKA|▶ Try it live in Instacode}
28
30
  */
29
31
  export const powMod = getPowMod(0, 1, 2, n => Math.floor(n));
30
32
 
@@ -35,5 +37,6 @@ export const powMod = getPowMod(0, 1, 2, n => Math.floor(n));
35
37
  * @param {bigint} exponent - The exponent BigInt.
36
38
  * @param {bigint} [modulus] - The optional modulus BigInt.
37
39
  * @returns {bigint} The result of (base ** exponent) % modulus.
40
+ * @see {@link https://instacode.app/run/FASwtgDg9gTgLgAgN4OgdwLJQCYCECSCAvggGYxRgIBEAAgOYDWArgMZggCmMAXgPTM4IADYBnagG5gwdFjz4pQA|▶ Try it live in Instacode}
38
41
  */
39
42
  export const powModBI = getPowMod(0n, 1n, 2n, n => n);
@@ -4,6 +4,7 @@
4
4
  * @param {number} [mean=0] - The mean of the normal distribution.
5
5
  * @param {number} [sigma=1] - The standard deviation of the normal distribution.
6
6
  * @returns {number} A random number from the specified normal distribution.
7
+ * @see {@link https://instacode.app/run/FASwtgDg9gTgLgAgN4JgQwHYBMBysxoA2CAvggGYxRgIBEAAgOYDWArgMZggCmMAXgHpWcEIQDOtANzBg6bHhgFC0oA|▶ Try it live in Instacode}
7
8
  */
8
9
  export const randNormal = (mean = 0, sigma = 1) => {
9
10
  const y1 = Math.random();
@@ -5,6 +5,7 @@
5
5
  * Converts a list of ranges into a flat array of numbers.
6
6
  * @param {Array<Array<number>>} ranges - An array of ranges, where each range is [min, max] or [min].
7
7
  * @returns {Array<number>} An array containing all numbers in the specified ranges.
8
+ * @see {@link https://instacode.app/run/FASwtgDg9gTgLgAgN4JgQwHYHMCmAmNGdATwQF8EAzGKMBAIgAEsBrAVwGMwQcYAvAPRs4IADYBnegG5gwdNnyESMoA|▶ Try it live in Instacode}
8
9
  */
9
10
  export const range2array = ranges => {
10
11
  return ranges.reduce((arr, range) => {
@@ -22,6 +23,7 @@ export const range2array = ranges => {
22
23
  * Isolated numbers are represented as [num, num].
23
24
  * @param {Array<number>} arr - The sorted array of numbers.
24
25
  * @returns {Array<Array<number>>} An array of ranges.
26
+ * @see {@link https://instacode.app/run/FASwtgDg9gTgLgAgN4IIYxqgngJkwOwHMBTBAXwQDMYowEAiAAUIGsBXAYzBGJgC8A9GzggANgGd6AbmDB0mXARIygA|▶ Try it live in Instacode}
25
27
  */
26
28
  export const array2range = arr => {
27
29
  const ranges = [];
@@ -8,6 +8,7 @@
8
8
  * @param {boolean} [immediate=true] - Whether to fire the first execution immediately
9
9
  * @param {boolean} [nextTick=false] - If immediate is true, whether to yield to the event loop before the first execution
10
10
  * @returns {Function} A function to clear the interval
11
+ * @see {@link https://instacode.app/run/FASwtgDg9gTgLgAgN4IM4FM4GUCGAzdASQDs50YA3HAGwQF8E8YowEAiAAQHMBrAVwDGYEOQBeAej5wQ1VGwDcwYBmz4ipclWqKgA|▶ Try it live in Instacode}
11
12
  */
12
13
  export const setSafeInterval = (cb, delay, immediate = true, nextTick = false) => {
13
14
  let isCleared = false;
@@ -6,6 +6,7 @@
6
6
  * @param {Array<Array<Number>>} bounds - [[min1, max1], [min2, max2], ...] bounds per dimension
7
7
  * @param {Object} options - { steps: 100, initialTemp: 100, finalTemp: 0.1, onProgress: async (state) => {} }
8
8
  * @returns {Promise<{bestParams: Array<Number>, bestScore: Number}>}
9
+ * @see {@link https://instacode.app/run/FASwtgDg9gTgLgAgN4IM7gK4BsCGcCmAJgIIB2p+OWIpA5ggL4IBmMUYCARAAK0DWGAMZgQ+GAC8A9BjggsqTgG5gwdGGx4iZClRq1lQA|▶ Try it live in Instacode}
9
10
  */
10
11
  export const simulatedAnnealing = async (evaluate, bounds, options = {}) => {
11
12
  const steps = options.steps || 100;
@@ -4,6 +4,7 @@
4
4
  * Calculates the square root of a number.
5
5
  * @param {number} n - The number to calculate the square root of.
6
6
  * @returns {number} The square root of n.
7
+ * @see {@link https://instacode.app/run/FASwtgDg9gTgLgAgN4IM4EcCuBDGBTAJSikQF8EAzGKMBAIgAEBzAa0wGMwQ8YAvAekxwQAG1R0A3MGAYc+IiSlA|▶ Try it live in Instacode}
7
8
  */
8
9
  export const squareRoot = n => n ** 0.5;
9
10
 
@@ -11,8 +12,10 @@ export const squareRoot = n => n ** 0.5;
11
12
  * Calculates the integer square root of a BigInt using Newton's method.
12
13
  * @param {bigint} n - The BigInt to calculate the square root of.
13
14
  * @returns {bigint} The integer square root of n.
15
+ * @see {@link https://instacode.app/run/FASwtgDg9gTgLgAgN4IM4EcCuBDGBTAJSijgCEBJBAXwQDMYowEAiAAQHMBrTAYzBDwwAXgHpMcEABtUzANzBgGHPiIkK8oA|▶ Try it live in Instacode}
14
16
  */
15
17
  export const squareRootBI = n => {
18
+ if (n < 0n) throw new RangeError('Square root of negative numbers is not supported');
16
19
  if (n === 0n) return 0n;
17
20
  if (n < 4n) return 1n;
18
21
  if (n < 9n) return 2n;
@@ -9,6 +9,7 @@ import {
9
9
  * @param {bigint} n - The number to find the square root of.
10
10
  * @param {bigint} p - The modulus (must be an odd prime).
11
11
  * @returns {bigint} The square root r such that r^2 = n (mod p), or 0n if no solution exists.
12
+ * @see {@link https://instacode.app/run/FASwtgDg9gTgLgAgN4LlAdgUwDbZAZQAsBDdAawGcAhASQQF8EAzGKMBAIgAEBzMgVwDGYEJhgAvAPT84IbBQ4BuYMDRZcBEuWo1lQA|▶ Try it live in Instacode}
12
13
  */
13
14
  export const tonelliShanksBI = (n, p) => {
14
15
  let s = 0n;