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

task:

你將遇到由L,R,F及數字組合而成的字符串,通過此字符串實現移動軌跡繪製,其中 L 代表當前方向向左拐,R代表向右,F表示在當前方向前進,用 "*" 標記走過的位置,其中只有F能夠產生"*",LR只有調整方向的作用,初始方向向右,並且會留下*;

字母后面接上數字表示字母會重複任意次。

示例:

LF5R5F5RFLFRFF

解答:

    首先要將接收的指令轉化爲連續的獨立的字符(指令),如接收的code爲“LF5”轉爲“LFFFFF”,直接利用正則匹配/[LRF]\d+/g,利用 replace 替換成 (m) => m[0].repeat(m.slice(1)),m爲匹配的字符串,因爲是 char 和 \d+ 組合的,故而可以直接使用repeat。

     然後就是軌跡繪製了,結合題意可知初始狀態時應爲二維數組 [["*"]] 的狀態,我們要在網格上進行繪製,二維數組可以看做直角座標系使用,但是沒有負座標軸,所以每次觸發 F 繪製時,要重新校準原點。

     方向與座標變動關係爲 (x+di,y+dj)

     →:di = 0, dj = 1;

     ↑  :di = 1, dj = 0;

     ←:di = 0,dj = -1;

     ↓  :di = -1,dj = 0; 

     易得每次變換方向 R : [di,dj] = [-dj,di]

                                   L  :[di,dj] = [dj,-di]

完整代碼:

/**
 * L左轉,R右轉,F表示在當前方向向前進一,初始方向朝右,用*標記痕跡,F5表示走五次,類推
 * 如:LF5RF
 *     **
 *     *
 *     *
 *     *
 *     *
 *     *
 */
function execute(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')
}
console.log(execute('LF5R5F5'))
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章