pick-me-too 1.2.1 → 1.3.0

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/CHANGELOG.md CHANGED
@@ -1,5 +1,7 @@
1
1
  # Changelog
2
2
 
3
+ ## v1.3.0 *2022-7-23*
4
+ - made `rando` reseedable
3
5
  ## v1.2.1 *2022-4-30*
4
6
  - fixed typo in README
5
7
  ## v1.2.0 *2022-4-17*
package/README.md CHANGED
@@ -194,6 +194,10 @@ const rng = rando(1)
194
194
  const ar: number[] = []
195
195
  for (let i = 0; i < 3; i++) ar.push(rng())
196
196
  // => [ 0.6270739405881613, 0.002735721180215478, 0.5274470399599522 ]
197
+
198
+ // reseed the generator
199
+ (rng as any)(Math.random())
200
+ // => ??? the random number sequence is still deterministic, but at a completely different place
197
201
  ```
198
202
 
199
203
  ## Acknowledgements
package/lib/index.d.ts CHANGED
@@ -82,6 +82,10 @@ export declare type Rng = () => number;
82
82
  * The implementation of `rando` is taken from https://stackoverflow.com/a/47593316/15060051.
83
83
  * It is the Mulberry32 algorithm.
84
84
  *
85
+ * Note, `rando` can be re-seeded by passing an optional number argument as the fresh seed (see
86
+ * example below). This can be useful if you are sharing a random number generator among
87
+ * several objects and you need to change random number sequences.
88
+ *
85
89
  * @example
86
90
  * ```ts
87
91
  * import { rando } from 'pick-me'
@@ -91,6 +95,16 @@ export declare type Rng = () => number;
91
95
  * const ar: number[] = []
92
96
  * for (let i = 0; i < 3; i++) ar.push(rng())
93
97
  * // => [ 0.6270739405881613, 0.002735721180215478, 0.5274470399599522 ]
98
+ *
99
+ * // the same seed will produce the same random number sequence
100
+ * rando(1)()
101
+ * // => 0.6270739405881613
102
+ * rando(1)()
103
+ * // => 0.6270739405881613
104
+ *
105
+ * // but you can provide a fresh seed to change the sequence
106
+ * (rando(1) as any)(2)
107
+ * // => 0.7342509443406016
94
108
  * ```
95
109
  *
96
110
  * @param {number} seed - the seed for a random number sequence
package/lib/index.js CHANGED
@@ -47,7 +47,8 @@ exports.rando = exports.pickMeToo = exports.pickMe = void 0;
47
47
  * @returns {() => T} a picker of T's
48
48
  */
49
49
  function pickMe(frequencies, rando) {
50
- return pickMeToo(frequencies)(rando !== null && rando !== void 0 ? rando : (() => Math.random()));
50
+ const rng = rando !== null && rando !== void 0 ? rando : (() => Math.random());
51
+ return pickMeToo(frequencies)(rng);
51
52
  }
52
53
  exports.pickMe = pickMe;
53
54
  /**
@@ -163,6 +164,10 @@ function portion(thresholds, start, end) {
163
164
  * The implementation of `rando` is taken from https://stackoverflow.com/a/47593316/15060051.
164
165
  * It is the Mulberry32 algorithm.
165
166
  *
167
+ * Note, `rando` can be re-seeded by passing an optional number argument as the fresh seed (see
168
+ * example below). This can be useful if you are sharing a random number generator among
169
+ * several objects and you need to change random number sequences.
170
+ *
166
171
  * @example
167
172
  * ```ts
168
173
  * import { rando } from 'pick-me'
@@ -172,13 +177,25 @@ function portion(thresholds, start, end) {
172
177
  * const ar: number[] = []
173
178
  * for (let i = 0; i < 3; i++) ar.push(rng())
174
179
  * // => [ 0.6270739405881613, 0.002735721180215478, 0.5274470399599522 ]
180
+ *
181
+ * // the same seed will produce the same random number sequence
182
+ * rando(1)()
183
+ * // => 0.6270739405881613
184
+ * rando(1)()
185
+ * // => 0.6270739405881613
186
+ *
187
+ * // but you can provide a fresh seed to change the sequence
188
+ * (rando(1) as any)(2)
189
+ * // => 0.7342509443406016
175
190
  * ```
176
191
  *
177
192
  * @param {number} seed - the seed for a random number sequence
178
193
  * @returns {Rng} a generator of random numbers
179
194
  */
180
195
  function rando(seed) {
181
- return () => {
196
+ return (reseed) => {
197
+ if (reseed !== undefined)
198
+ seed = reseed;
182
199
  let t = (seed += 0x6d2b79f5);
183
200
  t = Math.imul(t ^ (t >>> 15), t | 1);
184
201
  t ^= t + Math.imul(t ^ (t >>> 7), t | 61);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pick-me-too",
3
- "version": "1.2.1",
3
+ "version": "1.3.0",
4
4
  "description": "Generate a function that returns random items from a list with specified frequencies.",
5
5
  "main": "lib/index.js",
6
6
  "types": "lib/index.d.ts",
@@ -87,7 +87,7 @@ describe('README', () => {
87
87
  rng,
88
88
  )
89
89
  const clause = () => {
90
- let s = []
90
+ let s: string[] = []
91
91
  for (let i = 0, lim = clauseLength(); i < lim; i++) s.push(word())
92
92
  return s.join(' ')
93
93
  }
@@ -127,5 +127,7 @@ describe('index.ts', () => {
127
127
  test('rando', () => {
128
128
  expect(ar).toEqual([0.6270739405881613, 0.002735721180215478, 0.5274470399599522])
129
129
  })
130
+ test('rando(1)()', () => expect(rando(1)()).toEqual(0.6270739405881613))
131
+ test('(rando(1) as any)(2)', () => expect((rando(1) as any)(2)).toEqual(0.7342509443406016))
130
132
  })
131
133
  })
@@ -16,6 +16,19 @@ describe('rando', () => {
16
16
  for (let i = 0; i < bins.length; i++) {
17
17
  test('even distribution', () => expect(Math.round(bins[i] / 1000)).toEqual(1))
18
18
  }
19
+ for (let i = 0; i < 10; i++) {
20
+ const seed = Math.random()
21
+ const rng1 = rando(seed),
22
+ rng2 = rando(seed)
23
+ const ar1: number[] = [],
24
+ ar2: number[] = []
25
+ for (let j = 0; j < 10; j++) {
26
+ ar1.push(rng1())
27
+ ar2.push(rng2())
28
+ }
29
+ test(`two randos with seed ${seed} produce the same sequence of random values`, () => expect(ar1).toEqual(ar2))
30
+ test(`randos can be reseeded`, () => expect(rng1()).not.toEqual((rng2 as any)(Math.random())))
31
+ }
19
32
  })
20
33
 
21
34
  describe('pickMe', () => {
package/src/index.ts CHANGED
@@ -44,7 +44,8 @@
44
44
  * @returns {() => T} a picker of T's
45
45
  */
46
46
  export function pickMe<T>(frequencies: [T, number][] | T[], rando?: Rng): () => T {
47
- return pickMeToo(frequencies)(rando ?? (() => Math.random()))
47
+ const rng = rando ?? (() => Math.random())
48
+ return pickMeToo(frequencies)(rng)
48
49
  }
49
50
 
50
51
  /**
@@ -171,6 +172,10 @@ function portion(thresholds: number[], start: number, end: number): string {
171
172
  *
172
173
  * The implementation of `rando` is taken from https://stackoverflow.com/a/47593316/15060051.
173
174
  * It is the Mulberry32 algorithm.
175
+ *
176
+ * Note, `rando` can be re-seeded by passing an optional number argument as the fresh seed (see
177
+ * example below). This can be useful if you are sharing a random number generator among
178
+ * several objects and you need to change random number sequences.
174
179
  *
175
180
  * @example
176
181
  * ```ts
@@ -181,13 +186,24 @@ function portion(thresholds: number[], start: number, end: number): string {
181
186
  * const ar: number[] = []
182
187
  * for (let i = 0; i < 3; i++) ar.push(rng())
183
188
  * // => [ 0.6270739405881613, 0.002735721180215478, 0.5274470399599522 ]
189
+ *
190
+ * // the same seed will produce the same random number sequence
191
+ * rando(1)()
192
+ * // => 0.6270739405881613
193
+ * rando(1)()
194
+ * // => 0.6270739405881613
195
+ *
196
+ * // but you can provide a fresh seed to change the sequence
197
+ * (rando(1) as any)(2)
198
+ * // => 0.7342509443406016
184
199
  * ```
185
200
  *
186
201
  * @param {number} seed - the seed for a random number sequence
187
202
  * @returns {Rng} a generator of random numbers
188
203
  */
189
204
  export function rando(seed: number): Rng {
190
- return () => {
205
+ return (reseed?: number) => {
206
+ if (reseed !== undefined) seed = reseed
191
207
  let t = (seed += 0x6d2b79f5)
192
208
  t = Math.imul(t ^ (t >>> 15), t | 1)
193
209
  t ^= t + Math.imul(t ^ (t >>> 7), t | 61)