custom-permutation 1.0.7 → 1.1.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/README.md CHANGED
@@ -1,105 +1,121 @@
1
- # Fixed bugs
2
- 25.09.2023 - unChoices did not reflect always, fixed now.
3
-
4
1
  # Custom Permutation Generator
5
2
 
6
- ## 1. require / import
3
+ ## Usage
4
+
5
+ ### 1.1. `require`
6
+
7
+ ```ts
8
+ const CustomPermutation = require('custom-permutation');
9
+ ```
10
+
11
+ ### 1.2. `import`
12
+
7
13
  ```ts
8
- const CustomPermutation = require('custom-permutation')
14
+ import CustomPermutation from 'custom-permutation';
9
15
  ```
10
16
 
11
17
  ## 2. Constructor
18
+
12
19
  ```ts
13
- CustomPermutation(elList:[els...], choices:{ index: [els...]] }, nonChoices:{ index: [els...]] })
20
+ CustomPermutation(
21
+ elList:[],
22
+ choices:{ index: [] },
23
+ nonChoices:{ index: [] }
24
+ )
14
25
  ```
15
26
 
16
- ## 3. Usage explanation
27
+ ## 3. Usage explanied
17
28
 
18
29
  _example:_
19
30
 
20
31
  ```ts
21
- CustomPermutation(['a', 'b', 'c'], {1: ['a', 'b']}, {0: ['a']})
32
+ CustomPermutation(['a', 'b', 'c'], { '1': ['a', 'b'] }, { '0': ['a'] });
22
33
  ```
23
34
 
24
- Permutate 3 elements which are 'a', 'b' and 'c' with below rules
35
+ Permutate 3 elements which are "a", "b" and "c" with below rules
36
+
37
+ **`choices` rule:**
25
38
 
26
- __- choices rule:__
27
39
  ```json
28
- { 1: ['a', 'b'] }
40
+ { "1": ["a", "b"] }
29
41
  ```
30
42
 
31
- At index=1 there can only be the element 'a' or 'b'
43
+ > At `index=1` there can only be the element `"a"` or `"b"`
44
+
45
+ **`nonChoices` rule:**
32
46
 
33
- __- nonChoices rule:__
34
47
  ```json
35
- { 0: ['a'] }
48
+ { "0": ["a"] }
36
49
  ```
37
50
 
38
- At index=0 there can NOT be the element 'a'
51
+ > At `index=0` there can NOT be the element `"a"`
39
52
 
40
53
  _Note: given index are considered as 0 based: [index=0, index=1, etc.]_
41
54
 
55
+ | index | all options | after customization |
56
+ | :---: | :-----------------: | :-----------------: |
57
+ | 0 | `"a"`, `"b"`, `"c"` | `"b"`, `"c"` |
58
+ | 1 | `"a"`, `"b"`, `"c"` | `"a"`, `"b"` |
59
+ | 2 | `"a"`, `"b"`, `"c"` | `"a"`, `"b"`, `"c"` |
60
+
42
61
  ## 4. Result set explanation:
43
62
 
44
- Let's see all permutations, and which ones are valid or not.
45
- - `['a', 'b', 'c']` : violates nonChoices rule: _first element is `'a'`, but shouldn't be `'a'`
46
- - `['a', 'c', 'b']` : violates nonChoices rule: _first element is `'a'`, but shouldn't be `'a'`_
47
- - `['b', 'a', 'c']` : ok
48
- - `['b', 'c', 'a']` : violates choices rule: _second element is `'c'` but `'a'` or `'b'` is desired_
49
- - `['c', 'a', 'b']` : ok
50
- - `['c', 'b', 'a']` : ok
63
+ Let's check all permutations, and see which ones are and are not valid.
64
+
65
+ | Permutation | Is valid | Violates | Description |
66
+ | :---------------: | :------: | :--------: | :--------------------------------------------: |
67
+ | `["a", "b", "c"]` | No | nonChoices | _first elemen can't be `"a"`_ |
68
+ | `["a", "c", "b"]` | No | nonChoices | _first elemen can't be `"a"`_ |
69
+ | `["b", "a", "c"]` | Yes | - | - |
70
+ | `["b", "c", "a"]` | No | choices | _second element is asked to be `"a"` or `"b"`_ |
71
+ | `["c", "a", "b"]` | Yes | - | - |
72
+ | `["c", "b", "a"]` | Yes | - | - |
51
73
 
52
- So there are just 3 results that should be generated with this parameters.
74
+ So there are just **3** results that chould be generated with these parameters.
53
75
 
54
76
  ## 5. Complete example
55
77
 
56
- ### 1. Create permutation
78
+ ### 5.1. Create object from `CustomPermutation` class
57
79
 
58
80
  ```ts
59
- let customPerm = new CustomPermutation(
60
- ['a', 'b', 'c'],
61
- { 1: ['a', 'b'] },
62
- { 0: ['a'] }
63
- );
81
+ let customPerm = new CustomPermutation(['a', 'b', 'c'], { '1': ['a', 'b'] }, { '0': ['a'] });
64
82
  ```
65
83
 
66
- ### 2. Get next value
84
+ ### 5.2. Get next value
67
85
 
68
- #### 2.1. Use with next
86
+ #### 5.2.1. With `next`
69
87
 
70
88
  ```ts
71
89
  let next = customPerm.next();
72
90
 
73
91
  while (next) {
74
- // Use next
75
- console.log(next)
76
-
77
- // Get next
78
- next = customPerm.next();
92
+ console.log(next);
93
+ next = customPerm.next();
79
94
  }
80
95
  ```
81
96
 
82
- #### 2.2. Or use with generator
97
+ #### 5.2.2. With `generator`
83
98
 
84
99
  ```ts
85
100
  let generator = customPerm.generator();
86
101
  let next = generator.next();
87
102
 
88
103
  while (!next.done) {
89
- // Use next.value
90
- console.log(next.value)
91
-
92
- // Generate next one
93
- next = generator.next();
104
+ console.log(next.value);
105
+ next = generator.next();
94
106
  }
95
107
  ```
96
108
 
97
- ### 3. Output
98
-
99
- __Console__
109
+ **Output:**
100
110
 
101
111
  ```sh
102
- ['b', 'a', 'c']\
103
- ['c', 'a', 'b']\
104
- ['c', 'b', 'a']
105
- ```
112
+ ["b", "a", "c"]
113
+ ["c", "a", "b"]
114
+ ["c", "b", "a"]
115
+ ```
116
+
117
+ ## Fixed bugs
118
+
119
+ 11.06.2026 - Better typing implemented and more test coverage added.
120
+ 23.09.2024 - Edge cases are handled and the codespace is simplified.
121
+ 25.09.2023 - unChoices did not reflect always, fixed now.
@@ -1,13 +1,12 @@
1
- import { CustomPermutationGenerator } from "./CustomPermutationGenerator";
2
- export default class CustomPermutation {
1
+ import { CustomPermutationGenerator } from './CustomPermutationGenerator';
2
+ export default class CustomPermutation<T> {
3
3
  private listToPermutate;
4
4
  private choices;
5
5
  private nonChoices;
6
6
  private elementsOrderAbsolute?;
7
- private elementsOrderRelative?;
8
7
  private passFn?;
9
- customPermGen: CustomPermutationGenerator;
10
- constructor(listToPermutate: any[], choices: object, nonChoices: object, elementsOrderAbsolute?: any[], elementsOrderRelative?: any[], passFn?: Function);
11
- next(): any;
12
- generator(): Generator<any, void, unknown>;
8
+ customPermGen: CustomPermutationGenerator<T>;
9
+ constructor(listToPermutate: T[], choices: Record<number, T[]>, nonChoices: Record<number, T[]>, elementsOrderAbsolute?: number[] | undefined, passFn?: ((items: T[]) => boolean) | undefined);
10
+ next(): T[] | null;
11
+ generator(): Generator<T[], void, unknown>;
13
12
  }
@@ -1,74 +1,33 @@
1
1
  "use strict";
2
- var __generator = (this && this.__generator) || function (thisArg, body) {
3
- var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
4
- return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
5
- function verb(n) { return function (v) { return step([n, v]); }; }
6
- function step(op) {
7
- if (f) throw new TypeError("Generator is already executing.");
8
- while (_) try {
9
- if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
10
- if (y = 0, t) op = [op[0] & 2, t.value];
11
- switch (op[0]) {
12
- case 0: case 1: t = op; break;
13
- case 4: _.label++; return { value: op[1], done: false };
14
- case 5: _.label++; y = op[1]; op = [0]; continue;
15
- case 7: op = _.ops.pop(); _.trys.pop(); continue;
16
- default:
17
- if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
18
- if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
19
- if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
20
- if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
21
- if (t[2]) _.ops.pop();
22
- _.trys.pop(); continue;
23
- }
24
- op = body.call(thisArg, _);
25
- } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
26
- if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
27
- }
28
- };
29
2
  Object.defineProperty(exports, "__esModule", { value: true });
30
- var CustomPermutationGenerator_1 = require("./CustomPermutationGenerator");
31
- var CustomPermutation = /** @class */ (function () {
32
- function CustomPermutation(listToPermutate, choices, nonChoices, elementsOrderAbsolute, elementsOrderRelative, passFn) {
3
+ const CustomPermutationGenerator_1 = require("./CustomPermutationGenerator");
4
+ class CustomPermutation {
5
+ constructor(listToPermutate, choices, nonChoices, elementsOrderAbsolute, passFn) {
33
6
  this.listToPermutate = listToPermutate;
34
7
  this.choices = choices;
35
8
  this.nonChoices = nonChoices;
36
9
  this.elementsOrderAbsolute = elementsOrderAbsolute;
37
- this.elementsOrderRelative = elementsOrderRelative;
38
10
  this.passFn = passFn;
39
11
  if (!(elementsOrderAbsolute === null || elementsOrderAbsolute === void 0 ? void 0 : elementsOrderAbsolute.length)) {
40
- elementsOrderAbsolute = new Array(listToPermutate.length, 0).map(function (x, i) { return i; });
12
+ elementsOrderAbsolute = Array.from(listToPermutate).map((x, i) => i);
41
13
  }
42
- if (!(elementsOrderRelative === null || elementsOrderRelative === void 0 ? void 0 : elementsOrderRelative.length)) {
43
- elementsOrderRelative = new Array(listToPermutate.length, 0).map(function (x, i) { return i; });
44
- }
45
- this.customPermGen = new CustomPermutationGenerator_1.CustomPermutationGenerator(listToPermutate, choices, nonChoices, elementsOrderAbsolute, elementsOrderRelative, passFn);
14
+ this.customPermGen = new CustomPermutationGenerator_1.CustomPermutationGenerator(this.listToPermutate, this.choices, this.nonChoices, this.elementsOrderAbsolute, this.passFn);
46
15
  }
47
- CustomPermutation.prototype.next = function () {
16
+ next() {
48
17
  return this.customPermGen.next();
49
- };
50
- CustomPermutation.prototype.generator = function () {
51
- var nextPerm;
52
- return __generator(this, function (_a) {
53
- switch (_a.label) {
54
- case 0:
55
- nextPerm = null;
56
- _a.label = 1;
57
- case 1:
58
- if (!true) return [3 /*break*/, 5];
59
- nextPerm = this.customPermGen.next();
60
- if (!nextPerm) return [3 /*break*/, 3];
61
- return [4 /*yield*/, nextPerm];
62
- case 2:
63
- _a.sent();
64
- return [3 /*break*/, 4];
65
- case 3: return [3 /*break*/, 5];
66
- case 4: return [3 /*break*/, 1];
67
- case 5: return [2 /*return*/];
18
+ }
19
+ *generator() {
20
+ let nextPerm = null;
21
+ while (true) {
22
+ nextPerm = this.customPermGen.next();
23
+ if (nextPerm) {
24
+ yield nextPerm;
68
25
  }
69
- });
70
- };
71
- return CustomPermutation;
72
- }());
26
+ else {
27
+ break;
28
+ }
29
+ }
30
+ }
31
+ }
73
32
  exports.default = CustomPermutation;
74
33
  //# sourceMappingURL=CustomPermutation.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"CustomPermutation.js","sourceRoot":"","sources":["../src/CustomPermutation.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,2EAA0E;AAE1E;IAGE,2BACU,eAAsB,EACtB,OAAe,EACf,UAAkB,EAClB,qBAA6B,EAC7B,qBAA6B,EAC7B,MAAiB;QALjB,oBAAe,GAAf,eAAe,CAAO;QACtB,YAAO,GAAP,OAAO,CAAQ;QACf,eAAU,GAAV,UAAU,CAAQ;QAClB,0BAAqB,GAArB,qBAAqB,CAAQ;QAC7B,0BAAqB,GAArB,qBAAqB,CAAQ;QAC7B,WAAM,GAAN,MAAM,CAAW;QAGzB,IAAI,CAAC,CAAA,qBAAqB,aAArB,qBAAqB,uBAArB,qBAAqB,CAAE,MAAM,CAAA,EAAE;YAClC,qBAAqB,GAAG,IAAI,KAAK,CAAC,eAAe,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,UAAC,CAAC,EAAE,CAAC,IAAK,OAAA,CAAC,EAAD,CAAC,CAAC,CAAC;SAC/E;QAED,IAAI,CAAC,CAAA,qBAAqB,aAArB,qBAAqB,uBAArB,qBAAqB,CAAE,MAAM,CAAA,EAAE;YAClC,qBAAqB,GAAG,IAAI,KAAK,CAAC,eAAe,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,UAAC,CAAC,EAAE,CAAC,IAAK,OAAA,CAAC,EAAD,CAAC,CAAC,CAAC;SAC/E;QAED,IAAI,CAAC,aAAa,GAAG,IAAI,uDAA0B,CAAC,eAAe,EAAE,OAAO,EAAE,UAAU,EAAE,qBAAqB,EAAE,qBAAqB,EAAE,MAAM,CAAC,CAAC;IAClJ,CAAC;IAED,gCAAI,GAAJ;QACE,OAAO,IAAI,CAAC,aAAa,CAAC,IAAI,EAAE,CAAC;IACnC,CAAC;IAEA,qCAAS,GAAV;;;;;oBACM,QAAQ,GAAG,IAAI,CAAC;;;yBAEb,IAAI;oBACT,QAAQ,GAAG,IAAI,CAAC,aAAa,CAAC,IAAI,EAAE,CAAC;yBACjC,QAAQ,EAAR,wBAAQ;oBACV,qBAAM,QAAQ,EAAA;;oBAAd,SAAc,CAAC;;wBAEf,wBAAM;;;;;KAGX;IAEH,wBAAC;AAAD,CAAC,AAxCD,IAwCC"}
1
+ {"version":3,"file":"CustomPermutation.js","sourceRoot":"","sources":["../src/CustomPermutation.ts"],"names":[],"mappings":";;AAAA,6EAA0E;AAE1E,MAAqB,iBAAiB;IAGpC,YACU,eAAoB,EACpB,OAA4B,EAC5B,UAA+B,EAC/B,qBAAgC,EAChC,MAAgC;QAJhC,oBAAe,GAAf,eAAe,CAAK;QACpB,YAAO,GAAP,OAAO,CAAqB;QAC5B,eAAU,GAAV,UAAU,CAAqB;QAC/B,0BAAqB,GAArB,qBAAqB,CAAW;QAChC,WAAM,GAAN,MAAM,CAA0B;QAExC,IAAI,CAAC,CAAA,qBAAqB,aAArB,qBAAqB,uBAArB,qBAAqB,CAAE,MAAM,CAAA,EAAE,CAAC;YACnC,qBAAqB,GAAG,KAAK,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC;QACvE,CAAC;QAED,IAAI,CAAC,aAAa,GAAG,IAAI,uDAA0B,CACjD,IAAI,CAAC,eAAe,EACpB,IAAI,CAAC,OAAO,EACZ,IAAI,CAAC,UAAU,EACf,IAAI,CAAC,qBAAqB,EAC1B,IAAI,CAAC,MAAM,CACZ,CAAC;IACJ,CAAC;IAED,IAAI;QACF,OAAO,IAAI,CAAC,aAAa,CAAC,IAAI,EAAE,CAAC;IACnC,CAAC;IAED,CAAC,SAAS;QACR,IAAI,QAAQ,GAAG,IAAI,CAAC;QAEpB,OAAO,IAAI,EAAE,CAAC;YACZ,QAAQ,GAAG,IAAI,CAAC,aAAa,CAAC,IAAI,EAAE,CAAC;YACrC,IAAI,QAAQ,EAAE,CAAC;gBACb,MAAM,QAAQ,CAAC;YACjB,CAAC;iBAAM,CAAC;gBACN,MAAM;YACR,CAAC;QACH,CAAC;IACH,CAAC;CACF;AAvCD,oCAuCC"}
@@ -1,44 +1,38 @@
1
- export declare class CustomPermutationGenerator {
1
+ import { PermutationGeneratorForSet } from './PermutationGeneratorForSet';
2
+ export declare class CustomPermutationGenerator<T> {
2
3
  private elementList;
3
4
  private choicesByIndex;
4
5
  private nonChoicesByIndex;
5
- private elementsOrderAbs?;
6
- private elementsIndexRel;
6
+ private elementsOrderAbsolute?;
7
7
  private passFunction?;
8
- private randomizechoices?;
9
- set: any[];
10
- setAsStr: string[];
11
- permutationGenOfSet: any;
8
+ set: T[];
9
+ permutationGenOfSet: PermutationGeneratorForSet;
12
10
  nextIndexList: number[];
13
- choicesByIndexInSet: {};
14
- history: any[];
15
- historyHashes: any[];
16
- current: any[];
11
+ finalChoicesByIndexInSet: {
12
+ [key: string]: number[];
13
+ };
14
+ history: T[][];
15
+ historyHashes: string[];
16
+ current: T[];
17
17
  cursor: number;
18
- constructor(elementList: any[], choicesByIndex?: object, // ChoicesByIndex is relative to sub-sch so we need elementsIndexRel, a index list of sub-sch
19
- nonChoicesByIndex?: object, // nonChoices is also relative
20
- elementsOrderAbs?: any[], // Actual orders in final schdule
21
- elementsIndexRel?: any[], // Actual relative orders in sub-schedule
22
- passFunction?: Function, randomizechoices?: boolean);
23
- extendIndexesOfSameElements(choicesByIndex: any, indexesOfSameElements: any): void;
24
- init(): void;
25
- completeMissingChoicesIndexes(): void;
26
- setChoicesIndexesInSet(): void;
18
+ constructor(elementList: T[], choicesByIndex: Record<number, T[]>, nonChoicesByIndex: Record<number, T[]>, elementsOrderAbsolute?: number[] | undefined, passFunction?: ((items: T[]) => boolean) | undefined);
27
19
  removeNonChoicesIndexes(): void;
28
- getAllIndexesOfElementInList(el: any, list: any): any[];
29
- prev(): any;
30
- next(): any;
31
- nextDistinct(): false | {
32
- done: any;
33
- value: any;
20
+ setChoicesIndexesInSet(): void;
21
+ getAllIndexesOfElementInList(el: unknown, list: unknown[]): number[];
22
+ completeRestOfIndexes(): void;
23
+ extendIndexesOfSameElements(choicesByIndex: Record<string | number, any[]>, indexesOfSameElements: Record<number, number[]>): void;
24
+ prev(): T[] | undefined;
25
+ next(): T[] | null;
26
+ nextDistinct(): {
27
+ value: T[] | undefined;
28
+ done: boolean;
34
29
  };
35
30
  saveCurrentToHistory(): void;
36
- getHash(elList: any[]): string;
37
- getElementListByInitialListIndexes(indexes: any): any[];
38
- consecutiveDifferent(list: any[]): boolean;
31
+ getHash(elList: T[]): string;
32
+ getElementListByInitialListIndexes(indexes: number[]): T[];
39
33
  reset(): void;
40
- getSet(): any[];
34
+ getSet(): T[];
41
35
  isEmpty(): boolean;
42
- getCurrent(): any;
43
- last(): any;
36
+ getCurrent(): T[] | null;
37
+ last(): T[];
44
38
  }