y-ary 0.0.2
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/LICENSE +21 -0
- package/README.md +186 -0
- package/dist/index.cjs +261 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +247 -0
- package/dist/index.d.ts +247 -0
- package/dist/index.js +228 -0
- package/dist/index.js.map +1 -0
- package/package.json +57 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Amai Tsurai Donatsu
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
# Y-ary
|
|
2
|
+
|
|
3
|
+
<img src="./res/banner.webp" width="50%" alt="Y-ary Banner">
|
|
4
|
+
|
|
5
|
+
Y-ary is an experimental TypeScript library for mathematical operations and data generation.
|
|
6
|
+
It provides tools to evaluate mathematical formulas from strings with dynamic variables,
|
|
7
|
+
and generate controlled random arrays/matrices with sophisticated validation rules.
|
|
8
|
+
|
|
9
|
+
Perfect for: games, testing, simulations, educational tools, and mathematical experimentation.
|
|
10
|
+
|
|
11
|
+
## Features
|
|
12
|
+
|
|
13
|
+
### 🧮 Formula Interpreter
|
|
14
|
+
- **Dynamic Evaluation**: Interpret mathematical formulas as strings at runtime.
|
|
15
|
+
- **Variable Injection**: Easily map variable names to numeric values using the `where` object.
|
|
16
|
+
- **Full JavaScript Math Support**: Use standard operators (`+`, `-`, `*`, `/`, `**`, etc.) and all `Math` functions (e.g., `Math.sqrt`, `Math.pow`).
|
|
17
|
+
- **Safety Focused**: Uses the `Function` constructor for evaluation, providing a more controlled environment than `eval`.
|
|
18
|
+
- **Word-Boundary Precision**: Replaces variables only when they match as whole words, avoiding accidental partial replacements.
|
|
19
|
+
|
|
20
|
+
### 🎲 Smart Array Generation
|
|
21
|
+
- **Random Array Generation**: Create 1D arrays or 2D matrices with controlled randomization.
|
|
22
|
+
- **Occurrence Limits**: Define how many times each number can appear using a bank system.
|
|
23
|
+
- **30+ Validation Rules**: Pre-built rules for common patterns (parity, ranges, sequences, etc.).
|
|
24
|
+
- **Custom Rules**: Create your own validation functions for specific requirements.
|
|
25
|
+
- **Rule Combinators**: Combine rules with AND, OR, and NOT logic.
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
## Installation
|
|
29
|
+
|
|
30
|
+
### From npm registry
|
|
31
|
+
|
|
32
|
+
```bash
|
|
33
|
+
pnpm add y-ary
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
### From GitHub repository
|
|
37
|
+
|
|
38
|
+
Using **pnpm**:
|
|
39
|
+
```bash
|
|
40
|
+
pnpm add https://github.com/AmaiDonatsu/Y-ary.git
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
Using **npm**:
|
|
44
|
+
```bash
|
|
45
|
+
npm install https://github.com/AmaiDonatsu/Y-ary.git
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
## Usage
|
|
49
|
+
|
|
50
|
+
### Formula Interpreter
|
|
51
|
+
|
|
52
|
+
The `formulaInterpreter` function evaluates mathematical formulas with dynamic variables.
|
|
53
|
+
|
|
54
|
+
```typescript
|
|
55
|
+
import { formulaInterpreter } from 'y-ary';
|
|
56
|
+
|
|
57
|
+
// Basic usage
|
|
58
|
+
const result = formulaInterpreter('x / 1 + y', { x: 4, y: 6 });
|
|
59
|
+
console.log(result); // Output: 10
|
|
60
|
+
|
|
61
|
+
// Complex formulas with Math functions
|
|
62
|
+
const complexResult = formulaInterpreter('Math.sqrt(a) + Math.pow(b, 2) - c', {
|
|
63
|
+
a: 16,
|
|
64
|
+
b: 3,
|
|
65
|
+
c: 5
|
|
66
|
+
});
|
|
67
|
+
console.log(complexResult); // Output: 8 (4 + 9 - 5)
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
### Array Generation
|
|
71
|
+
|
|
72
|
+
Generate random arrays or matrices with controlled distribution and validation rules.
|
|
73
|
+
|
|
74
|
+
#### Basic 1D Array
|
|
75
|
+
```typescript
|
|
76
|
+
import { arrayWithBankNums } from 'y-ary';
|
|
77
|
+
|
|
78
|
+
// Generate array of length 5
|
|
79
|
+
// Each number (1-10) can appear up to 3 times
|
|
80
|
+
const array = arrayWithBankNums(
|
|
81
|
+
{ 1: 3, 2: 3, 3: 3, 4: 3, 5: 3, 6: 3, 7: 3, 8: 3, 9: 3, 10: 3 },
|
|
82
|
+
[5]
|
|
83
|
+
);
|
|
84
|
+
// Possible result: [3, 7, 1, 9, 2]
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
#### 2D Matrix
|
|
88
|
+
```typescript
|
|
89
|
+
// Generate 3x4 matrix (3 rows, 4 columns)
|
|
90
|
+
const matrix = arrayWithBankNums(
|
|
91
|
+
{ 1: 3, 2: 3, 3: 3, 4: 3, 5: 3, 6: 3 },
|
|
92
|
+
[3, 4]
|
|
93
|
+
);
|
|
94
|
+
// Possible result:
|
|
95
|
+
// [
|
|
96
|
+
// [1, 3, 2, 5],
|
|
97
|
+
// [4, 1, 6, 3],
|
|
98
|
+
// [2, 5, 4, 6]
|
|
99
|
+
// ]
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
#### Using Validation Rules
|
|
103
|
+
```typescript
|
|
104
|
+
import { arrayWithBankNums, onlyEven, inRange, and, noConsecutiveRepeats } from 'y-ary';
|
|
105
|
+
|
|
106
|
+
// Only even numbers
|
|
107
|
+
const evenArray = arrayWithBankNums(
|
|
108
|
+
{ 1: 3, 2: 3, 3: 3, 4: 3, 5: 3, 6: 3 },
|
|
109
|
+
[5],
|
|
110
|
+
onlyEven
|
|
111
|
+
);
|
|
112
|
+
// Possible result: [2, 4, 6, 2, 4]
|
|
113
|
+
|
|
114
|
+
// Combine multiple rules: even AND in range 2-8
|
|
115
|
+
const filtered = arrayWithBankNums(
|
|
116
|
+
{ 1: 3, 2: 3, 3: 3, 4: 3, 5: 3, 6: 3, 7: 3, 8: 3, 9: 3, 10: 3 },
|
|
117
|
+
[5],
|
|
118
|
+
and([onlyEven, inRange(2, 8)])
|
|
119
|
+
);
|
|
120
|
+
// Possible result: [2, 4, 6, 8, 2]
|
|
121
|
+
|
|
122
|
+
// No consecutive repeats
|
|
123
|
+
const noRepeats = arrayWithBankNums(
|
|
124
|
+
{ 1: 5, 2: 5, 3: 5 },
|
|
125
|
+
[10],
|
|
126
|
+
noConsecutiveRepeats
|
|
127
|
+
);
|
|
128
|
+
// Possible result: [1, 2, 3, 1, 2, 3, 2, 1, 3, 2]
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
#### Custom Validation Rules
|
|
132
|
+
```typescript
|
|
133
|
+
// Create your own rule
|
|
134
|
+
const customRule = (num: number, arr: number[]) => {
|
|
135
|
+
// Only allow numbers greater than the last element
|
|
136
|
+
if (arr.length === 0) return true;
|
|
137
|
+
return num > arr[arr.length - 1];
|
|
138
|
+
};
|
|
139
|
+
|
|
140
|
+
const ascending = arrayWithBankNums(
|
|
141
|
+
{ 1: 2, 2: 2, 3: 2, 4: 2, 5: 2 },
|
|
142
|
+
[5],
|
|
143
|
+
customRule
|
|
144
|
+
);
|
|
145
|
+
// Possible result: [1, 2, 3, 4, 5]
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
### Available Validation Rules
|
|
149
|
+
|
|
150
|
+
Y-ary includes 30+ pre-built validation rules:
|
|
151
|
+
|
|
152
|
+
**Parity**: `onlyEven`, `onlyOdd`
|
|
153
|
+
**Range**: `inRange(min, max)`, `notInRange(min, max)`
|
|
154
|
+
**Repetition**: `noConsecutiveRepeats`, `noDuplicates`, `maxOccurrences(n)`, `noRepeatInLast(n)`
|
|
155
|
+
**Sum/Average**: `sumLessThan(max)`, `averageInRange(min, max)`
|
|
156
|
+
**Sequence**: `ascending`, `descending`, `alternateEvenOdd`
|
|
157
|
+
**Divisibility**: `divisibleBy(n)`, `notDivisibleBy(n)`
|
|
158
|
+
**Advanced**: `onlyPrimes`, `onlySquares`, `maxDifference(n)`, `balanceEvenOdd(n)`
|
|
159
|
+
**Combinators**: `and([rules])`, `or([rules])`, `not(rule)`
|
|
160
|
+
|
|
161
|
+
See [docs/array-docs.md](./docs/array-docs.md) for complete documentation.
|
|
162
|
+
|
|
163
|
+
|
|
164
|
+
## Security Note
|
|
165
|
+
|
|
166
|
+
⚠️ **Formula Interpreter**: This library uses dynamic code evaluation. Only use it with trusted or validated formulas. Avoid evaluating formulas directly from untrusted user input without proper sanitization.
|
|
167
|
+
|
|
168
|
+
⚠️ **Array Generation**: Custom validation rules execute user-provided functions. Ensure that custom rules are from trusted sources and don't perform expensive operations that could impact performance.
|
|
169
|
+
|
|
170
|
+
|
|
171
|
+
## Development
|
|
172
|
+
|
|
173
|
+
```bash
|
|
174
|
+
# Install dependencies
|
|
175
|
+
pnpm install
|
|
176
|
+
|
|
177
|
+
# Build the package
|
|
178
|
+
pnpm build
|
|
179
|
+
|
|
180
|
+
# Watch mode during development
|
|
181
|
+
pnpm dev
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
## License
|
|
185
|
+
|
|
186
|
+
MIT
|
package/dist/index.cjs
ADDED
|
@@ -0,0 +1,261 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
// src/formulas/formulaInterpreter.ts
|
|
4
|
+
var formulaInterpreter = (formula, where) => {
|
|
5
|
+
let processedFormula = formula;
|
|
6
|
+
for (const [variable, value] of Object.entries(where)) {
|
|
7
|
+
const regex = new RegExp(`\\b${variable}\\b`, "g");
|
|
8
|
+
processedFormula = processedFormula.replace(regex, String(value));
|
|
9
|
+
}
|
|
10
|
+
try {
|
|
11
|
+
const result = new Function(`return ${processedFormula}`)();
|
|
12
|
+
return result;
|
|
13
|
+
} catch (error) {
|
|
14
|
+
throw new Error(`Invalid formula or evaluation error: ${error instanceof Error ? error.message : String(error)}`);
|
|
15
|
+
}
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
// src/algorithms/arrayGens.ts
|
|
19
|
+
var arrayWithBankNums = (bankNums, dims, extraRules) => {
|
|
20
|
+
const is2D = dims.length === 2;
|
|
21
|
+
const totalElements = is2D ? dims[0] * dims[1] : dims[0];
|
|
22
|
+
const flatArray = [];
|
|
23
|
+
const usageCount = {};
|
|
24
|
+
const availableNumbers = Object.keys(bankNums).map(Number);
|
|
25
|
+
for (let i = 0; i < totalElements; i++) {
|
|
26
|
+
let candidateNum = null;
|
|
27
|
+
let attempts = 0;
|
|
28
|
+
const maxAttempts = 1e3;
|
|
29
|
+
while (candidateNum === null && attempts < maxAttempts) {
|
|
30
|
+
attempts++;
|
|
31
|
+
const randomIndex = Math.floor(Math.random() * availableNumbers.length);
|
|
32
|
+
const selectedNum = availableNumbers[randomIndex];
|
|
33
|
+
const currentUsage = usageCount[selectedNum] || 0;
|
|
34
|
+
const maxUsage = bankNums[selectedNum];
|
|
35
|
+
if (currentUsage >= maxUsage) {
|
|
36
|
+
continue;
|
|
37
|
+
}
|
|
38
|
+
const passesExtraRules = extraRules ? extraRules(selectedNum, flatArray) : true;
|
|
39
|
+
if (passesExtraRules) {
|
|
40
|
+
candidateNum = selectedNum;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
if (candidateNum !== null) {
|
|
44
|
+
flatArray.push(candidateNum);
|
|
45
|
+
usageCount[candidateNum] = (usageCount[candidateNum] || 0) + 1;
|
|
46
|
+
} else {
|
|
47
|
+
console.warn(`Could not find valid number at position ${i} after ${maxAttempts} attempts`);
|
|
48
|
+
break;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
if (is2D) {
|
|
52
|
+
const rows = dims[0];
|
|
53
|
+
const cols = dims[1];
|
|
54
|
+
const matrix = [];
|
|
55
|
+
for (let row = 0; row < rows; row++) {
|
|
56
|
+
const rowArray = [];
|
|
57
|
+
for (let col = 0; col < cols; col++) {
|
|
58
|
+
const index = row * cols + col;
|
|
59
|
+
if (index < flatArray.length) {
|
|
60
|
+
rowArray.push(flatArray[index]);
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
matrix.push(rowArray);
|
|
64
|
+
}
|
|
65
|
+
return matrix;
|
|
66
|
+
}
|
|
67
|
+
return flatArray;
|
|
68
|
+
};
|
|
69
|
+
|
|
70
|
+
// src/algorithms/arrayRules.ts
|
|
71
|
+
var onlyEven = (num) => num % 2 === 0;
|
|
72
|
+
var onlyOdd = (num) => num % 2 !== 0;
|
|
73
|
+
var inRange = (min, max) => {
|
|
74
|
+
return (num) => num >= min && num <= max;
|
|
75
|
+
};
|
|
76
|
+
var notInRange = (min, max) => {
|
|
77
|
+
return (num) => num < min || num > max;
|
|
78
|
+
};
|
|
79
|
+
var noConsecutiveRepeats = (num, arr) => {
|
|
80
|
+
if (arr.length === 0) return true;
|
|
81
|
+
return arr[arr.length - 1] !== num;
|
|
82
|
+
};
|
|
83
|
+
var maxOccurrences = (maxCount) => {
|
|
84
|
+
return (num, arr) => {
|
|
85
|
+
const count = arr.filter((n) => n === num).length;
|
|
86
|
+
return count < maxCount;
|
|
87
|
+
};
|
|
88
|
+
};
|
|
89
|
+
var noDuplicates = (num, arr) => {
|
|
90
|
+
return !arr.includes(num);
|
|
91
|
+
};
|
|
92
|
+
var noRepeatInLast = (positions) => {
|
|
93
|
+
return (num, arr) => {
|
|
94
|
+
const lastN = arr.slice(-positions);
|
|
95
|
+
return !lastN.includes(num);
|
|
96
|
+
};
|
|
97
|
+
};
|
|
98
|
+
var sumLessThan = (maxSum) => {
|
|
99
|
+
return (num, arr) => {
|
|
100
|
+
const currentSum = arr.reduce((sum, n) => sum + n, 0);
|
|
101
|
+
return currentSum + num < maxSum;
|
|
102
|
+
};
|
|
103
|
+
};
|
|
104
|
+
var sumGreaterThan = (minSum) => {
|
|
105
|
+
return (num, arr) => {
|
|
106
|
+
const currentSum = arr.reduce((sum, n) => sum + n, 0);
|
|
107
|
+
return currentSum + num > minSum;
|
|
108
|
+
};
|
|
109
|
+
};
|
|
110
|
+
var averageInRange = (min, max) => {
|
|
111
|
+
return (num, arr) => {
|
|
112
|
+
if (arr.length === 0) return true;
|
|
113
|
+
const newSum = arr.reduce((sum, n) => sum + n, 0) + num;
|
|
114
|
+
const newAverage = newSum / (arr.length + 1);
|
|
115
|
+
return newAverage >= min && newAverage <= max;
|
|
116
|
+
};
|
|
117
|
+
};
|
|
118
|
+
var ascending = (num, arr) => {
|
|
119
|
+
if (arr.length === 0) return true;
|
|
120
|
+
return num > arr[arr.length - 1];
|
|
121
|
+
};
|
|
122
|
+
var descending = (num, arr) => {
|
|
123
|
+
if (arr.length === 0) return true;
|
|
124
|
+
return num < arr[arr.length - 1];
|
|
125
|
+
};
|
|
126
|
+
var different = (num, arr) => {
|
|
127
|
+
if (arr.length === 0) return true;
|
|
128
|
+
return num !== arr[arr.length - 1];
|
|
129
|
+
};
|
|
130
|
+
var alternateEvenOdd = (num, arr) => {
|
|
131
|
+
if (arr.length === 0) return true;
|
|
132
|
+
const lastWasEven = arr[arr.length - 1] % 2 === 0;
|
|
133
|
+
const currentIsEven = num % 2 === 0;
|
|
134
|
+
return lastWasEven !== currentIsEven;
|
|
135
|
+
};
|
|
136
|
+
var divisibleBy = (divisor) => {
|
|
137
|
+
return (num) => num % divisor === 0;
|
|
138
|
+
};
|
|
139
|
+
var notDivisibleBy = (divisor) => {
|
|
140
|
+
return (num) => num % divisor !== 0;
|
|
141
|
+
};
|
|
142
|
+
var byPosition = (rules) => {
|
|
143
|
+
return (num, arr) => {
|
|
144
|
+
const position = arr.length;
|
|
145
|
+
const rule = rules[position];
|
|
146
|
+
return rule ? rule(num, arr) : true;
|
|
147
|
+
};
|
|
148
|
+
};
|
|
149
|
+
var onEvenPositions = (rule) => {
|
|
150
|
+
return (num, arr) => {
|
|
151
|
+
const position = arr.length;
|
|
152
|
+
return position % 2 === 0 ? rule(num, arr) : true;
|
|
153
|
+
};
|
|
154
|
+
};
|
|
155
|
+
var onOddPositions = (rule) => {
|
|
156
|
+
return (num, arr) => {
|
|
157
|
+
const position = arr.length;
|
|
158
|
+
return position % 2 !== 0 ? rule(num, arr) : true;
|
|
159
|
+
};
|
|
160
|
+
};
|
|
161
|
+
var and = (rules) => {
|
|
162
|
+
return (num, arr) => {
|
|
163
|
+
return rules.every((rule) => rule(num, arr));
|
|
164
|
+
};
|
|
165
|
+
};
|
|
166
|
+
var or = (rules) => {
|
|
167
|
+
return (num, arr) => {
|
|
168
|
+
return rules.some((rule) => rule(num, arr));
|
|
169
|
+
};
|
|
170
|
+
};
|
|
171
|
+
var not = (rule) => {
|
|
172
|
+
return (num, arr) => {
|
|
173
|
+
return !rule(num, arr);
|
|
174
|
+
};
|
|
175
|
+
};
|
|
176
|
+
var onlyPrimes = (num) => {
|
|
177
|
+
if (num < 2) return false;
|
|
178
|
+
for (let i = 2; i <= Math.sqrt(num); i++) {
|
|
179
|
+
if (num % i === 0) return false;
|
|
180
|
+
}
|
|
181
|
+
return true;
|
|
182
|
+
};
|
|
183
|
+
var onlySquares = (num) => {
|
|
184
|
+
const sqrt = Math.sqrt(num);
|
|
185
|
+
return sqrt === Math.floor(sqrt);
|
|
186
|
+
};
|
|
187
|
+
var maxDifference = (maxDiff) => {
|
|
188
|
+
return (num, arr) => {
|
|
189
|
+
if (arr.length === 0) return true;
|
|
190
|
+
const diff = Math.abs(num - arr[arr.length - 1]);
|
|
191
|
+
return diff <= maxDiff;
|
|
192
|
+
};
|
|
193
|
+
};
|
|
194
|
+
var minDifference = (minDiff) => {
|
|
195
|
+
return (num, arr) => {
|
|
196
|
+
if (arr.length === 0) return true;
|
|
197
|
+
const diff = Math.abs(num - arr[arr.length - 1]);
|
|
198
|
+
return diff >= minDiff;
|
|
199
|
+
};
|
|
200
|
+
};
|
|
201
|
+
var balanceEvenOdd = (maxImbalance = 1) => {
|
|
202
|
+
return (num, arr) => {
|
|
203
|
+
const evenCount = arr.filter((n) => n % 2 === 0).length;
|
|
204
|
+
const oddCount = arr.length - evenCount;
|
|
205
|
+
const isEven = num % 2 === 0;
|
|
206
|
+
if (isEven) {
|
|
207
|
+
return evenCount + 1 - oddCount <= maxImbalance;
|
|
208
|
+
} else {
|
|
209
|
+
return oddCount + 1 - evenCount <= maxImbalance;
|
|
210
|
+
}
|
|
211
|
+
};
|
|
212
|
+
};
|
|
213
|
+
var valueAtPositions = (allowedPositions, value) => {
|
|
214
|
+
return (num, arr) => {
|
|
215
|
+
const currentPosition = arr.length;
|
|
216
|
+
if (num === value) {
|
|
217
|
+
return allowedPositions.includes(currentPosition);
|
|
218
|
+
}
|
|
219
|
+
return true;
|
|
220
|
+
};
|
|
221
|
+
};
|
|
222
|
+
|
|
223
|
+
// src/index.ts
|
|
224
|
+
function hello(name) {
|
|
225
|
+
return `Hello, ${name}!`;
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
exports.alternateEvenOdd = alternateEvenOdd;
|
|
229
|
+
exports.and = and;
|
|
230
|
+
exports.arrayWithBankNums = arrayWithBankNums;
|
|
231
|
+
exports.ascending = ascending;
|
|
232
|
+
exports.averageInRange = averageInRange;
|
|
233
|
+
exports.balanceEvenOdd = balanceEvenOdd;
|
|
234
|
+
exports.byPosition = byPosition;
|
|
235
|
+
exports.descending = descending;
|
|
236
|
+
exports.different = different;
|
|
237
|
+
exports.divisibleBy = divisibleBy;
|
|
238
|
+
exports.formulaInterpreter = formulaInterpreter;
|
|
239
|
+
exports.hello = hello;
|
|
240
|
+
exports.inRange = inRange;
|
|
241
|
+
exports.maxDifference = maxDifference;
|
|
242
|
+
exports.maxOccurrences = maxOccurrences;
|
|
243
|
+
exports.minDifference = minDifference;
|
|
244
|
+
exports.noConsecutiveRepeats = noConsecutiveRepeats;
|
|
245
|
+
exports.noDuplicates = noDuplicates;
|
|
246
|
+
exports.noRepeatInLast = noRepeatInLast;
|
|
247
|
+
exports.not = not;
|
|
248
|
+
exports.notDivisibleBy = notDivisibleBy;
|
|
249
|
+
exports.notInRange = notInRange;
|
|
250
|
+
exports.onEvenPositions = onEvenPositions;
|
|
251
|
+
exports.onOddPositions = onOddPositions;
|
|
252
|
+
exports.onlyEven = onlyEven;
|
|
253
|
+
exports.onlyOdd = onlyOdd;
|
|
254
|
+
exports.onlyPrimes = onlyPrimes;
|
|
255
|
+
exports.onlySquares = onlySquares;
|
|
256
|
+
exports.or = or;
|
|
257
|
+
exports.sumGreaterThan = sumGreaterThan;
|
|
258
|
+
exports.sumLessThan = sumLessThan;
|
|
259
|
+
exports.valueAtPositions = valueAtPositions;
|
|
260
|
+
//# sourceMappingURL=index.cjs.map
|
|
261
|
+
//# sourceMappingURL=index.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/formulas/formulaInterpreter.ts","../src/algorithms/arrayGens.ts","../src/algorithms/arrayRules.ts","../src/index.ts"],"names":[],"mappings":"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","file":"index.cjs","sourcesContent":["/**\r\n * Interprets a mathematical formula by replacing variables with their values\r\n * @param formula - Mathematical formula as a string (e.g., 'x/1 + y')\r\n * @param where - Object mapping variable names to their numeric values (e.g., {x: 4, y: 6})\r\n * @returns The evaluated result of the formula\r\n */\r\nexport const formulaInterpreter = (formula: string, where: { [key: string]: number }): number => {\r\n // Replace each variable in the formula with its value from the where object\r\n let processedFormula = formula;\r\n\r\n for (const [variable, value] of Object.entries(where)) {\r\n // Use regex with word boundaries to replace only complete variable names\r\n const regex = new RegExp(`\\\\b${variable}\\\\b`, 'g');\r\n processedFormula = processedFormula.replace(regex, String(value));\r\n }\r\n\r\n // Evaluate the mathematical expression\r\n // Using Function constructor is safer than eval for mathematical expressions\r\n try {\r\n const result = new Function(`return ${processedFormula}`)();\r\n return result;\r\n } catch (error) {\r\n throw new Error(`Invalid formula or evaluation error: ${error instanceof Error ? error.message : String(error)}`);\r\n }\r\n}","/**\r\n * Generates an array or matrix by randomly selecting numbers from a bank with occurrence limits.\r\n * \r\n * @param bankNums - Object where keys are the numbers to use and values are the maximum \r\n * number of times each number can appear in the array.\r\n * Example: { 1: 3, 2: 3, 3: 3 } means number 1 can appear up to 3 times,\r\n * number 2 can appear up to 3 times, etc.\r\n * \r\n * @param dims - Array dimensions:\r\n * - [length]: Creates a 1D array with the specified length\r\n * - [rows, cols]: Creates a 2D array (matrix) with the specified rows and columns\r\n * \r\n * @param extraRules - Optional validation callback that receives:\r\n * - candidateNum: The number being considered for addition\r\n * - currentArray: The flattened array built so far (for 2D arrays, this is all elements)\r\n * Returns true to allow the number, false to reject it and try another.\r\n * \r\n * @returns A 1D array or 2D array (matrix) of numbers randomly selected from bankNums,\r\n * respecting occurrence limits and any extra validation rules.\r\n * \r\n * @example\r\n * // Generate 1D array of length 5\r\n * const result1D = arrayWithBankNums(\r\n * { 1: 3, 2: 3, 3: 3, 4: 3, 5: 3, 6: 3, 7: 3, 8: 3, 9: 3, 10: 3 },\r\n * [5]\r\n * );\r\n * // Possible result: [3, 7, 1, 9, 2]\r\n * \r\n * @example\r\n * // Generate 2D array (matrix) of 3 rows x 4 columns\r\n * const result2D = arrayWithBankNums(\r\n * { 1: 3, 2: 3, 3: 3, 4: 3, 5: 3, 6: 3 },\r\n * [3, 4]\r\n * );\r\n * // Possible result: [[1, 3, 2, 5], [4, 1, 6, 3], [2, 5, 4, 6]]\r\n * \r\n * @example\r\n * // With extraRules: only allow even numbers\r\n * const result = arrayWithBankNums(\r\n * { 1: 3, 2: 3, 3: 3, 4: 3, 5: 3, 6: 3 },\r\n * [4],\r\n * (num, arr) => num % 2 === 0\r\n * );\r\n * // Possible result: [2, 4, 6, 2]\r\n */\r\nconst arrayWithBankNums = (\r\n bankNums: { [n: number]: number },\r\n dims: number[],\r\n extraRules?: (candidateNum: number, currentArray: number[]) => boolean\r\n): number[] | number[][] => {\r\n // Determine if we're creating a 1D or 2D array\r\n const is2D = dims.length === 2;\r\n const totalElements = is2D ? dims[0] * dims[1] : dims[0];\r\n\r\n const flatArray: number[] = [];\r\n\r\n // Track how many times each number has been used\r\n const usageCount: { [n: number]: number } = {};\r\n\r\n // Get available numbers from bankNums\r\n const availableNumbers = Object.keys(bankNums).map(Number);\r\n\r\n // Build flat array up to the total number of elements needed\r\n for (let i = 0; i < totalElements; i++) {\r\n let candidateNum: number | null = null;\r\n let attempts = 0;\r\n const maxAttempts = 1000; // Prevent infinite loops\r\n\r\n // Try to find a valid number\r\n while (candidateNum === null && attempts < maxAttempts) {\r\n attempts++;\r\n\r\n // Select a random number from available numbers\r\n const randomIndex = Math.floor(Math.random() * availableNumbers.length);\r\n const selectedNum = availableNumbers[randomIndex];\r\n\r\n // Check if this number hasn't exceeded its limit\r\n const currentUsage = usageCount[selectedNum] || 0;\r\n const maxUsage = bankNums[selectedNum];\r\n\r\n if (currentUsage >= maxUsage) {\r\n continue; // This number is exhausted, try another\r\n }\r\n\r\n // Apply extra rules if provided\r\n const passesExtraRules = extraRules ? extraRules(selectedNum, flatArray) : true;\r\n\r\n if (passesExtraRules) {\r\n candidateNum = selectedNum;\r\n }\r\n }\r\n\r\n // If we found a valid number, add it to the array\r\n if (candidateNum !== null) {\r\n flatArray.push(candidateNum);\r\n usageCount[candidateNum] = (usageCount[candidateNum] || 0) + 1;\r\n } else {\r\n // Could not find a valid number after max attempts\r\n console.warn(`Could not find valid number at position ${i} after ${maxAttempts} attempts`);\r\n break;\r\n }\r\n }\r\n\r\n // If 2D array requested, reshape the flat array into a matrix\r\n if (is2D) {\r\n const rows = dims[0];\r\n const cols = dims[1];\r\n const matrix: number[][] = [];\r\n\r\n for (let row = 0; row < rows; row++) {\r\n const rowArray: number[] = [];\r\n for (let col = 0; col < cols; col++) {\r\n const index = row * cols + col;\r\n if (index < flatArray.length) {\r\n rowArray.push(flatArray[index]);\r\n }\r\n }\r\n matrix.push(rowArray);\r\n }\r\n\r\n return matrix;\r\n }\r\n\r\n // Return 1D array\r\n return flatArray;\r\n};\r\n\r\nexport { arrayWithBankNums };","/**\r\n * Array Rules - Colección de funciones de validación para usar con arrayWithBankNums\r\n * \r\n * Estas funciones pueden ser usadas como el parámetro `extraRules` en arrayWithBankNums\r\n * para aplicar restricciones adicionales durante la generación del array.\r\n */\r\n\r\n/**\r\n * Type definition for array rule functions\r\n */\r\nexport type ArrayRule = (candidateNum: number, currentArray: number[]) => boolean;\r\n\r\n// ============================================================================\r\n// REGLAS BÁSICAS DE PARIDAD\r\n// ============================================================================\r\n\r\n/**\r\n * Solo permite números pares\r\n * @example arrayWithBankNums(bankNums, [5], onlyEven)\r\n */\r\nexport const onlyEven: ArrayRule = (num) => num % 2 === 0;\r\n\r\n/**\r\n * Solo permite números impares\r\n * @example arrayWithBankNums(bankNums, [5], onlyOdd)\r\n */\r\nexport const onlyOdd: ArrayRule = (num) => num % 2 !== 0;\r\n\r\n// ============================================================================\r\n// REGLAS DE RANGO\r\n// ============================================================================\r\n\r\n/**\r\n * Crea una regla que solo permite números dentro de un rango específico\r\n * @param min - Valor mínimo (inclusivo)\r\n * @param max - Valor máximo (inclusivo)\r\n * @example arrayWithBankNums(bankNums, [5], inRange(1, 5))\r\n */\r\nexport const inRange = (min: number, max: number): ArrayRule => {\r\n return (num) => num >= min && num <= max;\r\n};\r\n\r\n/**\r\n * Crea una regla que excluye números dentro de un rango específico\r\n * @param min - Valor mínimo a excluir (inclusivo)\r\n * @param max - Valor máximo a excluir (inclusivo)\r\n * @example arrayWithBankNums(bankNums, [5], notInRange(3, 7))\r\n */\r\nexport const notInRange = (min: number, max: number): ArrayRule => {\r\n return (num) => num < min || num > max;\r\n};\r\n\r\n// ============================================================================\r\n// REGLAS DE REPETICIÓN\r\n// ============================================================================\r\n\r\n/**\r\n * No permite números consecutivos repetidos\r\n * @example arrayWithBankNums(bankNums, [5], noConsecutiveRepeats)\r\n */\r\nexport const noConsecutiveRepeats: ArrayRule = (num, arr) => {\r\n if (arr.length === 0) return true;\r\n return arr[arr.length - 1] !== num;\r\n};\r\n\r\n/**\r\n * No permite que un número aparezca más de N veces en el array\r\n * @param maxCount - Número máximo de veces que puede aparecer\r\n * @example arrayWithBankNums(bankNums, [10], maxOccurrences(2))\r\n */\r\nexport const maxOccurrences = (maxCount: number): ArrayRule => {\r\n return (num, arr) => {\r\n const count = arr.filter(n => n === num).length;\r\n return count < maxCount;\r\n };\r\n};\r\n\r\n/**\r\n * No permite duplicados en el array (cada número solo puede aparecer una vez)\r\n * @example arrayWithBankNums(bankNums, [5], noDuplicates)\r\n */\r\nexport const noDuplicates: ArrayRule = (num, arr) => {\r\n return !arr.includes(num);\r\n};\r\n\r\n/**\r\n * No permite que el mismo número aparezca en las últimas N posiciones\r\n * @param positions - Número de posiciones a verificar\r\n * @example arrayWithBankNums(bankNums, [10], noRepeatInLast(3))\r\n */\r\nexport const noRepeatInLast = (positions: number): ArrayRule => {\r\n return (num, arr) => {\r\n const lastN = arr.slice(-positions);\r\n return !lastN.includes(num);\r\n };\r\n};\r\n\r\n// ============================================================================\r\n// REGLAS DE SUMA Y PROMEDIO\r\n// ============================================================================\r\n\r\n/**\r\n * Solo permite números que mantengan la suma total por debajo de un límite\r\n * @param maxSum - Suma máxima permitida\r\n * @example arrayWithBankNums(bankNums, [5], sumLessThan(20))\r\n */\r\nexport const sumLessThan = (maxSum: number): ArrayRule => {\r\n return (num, arr) => {\r\n const currentSum = arr.reduce((sum, n) => sum + n, 0);\r\n return currentSum + num < maxSum;\r\n };\r\n};\r\n\r\n/**\r\n * Solo permite números que mantengan la suma total por encima de un límite\r\n * @param minSum - Suma mínima requerida\r\n * @example arrayWithBankNums(bankNums, [5], sumGreaterThan(10))\r\n */\r\nexport const sumGreaterThan = (minSum: number): ArrayRule => {\r\n return (num, arr) => {\r\n const currentSum = arr.reduce((sum, n) => sum + n, 0);\r\n return currentSum + num > minSum;\r\n };\r\n};\r\n\r\n/**\r\n * Solo permite números que mantengan el promedio dentro de un rango\r\n * @param min - Promedio mínimo\r\n * @param max - Promedio máximo\r\n * @example arrayWithBankNums(bankNums, [5], averageInRange(3, 7))\r\n */\r\nexport const averageInRange = (min: number, max: number): ArrayRule => {\r\n return (num, arr) => {\r\n if (arr.length === 0) return true;\r\n const newSum = arr.reduce((sum, n) => sum + n, 0) + num;\r\n const newAverage = newSum / (arr.length + 1);\r\n return newAverage >= min && newAverage <= max;\r\n };\r\n};\r\n\r\n// ============================================================================\r\n// REGLAS DE SECUENCIA Y PATRÓN\r\n// ============================================================================\r\n\r\n/**\r\n * Solo permite números que sean mayores que el último número en el array (orden ascendente)\r\n * @example arrayWithBankNums(bankNums, [5], ascending)\r\n */\r\nexport const ascending: ArrayRule = (num, arr) => {\r\n if (arr.length === 0) return true;\r\n return num > arr[arr.length - 1];\r\n};\r\n\r\n/**\r\n * Solo permite números que sean menores que el último número en el array (orden descendente)\r\n * @example arrayWithBankNums(bankNums, [5], descending)\r\n */\r\nexport const descending: ArrayRule = (num, arr) => {\r\n if (arr.length === 0) return true;\r\n return num < arr[arr.length - 1];\r\n};\r\n\r\n/**\r\n * Solo permite números que sean diferentes del último número (no estrictamente ascendente/descendente)\r\n * @example arrayWithBankNums(bankNums, [5], different)\r\n */\r\nexport const different: ArrayRule = (num, arr) => {\r\n if (arr.length === 0) return true;\r\n return num !== arr[arr.length - 1];\r\n};\r\n\r\n/**\r\n * Alterna entre números pares e impares\r\n * @example arrayWithBankNums(bankNums, [6], alternateEvenOdd)\r\n */\r\nexport const alternateEvenOdd: ArrayRule = (num, arr) => {\r\n if (arr.length === 0) return true;\r\n const lastWasEven = arr[arr.length - 1] % 2 === 0;\r\n const currentIsEven = num % 2 === 0;\r\n return lastWasEven !== currentIsEven;\r\n};\r\n\r\n// ============================================================================\r\n// REGLAS DE DIVISIBILIDAD\r\n// ============================================================================\r\n\r\n/**\r\n * Solo permite números divisibles por un divisor específico\r\n * @param divisor - El divisor\r\n * @example arrayWithBankNums(bankNums, [5], divisibleBy(3))\r\n */\r\nexport const divisibleBy = (divisor: number): ArrayRule => {\r\n return (num) => num % divisor === 0;\r\n};\r\n\r\n/**\r\n * Solo permite números que NO sean divisibles por un divisor específico\r\n * @param divisor - El divisor\r\n * @example arrayWithBankNums(bankNums, [5], notDivisibleBy(5))\r\n */\r\nexport const notDivisibleBy = (divisor: number): ArrayRule => {\r\n return (num) => num % divisor !== 0;\r\n};\r\n\r\n// ============================================================================\r\n// REGLAS DE POSICIÓN\r\n// ============================================================================\r\n\r\n/**\r\n * Aplica diferentes reglas según la posición en el array\r\n * @param rules - Objeto que mapea índices a reglas\r\n * @example arrayWithBankNums(bankNums, [5], byPosition({ 0: onlyEven, 1: onlyOdd }))\r\n */\r\nexport const byPosition = (rules: { [index: number]: ArrayRule }): ArrayRule => {\r\n return (num, arr) => {\r\n const position = arr.length;\r\n const rule = rules[position];\r\n return rule ? rule(num, arr) : true;\r\n };\r\n};\r\n\r\n/**\r\n * Aplica una regla solo en posiciones pares (0, 2, 4, ...)\r\n * @param rule - La regla a aplicar\r\n * @example arrayWithBankNums(bankNums, [6], onEvenPositions(onlyEven))\r\n */\r\nexport const onEvenPositions = (rule: ArrayRule): ArrayRule => {\r\n return (num, arr) => {\r\n const position = arr.length;\r\n return position % 2 === 0 ? rule(num, arr) : true;\r\n };\r\n};\r\n\r\n/**\r\n * Aplica una regla solo en posiciones impares (1, 3, 5, ...)\r\n * @param rule - La regla a aplicar\r\n * @example arrayWithBankNums(bankNums, [6], onOddPositions(onlyOdd))\r\n */\r\nexport const onOddPositions = (rule: ArrayRule): ArrayRule => {\r\n return (num, arr) => {\r\n const position = arr.length;\r\n return position % 2 !== 0 ? rule(num, arr) : true;\r\n };\r\n};\r\n\r\n// ============================================================================\r\n// COMBINADORES DE REGLAS\r\n// ============================================================================\r\n\r\n/**\r\n * Combina múltiples reglas con AND (todas deben cumplirse)\r\n * @param rules - Array de reglas a combinar\r\n * @example arrayWithBankNums(bankNums, [5], and([onlyEven, inRange(2, 8)]))\r\n */\r\nexport const and = (rules: ArrayRule[]): ArrayRule => {\r\n return (num, arr) => {\r\n return rules.every(rule => rule(num, arr));\r\n };\r\n};\r\n\r\n/**\r\n * Combina múltiples reglas con OR (al menos una debe cumplirse)\r\n * @param rules - Array de reglas a combinar\r\n * @example arrayWithBankNums(bankNums, [5], or([onlyEven, divisibleBy(3)]))\r\n */\r\nexport const or = (rules: ArrayRule[]): ArrayRule => {\r\n return (num, arr) => {\r\n return rules.some(rule => rule(num, arr));\r\n };\r\n};\r\n\r\n/**\r\n * Invierte una regla (NOT)\r\n * @param rule - La regla a invertir\r\n * @example arrayWithBankNums(bankNums, [5], not(onlyEven)) // Solo impares\r\n */\r\nexport const not = (rule: ArrayRule): ArrayRule => {\r\n return (num, arr) => {\r\n return !rule(num, arr);\r\n };\r\n};\r\n\r\n// ============================================================================\r\n// REGLAS AVANZADAS\r\n// ============================================================================\r\n\r\n/**\r\n * Solo permite números primos\r\n * @example arrayWithBankNums(bankNums, [5], onlyPrimes)\r\n */\r\nexport const onlyPrimes: ArrayRule = (num) => {\r\n if (num < 2) return false;\r\n for (let i = 2; i <= Math.sqrt(num); i++) {\r\n if (num % i === 0) return false;\r\n }\r\n return true;\r\n};\r\n\r\n/**\r\n * Solo permite números que sean cuadrados perfectos\r\n * @example arrayWithBankNums(bankNums, [5], onlySquares)\r\n */\r\nexport const onlySquares: ArrayRule = (num) => {\r\n const sqrt = Math.sqrt(num);\r\n return sqrt === Math.floor(sqrt);\r\n};\r\n\r\n/**\r\n * Asegura que la diferencia entre números consecutivos no exceda un límite\r\n * @param maxDiff - Diferencia máxima permitida\r\n * @example arrayWithBankNums(bankNums, [5], maxDifference(3))\r\n */\r\nexport const maxDifference = (maxDiff: number): ArrayRule => {\r\n return (num, arr) => {\r\n if (arr.length === 0) return true;\r\n const diff = Math.abs(num - arr[arr.length - 1]);\r\n return diff <= maxDiff;\r\n };\r\n};\r\n\r\n/**\r\n * Asegura que la diferencia entre números consecutivos sea al menos un mínimo\r\n * @param minDiff - Diferencia mínima requerida\r\n * @example arrayWithBankNums(bankNums, [5], minDifference(2))\r\n */\r\nexport const minDifference = (minDiff: number): ArrayRule => {\r\n return (num, arr) => {\r\n if (arr.length === 0) return true;\r\n const diff = Math.abs(num - arr[arr.length - 1]);\r\n return diff >= minDiff;\r\n };\r\n};\r\n\r\n/**\r\n * Mantiene un balance entre números pares e impares\r\n * @param maxImbalance - Diferencia máxima permitida entre cantidad de pares e impares\r\n * @example arrayWithBankNums(bankNums, [10], balanceEvenOdd(2))\r\n */\r\nexport const balanceEvenOdd = (maxImbalance: number = 1): ArrayRule => {\r\n return (num, arr) => {\r\n const evenCount = arr.filter(n => n % 2 === 0).length;\r\n const oddCount = arr.length - evenCount;\r\n const isEven = num % 2 === 0;\r\n\r\n if (isEven) {\r\n return (evenCount + 1) - oddCount <= maxImbalance;\r\n } else {\r\n return (oddCount + 1) - evenCount <= maxImbalance;\r\n }\r\n };\r\n};\r\n\r\n/**\r\n * Solo permite números en posiciones específicas del array\r\n * @param allowedPositions - Array de posiciones permitidas (0-indexed)\r\n * @param value - El valor que solo puede aparecer en esas posiciones\r\n * @example arrayWithBankNums(bankNums, [5], valueAtPositions([0, 2, 4], 7))\r\n */\r\nexport const valueAtPositions = (allowedPositions: number[], value: number): ArrayRule => {\r\n return (num, arr) => {\r\n const currentPosition = arr.length;\r\n if (num === value) {\r\n return allowedPositions.includes(currentPosition);\r\n }\r\n return true;\r\n };\r\n};\r\n","/**\r\n * Y-ary package entry point\r\n * Export your public API here\r\n */\r\n\r\nexport function hello(name: string): string {\r\n return `Hello, ${name}!`;\r\n}\r\n\r\n// Export formula interpreter\r\nexport { formulaInterpreter } from './formulas/formulaInterpreter';\r\n\r\n// Export array generation\r\nexport { arrayWithBankNums } from './algorithms/arrayGens';\r\n\r\n// Export all array validation rules\r\nexport * from './algorithms/arrayRules';\r\n\r\n// Export types\r\nexport type { };\r\n"]}
|