functionalscript 0.4.2 → 0.4.3

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.
@@ -0,0 +1,28 @@
1
+ /**
2
+ * Provides an implementation of HMAC (Hash-based Message Authentication Code).
3
+ *
4
+ * https://en.wikipedia.org/wiki/HMAC
5
+ *
6
+ * @module
7
+ *
8
+ * @example
9
+ *
10
+ * ```ts
11
+ * import { vec } from '../../types/bit_vec/module.f.ts'
12
+ * import { msbUtf8 } from '../../text/module.f.ts'
13
+ * import { sha256 } from '../sha2/module.f.ts'
14
+ *
15
+ * const r = hmac(sha256)(msbUtf8('key'))(msbUtf8('The quick brown fox jumps over the lazy dog'))
16
+ * if (r !== vec(256n)(0xf7bc83f430538424b13298e6aa6fb143ef4d59a14946175997479dbc2d1a3cd8n)) { throw r }
17
+ * ```
18
+ */
19
+ import { type Vec } from '../../types/bit_vec/module.f.ts';
20
+ import { type Sha2 } from '../sha2/module.f.ts';
21
+ /**
22
+ * Generates an HMAC (Hash-based Message Authentication Code) using the specified SHA-2 hash function.
23
+ *
24
+ * @param sha2 - The SHA-2 hash function implementation to use.
25
+ * @returns - A function that takes a key and returns another function
26
+ * that takes a message and computes the HMAC.
27
+ */
28
+ export declare const hmac: (sha2: Sha2) => (k: Vec) => (m: Vec) => Vec;
@@ -0,0 +1,60 @@
1
+ /**
2
+ * Provides an implementation of HMAC (Hash-based Message Authentication Code).
3
+ *
4
+ * https://en.wikipedia.org/wiki/HMAC
5
+ *
6
+ * @module
7
+ *
8
+ * @example
9
+ *
10
+ * ```ts
11
+ * import { vec } from '../../types/bit_vec/module.f.ts'
12
+ * import { msbUtf8 } from '../../text/module.f.ts'
13
+ * import { sha256 } from '../sha2/module.f.ts'
14
+ *
15
+ * const r = hmac(sha256)(msbUtf8('key'))(msbUtf8('The quick brown fox jumps over the lazy dog'))
16
+ * if (r !== vec(256n)(0xf7bc83f430538424b13298e6aa6fb143ef4d59a14946175997479dbc2d1a3cd8n)) { throw r }
17
+ * ```
18
+ */
19
+ import { length } from "../../types/bit_vec/module.f.js";
20
+ import { empty, msb, vec, vec8 } from "../../types/bit_vec/module.f.js";
21
+ import { flip } from "../../types/function/module.f.js";
22
+ import { repeat } from "../../types/monoid/module.f.js";
23
+ import { computeSync } from "../sha2/module.f.js";
24
+ const { concat } = msb;
25
+ /**
26
+ * Outer padding.
27
+ */
28
+ const oPad = vec8(0x5cn);
29
+ /**
30
+ * Inner padding.
31
+ */
32
+ const iPad = vec8(0x36n);
33
+ /**
34
+ * Repeats a vector to create a padded block of the desired length.
35
+ */
36
+ const padRepeat = repeat({ identity: empty, operation: concat });
37
+ /**
38
+ * Generates an HMAC (Hash-based Message Authentication Code) using the specified SHA-2 hash function.
39
+ *
40
+ * @param sha2 - The SHA-2 hash function implementation to use.
41
+ * @returns - A function that takes a key and returns another function
42
+ * that takes a message and computes the HMAC.
43
+ */
44
+ export const hmac = (sha2) => {
45
+ const { blockLength } = sha2;
46
+ const p = flip(padRepeat)(blockLength >> 3n);
47
+ const ip = p(iPad);
48
+ const op = p(oPad);
49
+ const c = computeSync(sha2);
50
+ const vbl = vec(blockLength);
51
+ const xor = (a) => (b) => vbl(a ^ b);
52
+ return k => m => {
53
+ const k1 = length(k) > blockLength ? c([k]) : k;
54
+ const k2 = concat(k1)(vec(blockLength - length(k1))(0n));
55
+ const xk2 = xor(k2);
56
+ const f = (p, msg) => c([xk2(p), msg]);
57
+ const m1 = f(ip, m);
58
+ return f(op, m1);
59
+ };
60
+ };
@@ -0,0 +1,6 @@
1
+ declare const _default: {
2
+ example: () => void;
3
+ sha256: () => void;
4
+ sha512: () => void;
5
+ };
6
+ export default _default;
@@ -0,0 +1,24 @@
1
+ import { msbUtf8 } from "../../text/module.f.js";
2
+ import { vec } from "../../types/bit_vec/module.f.js";
3
+ import { sha256, sha512 } from "../sha2/module.f.js";
4
+ import { hmac } from "./module.f.js";
5
+ export default {
6
+ example: () => {
7
+ const r = hmac(sha256)(msbUtf8('key'))(msbUtf8('The quick brown fox jumps over the lazy dog'));
8
+ if (r !== vec(256n)(0xf7bc83f430538424b13298e6aa6fb143ef4d59a14946175997479dbc2d1a3cd8n)) {
9
+ throw r;
10
+ }
11
+ },
12
+ sha256: () => {
13
+ const r = hmac(sha256)(msbUtf8('key'))(msbUtf8('The quick brown fox jumps over the lazy dog'));
14
+ if (r !== 0x1f7bc83f430538424b13298e6aa6fb143ef4d59a14946175997479dbc2d1a3cd8n) {
15
+ throw r;
16
+ }
17
+ },
18
+ sha512: () => {
19
+ const r = hmac(sha512)(msbUtf8('key'))(msbUtf8('The quick brown fox jumps over the lazy dog'));
20
+ if (r !== 0x1b42af09057bac1e2d41708e48a902e09b5ff7f12ab428a4fe86653c73dd248fb82f948a549f7b791a5b41915ee4d1ec3935357e4e2317250d0372afa2ebeeb3an) {
21
+ throw r;
22
+ }
23
+ }
24
+ };
@@ -1,5 +1,6 @@
1
1
  import type { Array16, Array8 } from '../../types/array/module.f.ts';
2
2
  import { type Vec } from '../../types/bit_vec/module.f.ts';
3
+ import { type List } from '../../types/list/module.f.ts';
3
4
  export type V8 = Array8<bigint>;
4
5
  export type V16 = Array16<bigint>;
5
6
  /**
@@ -40,6 +41,14 @@ export type Base = {
40
41
  * ```
41
42
  */
42
43
  export type Sha2 = {
44
+ /**
45
+ * A hash length.
46
+ */
47
+ readonly hashLength: bigint;
48
+ /**
49
+ * An internal block length.
50
+ */
51
+ readonly blockLength: bigint;
43
52
  /**
44
53
  * Initial state of the SHA-2 algorithm.
45
54
  */
@@ -60,6 +69,7 @@ export type Sha2 = {
60
69
  */
61
70
  readonly end: (state: State) => bigint;
62
71
  };
72
+ export declare const computeSync: ({ append, init, end }: Sha2) => (list: List<Vec>) => Vec;
63
73
  export declare const base32: Base;
64
74
  export declare const base64: Base;
65
75
  /** SHA-256 */
@@ -1,5 +1,7 @@
1
1
  import { mask } from "../../types/bigint/module.f.js";
2
2
  import { vec, length, empty, msb } from "../../types/bit_vec/module.f.js";
3
+ import { flip } from "../../types/function/module.f.js";
4
+ import { fold } from "../../types/list/module.f.js";
3
5
  const { concat, popFront, front } = msb;
4
6
  const lastOne = vec(1n)(1n);
5
7
  const base = ({ logBitLen, k, bs0, bs1, ss0, ss1 }) => {
@@ -138,6 +140,7 @@ const base = ({ logBitLen, k, bs0, bs1, ss0, ss1 }) => {
138
140
  },
139
141
  end: (hashLength) => {
140
142
  const offset = (bitLength << 3n) - hashLength;
143
+ const result = vec(hashLength);
141
144
  return (state) => {
142
145
  const { len, remainder } = state;
143
146
  let { hash } = state;
@@ -148,12 +151,14 @@ const base = ({ logBitLen, k, bs0, bs1, ss0, ss1 }) => {
148
151
  hash = compress(hash)(u);
149
152
  u = 0n;
150
153
  }
151
- return fromV8(compress(hash)(u | (len + rLen))) >> offset;
154
+ return result(fromV8(compress(hash)(u | (len + rLen))) >> offset);
152
155
  };
153
156
  }
154
157
  };
155
158
  };
156
- const sha2 = ({ append, end }, hash, hashLength) => ({
159
+ const sha2 = ({ append, end, chunkLength }, hash, hashLength) => ({
160
+ hashLength,
161
+ blockLength: chunkLength,
157
162
  init: {
158
163
  hash,
159
164
  len: 0n,
@@ -162,6 +167,10 @@ const sha2 = ({ append, end }, hash, hashLength) => ({
162
167
  append,
163
168
  end: end(hashLength),
164
169
  });
170
+ export const computeSync = ({ append, init, end }) => {
171
+ const f = fold(flip(append))(init);
172
+ return (list) => end(f(list));
173
+ };
165
174
  export const base32 = base({
166
175
  logBitLen: 5n,
167
176
  k: [
@@ -1,7 +1,8 @@
1
1
  import { msbUtf8 } from "../../text/module.f.js";
2
2
  import { empty, msb, vec } from "../../types/bit_vec/module.f.js";
3
+ import { map } from "../../types/list/module.f.js";
3
4
  import { repeat } from "../../types/monoid/module.f.js";
4
- import { base32, base64, sha224, sha256, sha384, sha512, sha512x224, sha512x256, } from "./module.f.js";
5
+ import { base32, base64, computeSync, sha224, sha256, sha384, sha512, sha512x224, sha512x256, } from "./module.f.js";
5
6
  const { concat: beConcat } = msb;
6
7
  const checkEmpty = ({ init, end }) => (x) => {
7
8
  const result = end(init);
@@ -22,7 +23,7 @@ export default {
22
23
  const result = fromV8(compress(sha256.init.hash)(e));
23
24
  const x = 0xe3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855n;
24
25
  if (result !== x) {
25
- throw [result, x];
26
+ throw [result.toString(16), x.toString(16)];
26
27
  }
27
28
  },
28
29
  s224: () => {
@@ -70,29 +71,35 @@ export default {
70
71
  }
71
72
  },
72
73
  sha2: {
73
- sha256: () => checkEmpty(sha256)(0xe3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855n),
74
- sha224: () => checkEmpty(sha224)(0xd14a028c2a3a2bc9476102bb288234c415a2b01f828ea62ac5b3e42fn),
75
- sha512: () => checkEmpty(sha512)(0xcf83e1357eefb8bdf1542850d66d8007d620e4050b5715dc83f4a921d36ce9ce47d0d13c5d85f2b0ff8318d2877eec2f63b931bd47417a81a538327af927da3en),
76
- sha384: () => checkEmpty(sha384)(0x38b060a751ac96384cd9327eb1b1e36a21fdb71114be07434c0cc7bf63f6e1da274edebfe76f65fbd51ad2f14898b95bn),
77
- sha512x256: () => checkEmpty(sha512x256)(0xc672b8d1ef56ed28ab87c3622c5114069bdd3ad7b8f9737498d0c01ecef0967an),
78
- sha512x224: () => checkEmpty(sha512x224)(0x6ed0dd02806fa89e25de060c19d3ac86cabb87d6a0ddd05c333b84f4n),
74
+ sha256: () => checkEmpty(sha256)(0x1e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855n),
75
+ sha224: () => checkEmpty(sha224)(0x1d14a028c2a3a2bc9476102bb288234c415a2b01f828ea62ac5b3e42fn),
76
+ sha512: () => checkEmpty(sha512)(0x1cf83e1357eefb8bdf1542850d66d8007d620e4050b5715dc83f4a921d36ce9ce47d0d13c5d85f2b0ff8318d2877eec2f63b931bd47417a81a538327af927da3en),
77
+ sha384: () => checkEmpty(sha384)(0x138b060a751ac96384cd9327eb1b1e36a21fdb71114be07434c0cc7bf63f6e1da274edebfe76f65fbd51ad2f14898b95bn),
78
+ sha512x256: () => checkEmpty(sha512x256)(0x1c672b8d1ef56ed28ab87c3622c5114069bdd3ad7b8f9737498d0c01ecef0967an),
79
+ sha512x224: () => checkEmpty(sha512x224)(0x16ed0dd02806fa89e25de060c19d3ac86cabb87d6a0ddd05c333b84f4n),
79
80
  },
80
81
  utf8: [
81
82
  () => {
82
- const s = msbUtf8("The quick brown fox jumps over the lazy dog");
83
- let state = sha224.init;
84
- state = sha224.append(state)(s);
85
- const h = sha224.end(state);
86
- if (h !== 0x730e109bd7a8a32b1cb9d9a09aa2325d2430587ddbc0c38bad911525n) {
87
- throw h;
83
+ const e = 0x1730e109bd7a8a32b1cb9d9a09aa2325d2430587ddbc0c38bad911525n;
84
+ {
85
+ const s = msbUtf8("The quick brown fox jumps over the lazy dog");
86
+ const h = computeSync(sha224)([s]);
87
+ if (h !== e) {
88
+ throw h;
89
+ }
90
+ }
91
+ {
92
+ const s = ['The', ' quick', ' brown', ' fox', ' jumps', ' over', ' the', ' lazy', ' dog'];
93
+ const h = computeSync(sha224)(map(msbUtf8)(s));
94
+ if (h !== e) {
95
+ throw h;
96
+ }
88
97
  }
89
98
  },
90
99
  () => {
91
100
  const s = msbUtf8("The quick brown fox jumps over the lazy dog.");
92
- let state = sha224.init;
93
- state = sha224.append(state)(s);
94
- const h = sha224.end(state);
95
- if (h !== 0x619cba8e8e05826e9b8c519c0a5c68f4fb653e8a3d8aa04bb2c8cd4cn) {
101
+ const h = computeSync(sha224)([s]);
102
+ if (h !== 0x1619cba8e8e05826e9b8c519c0a5c68f4fb653e8a3d8aa04bb2c8cd4cn) {
96
103
  throw h;
97
104
  }
98
105
  },
@@ -104,7 +111,7 @@ export default {
104
111
  let state = sha256.init;
105
112
  state = sha256.append(state)(s);
106
113
  const h = sha256.end(state);
107
- if (h !== 0xb94d27b9934d3e08a52e52d7da7dabfac484efe37a5380ee9088f7ace2efcde9n) {
114
+ if (h !== 0x1b94d27b9934d3e08a52e52d7da7dabfac484efe37a5380ee9088f7ace2efcde9n) {
108
115
  throw h;
109
116
  }
110
117
  }
@@ -117,7 +124,7 @@ export default {
117
124
  let state = sha256.init;
118
125
  state = sha256.append(state)(r);
119
126
  const h = sha256.end(state);
120
- if (h >> 224n !== 0x8a83665fn) {
127
+ if (h >> 224n !== 0x18a83665fn) {
121
128
  throw h;
122
129
  }
123
130
  },
@@ -126,7 +133,7 @@ export default {
126
133
  let state = sha256.init;
127
134
  state = sha256.append(state)(r);
128
135
  const h = sha256.end(state);
129
- if (h !== 0x3138bb9bc78df27c473ecfd1410f7bd45ebac1f59cf3ff9cfe4db77aab7aedd3n) {
136
+ if (h !== 0x13138bb9bc78df27c473ecfd1410f7bd45ebac1f59cf3ff9cfe4db77aab7aedd3n) {
130
137
  throw h;
131
138
  }
132
139
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "functionalscript",
3
- "version": "0.4.2",
3
+ "version": "0.4.3",
4
4
  "type": "module",
5
5
  "files": [
6
6
  "**/*.f.d.ts",
@@ -1,5 +1,5 @@
1
1
  /**
2
- * A collection of utility functions for working with `bigint` values.
2
+ * Utility functions for working with `bigint` values.
3
3
  *
4
4
  * @module
5
5
  *
@@ -14,17 +14,67 @@
14
14
  * const bitCount = bitLength(255n) // 8n
15
15
  * const bitmask = mask(5n) // 31n
16
16
  * const m = min(3n)(13n) // 3n
17
+ * const c = combination([3n, 2n, 1n]) // 60n
17
18
  * ```
18
19
  */
19
20
  import { type Sign } from '../function/compare/module.f.ts';
20
21
  import type * as Operator from '../function/operator/module.f.ts';
21
22
  import { type List } from '../list/module.f.ts';
23
+ /**
24
+ * Type representing a unary operation on `bigint`.
25
+ */
22
26
  export type Unary = Operator.Unary<bigint, bigint>;
27
+ /**
28
+ * Type representing a reduction operation on `bigint` values.
29
+ */
23
30
  export type Reduce = Operator.Reduce<bigint>;
31
+ /**
32
+ * Adds two `bigint` values.
33
+ *
34
+ * @param a - The first bigint value.
35
+ * @returns A function that takes the second bigint value and returns the sum.
36
+ */
24
37
  export declare const addition: Reduce;
38
+ /**
39
+ * Calculates the sum of a list of `bigint` values.
40
+ *
41
+ * @param input - A list of bigint values.
42
+ * @returns The sum of all values in the list.
43
+ */
25
44
  export declare const sum: (input: List<bigint>) => bigint;
45
+ /**
46
+ * Multiplies two `bigint` values.
47
+ *
48
+ * @param a - The first bigint value.
49
+ * @returns A function that takes the second bigint value and returns the product.
50
+ */
51
+ export declare const multiple: Reduce;
52
+ /**
53
+ * Calculates the product of a list of `bigint` values.
54
+ *
55
+ * @param input - A list of bigint values.
56
+ * @returns The product of all values in the list.
57
+ */
58
+ export declare const product: (input: List<bigint>) => bigint;
59
+ /**
60
+ * Calculates the absolute value of a `bigint`.
61
+ *
62
+ * @param a - The bigint value.
63
+ * @returns The absolute value of the input bigint.
64
+ */
26
65
  export declare const abs: Unary;
66
+ /**
67
+ * Determines the sign of a `bigint`.
68
+ * @param a - The bigint value.
69
+ * @returns `1` if positive, `-1` if negative, and `0` if zero.
70
+ */
27
71
  export declare const sign: (a: bigint) => Sign;
72
+ /**
73
+ * Serializes a `bigint` to a string representation.
74
+ *
75
+ * @param a - The bigint value.
76
+ * @returns A string representation of the bigint (e.g., '123n').
77
+ */
28
78
  export declare const serialize: (a: bigint) => string;
29
79
  /**
30
80
  * Calculates the base-2 logarithm (floor).
@@ -81,6 +131,37 @@ export declare const bitLength: (v: bigint) => bigint;
81
131
  */
82
132
  export declare const mask: (len: bigint) => bigint;
83
133
  /**
84
- * A minimal value.
134
+ * Returns the smaller of two `bigint` values.
135
+ *
136
+ * @param a - The first bigint.
137
+ * @returns A function that takes the second bigint and returns the smaller value.
85
138
  */
86
139
  export declare const min: (a: bigint) => (b: bigint) => bigint;
140
+ /**
141
+ * Returns the larger of two `bigint` values.
142
+ *
143
+ * @param a - The first bigint.
144
+ * @returns A function that takes the second bigint and returns the larger value.
145
+ */
146
+ export declare const max: (a: bigint) => (b: bigint) => bigint;
147
+ /**
148
+ * Calculates the partial factorial `b!/a!`.
149
+ *
150
+ * @param a - The starting bigint value.
151
+ * @returns A function that takes `b` and computes `b!/a!`.
152
+ */
153
+ export declare const partialFactorial: (a: bigint) => (b: bigint) => bigint;
154
+ /**
155
+ * Calculates the factorial of a `bigint`.
156
+ *
157
+ * @param b - The bigint value.
158
+ * @returns The factorial of the input.
159
+ */
160
+ export declare const factorial: (b: bigint) => bigint;
161
+ /**
162
+ * Calculates the number of combinations for a list of `bigint` values.
163
+ *
164
+ * @param k - A list of bigint values.
165
+ * @returns The number of combinations.
166
+ */
167
+ export declare const combination: (...k: readonly bigint[]) => bigint;
@@ -1,5 +1,5 @@
1
1
  /**
2
- * A collection of utility functions for working with `bigint` values.
2
+ * Utility functions for working with `bigint` values.
3
3
  *
4
4
  * @module
5
5
  *
@@ -14,14 +14,58 @@
14
14
  * const bitCount = bitLength(255n) // 8n
15
15
  * const bitmask = mask(5n) // 31n
16
16
  * const m = min(3n)(13n) // 3n
17
+ * const c = combination([3n, 2n, 1n]) // 60n
17
18
  * ```
18
19
  */
19
20
  import { unsafeCmp } from "../function/compare/module.f.js";
20
21
  import { reduce } from "../list/module.f.js";
22
+ /**
23
+ * Adds two `bigint` values.
24
+ *
25
+ * @param a - The first bigint value.
26
+ * @returns A function that takes the second bigint value and returns the sum.
27
+ */
21
28
  export const addition = a => b => a + b;
29
+ /**
30
+ * Calculates the sum of a list of `bigint` values.
31
+ *
32
+ * @param input - A list of bigint values.
33
+ * @returns The sum of all values in the list.
34
+ */
22
35
  export const sum = reduce(addition)(0n);
36
+ /**
37
+ * Multiplies two `bigint` values.
38
+ *
39
+ * @param a - The first bigint value.
40
+ * @returns A function that takes the second bigint value and returns the product.
41
+ */
42
+ export const multiple = a => b => a * b;
43
+ /**
44
+ * Calculates the product of a list of `bigint` values.
45
+ *
46
+ * @param input - A list of bigint values.
47
+ * @returns The product of all values in the list.
48
+ */
49
+ export const product = reduce(multiple)(1n);
50
+ /**
51
+ * Calculates the absolute value of a `bigint`.
52
+ *
53
+ * @param a - The bigint value.
54
+ * @returns The absolute value of the input bigint.
55
+ */
23
56
  export const abs = a => a >= 0 ? a : -a;
57
+ /**
58
+ * Determines the sign of a `bigint`.
59
+ * @param a - The bigint value.
60
+ * @returns `1` if positive, `-1` if negative, and `0` if zero.
61
+ */
24
62
  export const sign = (a) => unsafeCmp(a)(0n);
63
+ /**
64
+ * Serializes a `bigint` to a string representation.
65
+ *
66
+ * @param a - The bigint value.
67
+ * @returns A string representation of the bigint (e.g., '123n').
68
+ */
25
69
  export const serialize = (a) => `${a}n`;
26
70
  const { isFinite } = Number;
27
71
  const { log2: mathLog2 } = Math;
@@ -139,6 +183,58 @@ export const bitLength = (v) => {
139
183
  */
140
184
  export const mask = (len) => (1n << len) - 1n;
141
185
  /**
142
- * A minimal value.
186
+ * Returns the smaller of two `bigint` values.
187
+ *
188
+ * @param a - The first bigint.
189
+ * @returns A function that takes the second bigint and returns the smaller value.
143
190
  */
144
191
  export const min = (a) => (b) => a < b ? a : b;
192
+ /**
193
+ * Returns the larger of two `bigint` values.
194
+ *
195
+ * @param a - The first bigint.
196
+ * @returns A function that takes the second bigint and returns the larger value.
197
+ */
198
+ export const max = (a) => (b) => a < b ? b : a;
199
+ /**
200
+ * Calculates the partial factorial `b!/a!`.
201
+ *
202
+ * @param a - The starting bigint value.
203
+ * @returns A function that takes `b` and computes `b!/a!`.
204
+ */
205
+ export const partialFactorial = (a) => (b) => {
206
+ let result = b;
207
+ while (true) {
208
+ --b;
209
+ if (b <= a) {
210
+ return result;
211
+ }
212
+ result *= b;
213
+ }
214
+ };
215
+ /**
216
+ * Calculates the factorial of a `bigint`.
217
+ *
218
+ * @param b - The bigint value.
219
+ * @returns The factorial of the input.
220
+ */
221
+ export const factorial = partialFactorial(1n);
222
+ /**
223
+ * Calculates the number of combinations for a list of `bigint` values.
224
+ *
225
+ * @param k - A list of bigint values.
226
+ * @returns The number of combinations.
227
+ */
228
+ export const combination = (...k) => {
229
+ let s = 0n;
230
+ let m = 1n;
231
+ let p = 1n;
232
+ for (let i of k) {
233
+ s += i;
234
+ if (i >= m) {
235
+ [i, m] = [m, i];
236
+ }
237
+ p *= factorial(i);
238
+ }
239
+ return partialFactorial(m)(s) / p;
240
+ };
@@ -23,5 +23,9 @@ declare const _default: {
23
23
  big: () => void;
24
24
  neg: (() => void)[];
25
25
  };
26
+ factorial: () => void;
27
+ combination: () => void;
28
+ combination50x50: () => void;
29
+ combination3: () => void;
26
30
  };
27
31
  export default _default;
@@ -1,4 +1,4 @@
1
- import { sum, abs, serialize, log2, bitLength, mask, min } from "./module.f.js";
1
+ import { sum, abs, serialize, log2, bitLength, mask, min, combination, factorial } from "./module.f.js";
2
2
  const oldLog2 = (v) => {
3
3
  if (v <= 0n) {
4
4
  return -1n;
@@ -174,15 +174,19 @@ export default {
174
174
  if (m !== 3n) {
175
175
  throw m;
176
176
  }
177
+ const c = combination(3n, 2n, 1n); // 60n
178
+ if (c !== 60n) {
179
+ throw c;
180
+ }
177
181
  },
178
182
  benchmark: () => {
179
183
  const list = {
180
- strBinLog2,
181
- strHexLog2,
184
+ // strBinLog2,
185
+ // strHexLog2,
182
186
  str32Log2,
183
- oldLog2,
184
- clz32Log2,
185
- m1023log2,
187
+ // oldLog2,
188
+ // clz32Log2,
189
+ // m1023log2,
186
190
  log2,
187
191
  };
188
192
  const transform = (b) => Object.fromEntries(Object.entries(list).map(([k, f]) => [k, b(f)]));
@@ -391,5 +395,61 @@ export default {
391
395
  }
392
396
  },
393
397
  ]
398
+ },
399
+ factorial: () => {
400
+ {
401
+ const r = factorial(3n);
402
+ if (r !== 6n) {
403
+ throw r;
404
+ }
405
+ }
406
+ {
407
+ const r = factorial(5n);
408
+ if (r !== 120n) {
409
+ throw r;
410
+ }
411
+ }
412
+ },
413
+ combination: () => {
414
+ const r = combination(2n, 3n);
415
+ if (r != 120n / (2n * 6n)) {
416
+ throw r;
417
+ }
418
+ },
419
+ combination50x50: () => {
420
+ {
421
+ const r = combination(1n, 1n);
422
+ if (r !== 2n) {
423
+ throw r;
424
+ }
425
+ }
426
+ {
427
+ const r = combination(2n, 2n);
428
+ if (r !== 6n) {
429
+ throw r;
430
+ }
431
+ }
432
+ {
433
+ const r = combination(3n, 3n);
434
+ if (r !== 20n) {
435
+ throw r;
436
+ }
437
+ }
438
+ {
439
+ const r = combination(4n, 4n);
440
+ if (r !== 70n) {
441
+ throw r;
442
+ }
443
+ }
444
+ },
445
+ combination3: () => {
446
+ const r = combination(2n, 3n, 4n, 2n);
447
+ // 2! * 3! * 4! * 2! : 2! * 2! * 3!
448
+ // 2+3+4+2 = 5*6*7*8*9*10*11
449
+ // e = 5 * 6 * 7 * 8 * 9 * 10 * 11 / (2n * 2n * 6n) =
450
+ // e = 5 * 7 * 2 * 9 * 10 * 11 = 69300
451
+ if (r !== 69300n) {
452
+ throw r;
453
+ }
394
454
  }
395
455
  };
@@ -6,7 +6,7 @@ export type Vec = bigint;
6
6
  /**
7
7
  * An empty vector of bits.
8
8
  */
9
- export declare const empty = 1n;
9
+ export declare const empty: Vec;
10
10
  /**
11
11
  * Calculates the length of the given vector of bits.
12
12
  */
@@ -4,3 +4,7 @@ export declare const sum: (input: List<number>) => number;
4
4
  export declare const min: (input: List<number>) => number | null;
5
5
  export declare const max: (input: List<number>) => number | null;
6
6
  export declare const cmp: (a: number) => (b: number) => Sign;
7
+ /**
8
+ * Count a number of ones in 32 bit number
9
+ */
10
+ export declare const countOnes: (n: number) => number;
@@ -5,3 +5,19 @@ export const sum = reduce(addition)(0);
5
5
  export const min = reduce(minOp)(null);
6
6
  export const max = reduce(maxOp)(null);
7
7
  export const cmp = unsafeCmp;
8
+ const mo = [
9
+ [0x5555_5555, 1],
10
+ [0x3333_3333, 2],
11
+ [0x0F0F_0F0F, 4],
12
+ [0x00FF_00FF, 8],
13
+ [0x0000_FFFF, 16],
14
+ ];
15
+ /**
16
+ * Count a number of ones in 32 bit number
17
+ */
18
+ export const countOnes = (n) => {
19
+ for (const [mask, offset] of mo) {
20
+ n = (n & mask) + ((n >> offset) & mask);
21
+ }
22
+ return n;
23
+ };
@@ -7,5 +7,6 @@ declare const _default: {
7
7
  max: () => void;
8
8
  cmp: () => void;
9
9
  standard: () => void;
10
+ countOnes: (() => void)[];
10
11
  };
11
12
  export default _default;
@@ -1,4 +1,4 @@
1
- import { sum, min, max, cmp } from "./module.f.js";
1
+ import { sum, min, max, cmp, countOnes } from "./module.f.js";
2
2
  export default {
3
3
  sum: () => {
4
4
  const result = sum([2, 3, 4, 5]);
@@ -34,7 +34,7 @@ export default {
34
34
  },
35
35
  standard: () => {
36
36
  const check = a => b => {
37
- if (BigInt(Number(a)) != b) {
37
+ if (BigInt(Number(a)) !== b) {
38
38
  throw [a, b];
39
39
  }
40
40
  };
@@ -119,5 +119,21 @@ export default {
119
119
  // 4_3210_FEDC_BA98_7654_3210_FEDC_BA98_7654_3210_FEDC_BA98_7654_3210_1234
120
120
  check(104002482718319358n)(104002482718319360n);
121
121
  check(142693895881191444n)(142693895881191440n);
122
- }
122
+ },
123
+ countOnes: [
124
+ () => {
125
+ // 1121 2231 = 5 + 8 = 13
126
+ const r = countOnes(0x1234_5678);
127
+ if (r !== 13) {
128
+ throw r;
129
+ }
130
+ },
131
+ () => {
132
+ // 2232 3340 = 9 + 10 = 19
133
+ const r = countOnes(0x9ABC_DEF0);
134
+ if (r !== 19) {
135
+ throw r;
136
+ }
137
+ }
138
+ ]
123
139
  };