JavaScript State Machine - Neat Solution


  • 0

    The idea is to define 4 states (functions) based on direction.

    Each state steps in one direction until it hits a boundary.

    Transitions:
    right => down
    down => left
    left => up
    up => right

    This continues until a base case is met.

    var spiralOrder = function(matrix) {
        if(matrix.length == 0) return matrix;
        if(matrix.length == 1) return matrix[0];
        if(matrix[0].length == 1){
            var output = [];
            matrix.forEach((row)=>{
                output.push(row[0]);
            });
            return output;
        }
        
        var initial_bounds = {
            n: 0,
            s: matrix.length-1,
            e: matrix[0].length-1,
            w: 0
        };
        var spiral = new Spiral(matrix, initial_bounds);
        return spiral.wind();
    };
    
    class Spiral {
        constructor( matrix, bounds ){
            this.matrix = matrix;
            this.bounds = bounds;
            this.row = 0;
            this.col = 0;
            this.state = this.right;
        }
    
        wind(){
            var output = [];
            this.col--; // because we have to step on first cell, then push its data
            while(this.state() !== false){
                output.push(this.matrix[this.row][this.col]);
            }
            return output;
        }
        
        right(){
            if(this.col === this.bounds.e) return false;
            this.col++;                         // update cursor
            if(this.col === this.bounds.e){     // watch for pivot point
                this.state = this.down;         // change directon
                this.bounds.n++;                // shrink bounds
            }
        }
        down(){
            if(this.row === this.bounds.s) return false;
            this.row++;
            if(this.row === this.bounds.s){
                this.state = this.left;
                this.bounds.e--;
            }
        }
        left(){
            if(this.col === this.bounds.w) return false;
            this.col--;
            if(this.col === this.bounds.w){
                this.state = this.up;
                this.bounds.s--;
            }
        }
        up(){
            if(this.row === this.bounds.n) return false;
            this.row--;
            if(this.row === this.bounds.n){
                this.state = this.right;
                this.bounds.w++;
            }
        }
    }
    

Log in to reply
 

Looks like your connection to LeetCode Discuss was lost, please wait while we try to reconnect.