skip to Main Content

I was trying to solve the following problem:

Given an odd integer "n" such that √(n)^2 = n (perfect square), ex. 1, 9, 25, 49, 81…
Generate a matrix of n coordinates (x, y) occurrences

This is my solution:

// PasteCount - An odd integer such that √(PasteCount)^2 = PasteCount ex. 1, 9, 25, 49, 81...
// Distance (d) - Any positive integer
function snailGeneration(pasteCount, distance) {
    let x = 0;
    let y = 0;

    console.log(x + " , " + y); // 1st move is always done

    let totalMoves = 1;
    let rightAndUpMoves = 1;
    let leftAndDownMoves = 2;


    while (true) {
        // 1st loop - go right - 1 move, 3 moves, 5 moves, 7 moves, 9 moves
        // This loop has check on counter at every iteration to see if pasteCount has been reached.
        // go right => do (x + d) for n moves - y stays unchanged from last loop
        for (let i = 0; i < rightAndUpMoves; i++) {
            x += distance;
            totalMoves += 1;
            console.log(x + " , " + y);

            if (totalMoves == pasteCount) return;
        }

        // 2nd loop - go up - 1 move, 3 moves, 5 moves, 7 moves, 9 moves
        // go up => do (y + d) for n moves - x stays unchanged from last loop
        for (let i = 0; i < rightAndUpMoves; i++) {
            y += distance;
            totalMoves += 1;
            console.log(x + " , " + y);
        }

        // 3rd loop - go left - 2 moves, 4 moves, 6 moves, 8 moves, 10 moves
        // go left => do (x - d) for n moves - y stays unchanged from last loop
        for (let i = 0; i < leftAndDownMoves; i++) {
            x -= distance;
            totalMoves += 1;
            console.log(x + " , " + y);
        }

        // 4th loop - go down - 2 moves, 4 moves, 6 moves, 8 moves, 10 moves
        // go down => do (y - d) for n moves - x stays unchanged from last loop
        for (let i = 0; i < leftAndDownMoves; i++) {
            y -= distance;
            totalMoves += 1;
            console.log(x + " , " + y);
        }

        // Incremeting pattern for every loop of +2.
        // Everytime we enter a loop the total iterations is increased by two.
        // At the end of the while, increment the total iterations for the loops.
        rightAndUpMoves += 2;
        leftAndDownMoves += 2;
    }
}

Basically if we try to visualise it by calling snailGeneration(9, 1) it looks like this:

image

Is there a way to implement this in a more efficient way?
Can you suggest any alternative solutions?

2

Answers


  1. I would use vectors and 2 nested for loops …

    int nn = 25;                // input n^2 number of coordinates
    int  n = sqrt(nn);          // input n size of square size
    int i,j,k,m,x,y,dx,dy;
    x=n>>1; dx= 0;              // initial position and direction
    y=n>>1; dy=+1;
    for (i=0,k=0,m=1;i<nn;k++)  // outter loop going through all positions
        {
        for (j=0;;i++,j++)      // inner loop going through single direction (line)
            {
            if (i>=nn) break;
            Here output/use your (x,y) coordinate ...
            if (j>=m) break;
            x+=dx;
            y+=dy;
            }
        if ((k&1)==1) m++;      // increase line length every other line
        j=dx; dx=+dy; dy=-j;    // rotate direction CCW by 90 deg
    //  j=dx; dx=-dy; dy=+j;    // rotate direction CW by 90 deg
        }
    }
    
    Login or Signup to reply.
  2. You could determine the modification in each iteration of a single loop. This function is also a good candidate for a generator function:

    function* snailGeneration(square, d) {
        let x = 0, y = 0;
        while (square--) {
            yield [x, y];
            if (Math.abs(y) < x || Math.abs(y-0.5) < -x) y += x < 0 ? -d : d;
                                                    else x += y > 0 ? -d : d;
        }
    }
    
    // Demo: square with 25 values, with distance of 2:
    for (let pair of snailGeneration(25, 2)) {
        console.log(...pair);
    }
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search