Skip to content

Commit

Permalink
feat(grid-iterators): add diagonalSlopeX/Y()
Browse files Browse the repository at this point in the history
- add diagonal iterators with configurable slope (X & Y versions)
- update pkg deps
  • Loading branch information
postspectacular committed Mar 25, 2023
1 parent e20bf7b commit f63dc6e
Show file tree
Hide file tree
Showing 4 changed files with 110 additions and 0 deletions.
4 changes: 4 additions & 0 deletions packages/grid-iterators/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
"@thi.ng/arrays": "^2.5.8",
"@thi.ng/binary": "^3.3.21",
"@thi.ng/bitfield": "^2.2.24",
"@thi.ng/errors": "^2.2.13",
"@thi.ng/morton": "^3.1.32",
"@thi.ng/random": "^3.3.27",
"@thi.ng/transducers": "^8.4.0"
Expand Down Expand Up @@ -101,6 +102,9 @@
"./diagonal-ends": {
"default": "./diagonal-ends.js"
},
"./diagonal-slope": {
"default": "./diagonal-slope.js"
},
"./diagonal": {
"default": "./diagonal.js"
},
Expand Down
104 changes: 104 additions & 0 deletions packages/grid-iterators/src/diagonal-slope.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
import { assert } from "@thi.ng/errors/assert";
import type { GridIterOpts } from "./api.js";
import { __opts } from "./utils.js";

/**
* Similar to {@link diagonalSlopeX}. Yields sequence of 2D grid coordinates in
* diagonal order with configurable slope, starting at [0,0]. Each diagonal
* starts at y=0 and progresses in +y direction and every `slope` steps, one
* step in -x direction.
*
* @example
* ```ts
* // iterate grid in diagonals of 1:3 ratio (x:y)
* [...diagonalSlopeY({ cols: 5, slope: 3 })]
* // [
* // [0, 0], [0, 1 ], [0, 2 ],
* // [1, 0], [1, 1 ], [1, 2 ],
* // [0, 3], [0, 4 ], [2, 0 ],
* // [2, 1], [2, 2 ], [1, 3 ],
* // [1, 4], [3, 0 ], [3, 1 ],
* // [3, 2], [2, 3 ], [2, 4 ],
* // [4, 0], [4, 1 ], [4, 2 ],
* // [3, 3], [3, 4 ], [4, 3 ],
* // [4, 4]
* // ]
* ```
*
* @param opts -
*/
export function* diagonalSlopeY(opts: GridIterOpts & { slope: number }) {
const { cols, rows, tx } = __opts(opts);
const maxX = cols - 1;
const slope = opts.slope | 0;
assert(slope > 0, "slope must be > 0");
const num = cols * rows - 1;
let x = 0;
let y = 0;
let nx = Math.min(1, maxX);
let ny = nx > 0 ? 0 : slope;
let n = slope;
const reset = () => {
n = slope;
x = nx;
y = ny;
if (nx < maxX) nx++;
else ny += slope;
};
for (let i = 0; i <= num; i++) {
yield tx(x, y);
if (--n > 0) {
y++;
if (y >= rows) reset();
} else {
x--;
y++;
if (x < 0 || y >= rows) reset();
else n = slope;
}
}
}

/**
* Similar to {@link diagonalSlopeY}. Yields sequence of 2D grid coordinates in
* diagonal order with configurable slope, starting at [slope-1,0]. Each
* diagonal starts at y=0 and progresses in -x direction and every `slope`
* steps, one step in +y direction.
*
* @param opts -
*/
export function* diagonalSlopeX(opts: GridIterOpts & { slope: number }) {
const { cols, rows, tx } = __opts(opts);
const maxX = cols - 1;
const slope = opts.slope | 0;
assert(slope > 0, "slope must be > 0");
const num = cols * rows - 1;
let x = Math.min(slope - 1, maxX);
let y = 0;
let n = x + 1;
let nx = Math.min(x + slope, maxX);
let ny = nx > 0 ? 0 : slope;
const reset = () => {
x = nx;
y = ny;
if (nx < maxX) {
nx = Math.min(nx + slope, maxX);
n = slope;
} else {
ny++;
n = (x % slope) + 1;
}
};
for (let i = 0; i <= num; i++) {
yield tx(x, y);
if (--n > 0) {
x--;
if (x < 0) reset();
} else {
x--;
y++;
if (x < 0 || y >= rows) reset();
else n = slope;
}
}
}
1 change: 1 addition & 0 deletions packages/grid-iterators/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ export * from "./column-ends.js";
export * from "./columns.js";
export * from "./diagonal.js";
export * from "./diagonal-ends.js";
export * from "./diagonal-slope.js";
export * from "./diamond-square.js";
export * from "./flood-fill.js";
export * from "./hilbert.js";
Expand Down
1 change: 1 addition & 0 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -3802,6 +3802,7 @@ __metadata:
"@thi.ng/arrays": ^2.5.8
"@thi.ng/binary": ^3.3.21
"@thi.ng/bitfield": ^2.2.24
"@thi.ng/errors": ^2.2.13
"@thi.ng/morton": ^3.1.32
"@thi.ng/random": ^3.3.27
"@thi.ng/testament": ^0.3.13
Expand Down

0 comments on commit f63dc6e

Please sign in to comment.