Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to print an ascii square spiral to the console

This was an interview question that I couldn't figure out..

Print out the following output to the JavaScript console (or whatever console you use)

My attempt to solve this was to build an array of stars, and an array of spaces.

Then to print each line one by one modifying it by adding a star or changing a star to a space.

But this does not build the whole spiral. It only builds the top half, so I'm wondering if there is a more elegant solution?

It feels like some sort of a recursive function would be good for this?

var starLine = [];
var spaceLine = [];
for (var i = 0; i < 33; i++) {
    starLine.push('*');
    spaceLine.push(' ');
}

console.log(starLine.join(' '));
for (var i = 1; i <= 32/2; i+=2) {
    spaceLine[(i-1)] = '*';
    spaceLine[32-(i-1)] = '*';
    starLine[i] = ' ';
    starLine[32-(i)] = ' '; 
    console.log(spaceLine.join(' '));
    console.log(starLine.join(' '));
}

Edit: My attempt at a recursive solution. I got pretty close, but it's still somewhat hacky: https://jsfiddle.net/6fa9uty3/

    * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *      
    *                                                               *      
    *   * * * * * * * * * * * * * * * * * * * * * * * * * * * * *   *      
    *   *                                                       *   *      
    *   *   * * * * * * * * * * * * * * * * * * * * * * * * *   *   *      
    *   *   *                                               *   *   *      
    *   *   *   * * * * * * * * * * * * * * * * * * * * *   *   *   *      
    *   *   *   *                                       *   *   *   *      
    *   *   *   *   * * * * * * * * * * * * * * * * *   *   *   *   *      
    *   *   *   *   *                               *   *   *   *   *      
    *   *   *   *   *   * * * * * * * * * * * * *   *   *   *   *   *      
    *   *   *   *   *   *                       *   *   *   *   *   *      
    *   *   *   *   *   *   * * * * * * * * *   *   *   *   *   *   *      
    *   *   *   *   *   *   *               *   *   *   *   *   *   *      
    *   *   *   *   *   *   *   * * * * *   *   *   *   *   *   *   *      
    *   *   *   *   *   *   *   *       *   *   *   *   *   *   *   *      
    *   *   *   *   *   *   *   *   *   *   *   *   *   *   *   *   *      
    *   *   *   *   *   *   *   *   * * *   *   *   *   *   *   *   *      
    *   *   *   *   *   *   *   *           *   *   *   *   *   *   *      
    *   *   *   *   *   *   *   * * * * * * *   *   *   *   *   *   *      
    *   *   *   *   *   *   *                   *   *   *   *   *   *      
    *   *   *   *   *   *   * * * * * * * * * * *   *   *   *   *   *      
    *   *   *   *   *   *                           *   *   *   *   *      
    *   *   *   *   *   * * * * * * * * * * * * * * *   *   *   *   *      
    *   *   *   *   *                                   *   *   *   *      
    *   *   *   *   * * * * * * * * * * * * * * * * * * *   *   *   *      
    *   *   *   *                                           *   *   *      
    *   *   *   * * * * * * * * * * * * * * * * * * * * * * *   *   *      
    *   *   *                                                   *   *      
    *   *   * * * * * * * * * * * * * * * * * * * * * * * * * * *   *   *  
    *   *                                                           *   *  
    *   * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *   *  
    *                                                                   *  
    * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 

(Image in case text doesn't render properly) square spiral

like image 601
Atomix Avatar asked Dec 01 '25 18:12

Atomix


2 Answers

Solution: https://jsfiddle.net/oc5b5qzh/ - View console window in browser to see the spiral.

Keep size odd. I used different letters instead of * for each case just so you could see what part of the loop solved that case. Could obviously be compressed more, but that would just make it less readable.

Note: Doesn't match what you have exactly. I think mine spirals the other direction.

var size = 21;

for (var h = 0; h < size; h++) {
    var line = "";
    for (var w = 0; w < size; w++) {
        if (h < size/2) {
            if (h % 2 === 0) {
                if (w >= h && w < size - h) {
                    line += "A";
                }
                else {
                    line += (w % 2 === 0) ? "B" : " ";
                }
            }
            else {
                if (w >= h && w < size - h) {
                    line += " ";
                }
                else {
                    line += (w % 2 === 0) ? "C" : " ";
                }
            }
        }
        else {
            if (h % 2 === 0) {
                if (w < h - 1 && w >= size - h) {
                    line += "D";
                }
                else {
                    line += (w % 2 === 0) ? "E" : " ";
                }
            }
            else {
                if (w < h - 1 && w >= size - h) {
                    line += " ";
                }
                else {
                    line += (w % 2 === 0) ? "F" : " ";
                }
            }
        }
    }
    console.log(line);
}
like image 50
Mike Avatar answered Dec 04 '25 08:12

Mike


I have a python solution pixelscan that can traverse pixels in a variety of spatial patterns, including square rings like you have. The basic idea is move pixel-to-pixel in one of the 8 cardinal directions while maintaining a particular metric constant per ring, in your case it is the chebyshev metric.

like image 24
dpmcmlxxvi Avatar answered Dec 04 '25 07:12

dpmcmlxxvi