@gkucmierz/utils 2.0.8 → 2.1.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/README.md CHANGED
@@ -48,6 +48,9 @@ This library provides a wide range of mathematical functions and data structures
48
48
  - `heronsFormula`: Triangle area calculation.
49
49
  - `squareRoot`: Integer square root using Newton's method.
50
50
 
51
+ - **Automata & Simulation**:
52
+ - `createLangtonsAnt`, `createUnlimitedGrid`: Infinite 2D grid and Langton's Ant cellular automaton engine (Project Euler 349 compatible).
53
+
51
54
  - **String & Encoding & Arrays**:
52
55
  - `base64`: Base64 and Base64Url encoding/decoding.
53
56
  - `copyCase`: Match case of a string to another.
package/main.mjs CHANGED
@@ -53,6 +53,9 @@ import {
53
53
  import {
54
54
  heronsFormula, heronsFormulaBI
55
55
  } from './src/herons-formula.mjs'
56
+ import {
57
+ createLangtonsAnt, createUnlimitedGrid
58
+ } from './src/langtons-ant.mjs'
56
59
  import {
57
60
  lcm, lcmBI
58
61
  } from './src/lcm.mjs'
@@ -132,6 +135,7 @@ export * from './src/gpn.mjs';
132
135
  export * from './src/gray-code.mjs';
133
136
  export * from './src/heap.mjs';
134
137
  export * from './src/herons-formula.mjs';
138
+ export * from './src/langtons-ant.mjs';
135
139
  export * from './src/lcm.mjs';
136
140
  export * from './src/list-node.mjs';
137
141
  export * from './src/lucas-lehmer.mjs';
@@ -154,5 +158,5 @@ export * from './src/square-root.mjs';
154
158
  export * from './src/tonelli-shanks.mjs';
155
159
 
156
160
  export default [
157
- SetCnt, Trie, arrayHistogram, fromBase64, fromBase64Url, toBase64, toBase64Url, bijective2num, bijective2numBI, num2bijective, num2bijectiveBI, binarySearchArr, binarySearchGE, binarySearchLE, binarySearchRangeIncl, combinations, combinationsIterator, consumeIteratorNonBlocking, copyCase, egcd, factors, factorsBI, formatBigNumber, formatBigNumberBI, wrapFn, gcd, gcdBI, getType, gpn, gpnBI, bin2gray, gray2bin, Heap, heronsFormula, heronsFormulaBI, lcm, lcmBI, ListNode, lucasLehmerBI, axisAngleToMatrix4, crossProduct, dotProduct, getRotationMatrixFromVectors, multiplyMatrix4, normalize, projectToTrackball, matrixAsArray, memoize, mod, modBI, nChooseK, naturalSearch, nelderMead, particleSwarmOptimization, permutations, permutationsIterator, phi, phiBI, powMod, powModBI, randNormal, array2range, range2array, setSafeInterval, simulatedAnnealing, squareRoot, squareRootBI, tonelliShanksBI
161
+ SetCnt, Trie, arrayHistogram, fromBase64, fromBase64Url, toBase64, toBase64Url, bijective2num, bijective2numBI, num2bijective, num2bijectiveBI, binarySearchArr, binarySearchGE, binarySearchLE, binarySearchRangeIncl, combinations, combinationsIterator, consumeIteratorNonBlocking, copyCase, egcd, factors, factorsBI, formatBigNumber, formatBigNumberBI, wrapFn, gcd, gcdBI, getType, gpn, gpnBI, bin2gray, gray2bin, Heap, heronsFormula, heronsFormulaBI, createLangtonsAnt, createUnlimitedGrid, lcm, lcmBI, ListNode, lucasLehmerBI, axisAngleToMatrix4, crossProduct, dotProduct, getRotationMatrixFromVectors, multiplyMatrix4, normalize, projectToTrackball, matrixAsArray, memoize, mod, modBI, nChooseK, naturalSearch, nelderMead, particleSwarmOptimization, permutations, permutationsIterator, phi, phiBI, powMod, powModBI, randNormal, array2range, range2array, setSafeInterval, simulatedAnnealing, squareRoot, squareRootBI, tonelliShanksBI
158
162
  ];
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gkucmierz/utils",
3
- "version": "2.0.8",
3
+ "version": "2.1.0",
4
4
  "type": "module",
5
5
  "description": "Usefull functions for solving programming tasks",
6
6
  "keywords": [
@@ -19,8 +19,10 @@
19
19
  "iterator",
20
20
  "javascript",
21
21
  "lcm",
22
+ "langtons-ant",
22
23
  "lucas-lehmer",
23
24
  "math",
25
+ "cellular-automaton",
24
26
  "memoize",
25
27
  "mersenne",
26
28
  "mod",
@@ -0,0 +1,79 @@
1
+ /**
2
+ * Creates an unlimited, dynamically expanding 2D grid using nested Maps.
3
+ * Ideal for sparse matrices or algorithms operating on an infinite plane (e.g., Langton's Ant, Game of Life).
4
+ *
5
+ * @returns {Object} An object containing `get(x, y)` and `set(x, y, val)` methods.
6
+ */
7
+ export const createUnlimitedGrid = () => {
8
+ const grid = new Map();
9
+
10
+ const getRow = y => {
11
+ let row;
12
+ if (!(row = grid.get(y))) {
13
+ row = new Map();
14
+ grid.set(y, row);
15
+ }
16
+ return row;
17
+ };
18
+
19
+ const set = (x, y, val) => {
20
+ const row = getRow(y);
21
+ row.set(x, val);
22
+ };
23
+
24
+ const get = (x, y) => {
25
+ const row = getRow(y);
26
+ return row.get(x) || 0;
27
+ };
28
+
29
+ return { set, get };
30
+ };
31
+
32
+ /**
33
+ * Initializes a Langton's Ant automaton on a given grid.
34
+ * The ant follows standard rules: turns right on 0, turns left on 1, and flips the cell state.
35
+ *
36
+ * @param {Object} grid - The grid interface containing `get(x, y)` and `set(x, y, val)` methods.
37
+ * @param {number} startX - The initial X coordinate of the ant.
38
+ * @param {number} startY - The initial Y coordinate of the ant.
39
+ * @param {number} [initialDir=-1] - The initial direction (0: TOP, 1: RIGHT, 2: BOTTOM, 3: LEFT). If -1, a random direction is chosen.
40
+ * @returns {Object} An object containing a `step()` method which advances the simulation by one tick and returns `{x, y, state}` of the modified cell.
41
+ */
42
+ export const createLangtonsAnt = (grid, startX, startY, initialDir = -1) => {
43
+ const [X, Y] = [0, 1];
44
+ const [TOP, RIGHT, BOT, LEFT] = [0, 1, 2, 3];
45
+ const coordMap = new Map([
46
+ [TOP, [ 0,-1]],
47
+ [RIGHT, [ 1, 0]],
48
+ [BOT, [ 0, 1]],
49
+ [LEFT, [-1, 0]],
50
+ ]);
51
+
52
+ let dir = initialDir !== -1 ? initialDir : Math.floor(Math.random() * 4);
53
+ const pos = [startX, startY];
54
+
55
+ const step = () => {
56
+ const currentState = grid.get(pos[X], pos[Y]);
57
+ const nextState = currentState === 0 ? 1 : 0;
58
+
59
+ grid.set(pos[X], pos[Y], nextState);
60
+
61
+ if (currentState === 0) {
62
+ dir = (dir + 1) % 4; // Turn Right
63
+ } else {
64
+ dir = (dir + 3) % 4; // Turn Left
65
+ }
66
+
67
+ const move = coordMap.get(dir);
68
+ pos[X] += move[X];
69
+ pos[Y] += move[Y];
70
+
71
+ return {
72
+ x: pos[X] - move[X],
73
+ y: pos[Y] - move[Y],
74
+ state: nextState
75
+ };
76
+ };
77
+
78
+ return { step };
79
+ };