RobotScript#3 字符串扁平化,處理()

task:

   上一題:RobotScript#2:實現循環指令的重複化(字符串擴展)並畫出軌跡

   基於RobotScript#2,(*)2 等價 **,示例如下:

    F4L((F4R)(F4L)2)2(F4R)2F4

     

 

解題:

  只要將“()”祛除即可,不考慮輸入字符串異常的情況下,最開始想到的是轉成AST,用text記錄文本,()最爲層級分割,但是沒能解答出來,於是用正則遞歸處理字符串,直到字符串中不存在括號。

   關鍵代碼如下:

    

function flatCode(code){
    if(code.indexOf('(')>-1){
        code = code.replace(/\([^=\)\()]*\)\d*/g,item=>{
        const  index = item.indexOf(')')
        if(index===item.length-1)return item.slice(1,index);
        else return item.slice(1,index).repeat(item.slice(index+1))
        })
        if(code.indexOf('(')>-1)return flatCode(code)
    }
    return code
}

完整代碼:

/**
 * L左轉,R右轉,F表示在當前方向向前進一,初始方向朝右,用*標記痕跡,F5表示走五次,類推
 * 如:LF5RF
 *     **
 *     *
 *     *
 *     *
 *     *
 *     *
 */
function execute(code){
    code = flatCode(code)
    code = code.replace(/[LFR]\d+/g, (m) => m[0].repeat(+m.slice(1)))
    let i = 0,j = 0,col,row,di = 0 ,dj = 1,grid = [['*']];
    for(let key = 0;key<code.length;key++){
        col = grid[0].length;
        row = grid.length;
        switch(code[key]){
           case "F":
            [i,j] = [i+di, j+dj];
            if(i<0)grid = [new Array(col).fill(" "),...grid];
            if(i>=row)grid = [...grid,new Array(col).fill(" ")];
            if(j<0)grid = grid.map(item=>{return [" ",...item]})
            if(j>=col)grid = grid.map(item=>{return [...item," "]})
            i = Math.max(0,i);
            j = Math.max(0,j);
           break;
           case "L":
            [di,dj] = [-dj,di]   
            break;
           case "R":
            [di,dj] = [dj,-di]    
           break;
        }
        grid[i][j] = "*"
    }
    return grid.map(item=>{return item.join('')}).join('\r\n')
}

function flatCode(code){
    if(code.indexOf('(')>-1){
        code = code.replace(/\([^=\)\()]*\)\d*/g,item=>{
        const  index = item.indexOf(')')
        if(index===item.length-1)return item.slice(1,index);
        else return item.slice(1,index).repeat(item.slice(index+1))
        })
        if(code.indexOf('(')>-1)return flatCode(code)
    }
    return code
}
console.log(execute('F4L((F4R)(F4L)2)2(F4R)2F4'))

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章