Skip to content

Instantly share code, notes, and snippets.

@oversider-kosma
Created September 28, 2023 15:13
Show Gist options
  • Save oversider-kosma/db9f831212bc97f0155a4973162c353c to your computer and use it in GitHub Desktop.
Save oversider-kosma/db9f831212bc97f0155a4973162c353c to your computer and use it in GitHub Desktop.
hexlet snail
function* go_right(matrix, x, y, times) { for (let x_=x; x_ < x+times; x_++) yield matrix[y][x_]; }
function* go_left(matrix, x, y, times) { for (let x_=x; x_ > x-times; x_--) yield matrix[y][x_]; }
function* go_up(matrix, x, y, times) { for (let y_=y; y_ > y-times; y_--) yield matrix[y_][x]; }
function* go_down(matrix, x, y, times) { for (let y_=y; y_ < y+times; y_++) yield matrix[y_][x]; }
function* iter_snail(M) {
let cnt = 0;
let i = -1;
let funcs = [go_right, go_down, go_left, go_up];
let steps = [M[0].length, M.length];
let cur = [0, 0];
let inc = [1, -1, -1, 1];
let sign = [1, 1, -1, -1];
while (cnt < M[0].length*M.length) {
yield* funcs[++i%4](M, cur[0], cur[1], steps[i%2])
cnt += steps[i%2];
cur[i%2] += (steps[i%2] - 1)*sign[i%4];
cur[(i+1)%2] += inc[i%4]
steps[(i+1)%2]--;
}
}
function buildSnailPath(matrix) {
return Array.from(iter_snail(matrix));
}
/*driver*/
let M = [[1, 2, 3, 4],
[5, 6, 7, 8],
[9, 10, 11, 12],
[13, 14, 15, 16]];
let M2 = ['AFKS', 'WGCK', 'CCBK', 'QOPM'];
console.log(buildSnailPath(M));
console.log(buildSnailPath(M2));
/*
// less compact, but more readable version:
function* go_right(matrix, x, y, times){
for (let x_=x; x_ < x+times; x_++){
yield matrix[y][x_];
}
}
function* go_down(moses, x, y, times){
for (let y_=y; y_ < y+times; y_++){
yield moses[y_][x];
}
}
function* go_left(matrix, x, y, times){
for (let x_=x; x_ > x - times; x_--){
yield matrix[y][x_];
}
}
function* go_up(matrix, x, y, times){
for (let y_=y; y_ > y - times; y_--){
yield matrix[y_][x];
}
}
function* iter_snail(M) {
let sizeX = M[0].length;
let sizeY = M.length;
let stepsX = sizeX;
let stepsY = sizeY;
let total = sizeX*sizeY;
let curX = 0;
let curY = 0;
let cnt = 0;
while (cnt < total) {
yield* go_right(M, curX, curY, stepsX);
cnt += stepsX;
curX += stepsX-1;
curY++;
stepsY--;
if (cnt >= total)
break
yield* go_down(M, curX, curY, stepsY);
cnt += stepsY;
curY += stepsY-1;
curX--;
stepsX--;
if (cnt >= total)
break
yield* go_left(M, curX, curY, stepsX);
cnt += stepsX;
curX -= stepsX-1;
curY--;
stepsY--;
if (cnt >= total)
break
yield* go_up(M, curX, curY, stepsY);
cnt += stepsY;
curY -= stepsY-1;
curX++;
stepsX--;
if (cnt >= total)
break
}
}
*/
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment