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'))
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章