Skip to content

Instantly share code, notes, and snippets.

@gvergnaud
Last active February 21, 2020 13:42
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save gvergnaud/e6a2e5940a277e5538ed228f52eeaeae to your computer and use it in GitHub Desktop.
Save gvergnaud/e6a2e5940a277e5538ed228f52eeaeae to your computer and use it in GitHub Desktop.
const between = (min: number, max: number, x: number) =>
Math.max(min, Math.min(max, x));
type Point = { x: number; y: number };
type Direction = 'up' | 'down' | 'left' | 'right';
export function* lazySpiralGenerator(
width: number,
height: number,
startPos: Point
): Generator<{ x: number; y: number; direction: Direction }> {
let direction: Direction = 'up';
let x = startPos.x;
let y = startPos.y;
let maxReachedX = x;
let minReachedX = x;
let maxReachedY = y;
let minReachedY = y;
while (
minReachedX !== 0 &&
minReachedY !== 0 &&
maxReachedX !== width &&
maxReachedY !== height
) {
const currentDirection = direction;
switch (direction) {
case 'up':
y--;
if (y < minReachedY) {
direction = 'right';
minReachedY = y;
y = between(0, width, y);
}
break;
case 'right':
x--;
if (x < minReachedX) {
direction = 'down';
minReachedX = x;
x = between(0, height, x);
}
break;
case 'down':
y++;
if (y > maxReachedY) {
direction = 'left';
maxReachedY = y;
y = between(0, width, y);
}
break;
case 'left':
x++;
if (x > maxReachedX) {
direction = 'up';
maxReachedX = x;
x = between(0, height, x);
}
break;
}
yield { x, y, direction: currentDirection };
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment