paizaラーニング レベルアップ問題集Aランクレベルアップメニュー JavaScript 座標系での向きの変わる移動

座標系での向きの変わる移動 (paizaランク B 相当)

https://paiza.jp/works/mondai/a_rank_level_up_problems/a_rank_snake_move_boss

JavaScriptで解いてみました。


# 解答例(C++の場合を参考)
各移動の方向LかRをmで受け取って、関数 move に現在の向きと移動の方向を渡し、関数を実行します。
```javascript
const fs = require("fs");
const input = fs.readFileSync("/dev/stdin", "utf-8").trim();
const lines = input.split("\n");

const direct = ['N','E','S','W'];
let dcount = 0;

//移動の関数定義
const move = (D, M) => {
   let [LR, add] = [1, 1];

    if(M == 'L'){
        LR = -1;
        add = 3;
    }

    if(D == 'N'){
        sx += LR;
        dcount += add;
    }else if(D == 'S'){
        sx -= LR;
        dcount += add;
    }else if(D == 'E'){
        sy += LR;
        dcount += add;
    }else{
        sy -= LR;
        dcount += add;
    }  
};

//開始時点の x , y 座標を表す X , Y, 移動の回数 N 
let [sx,sy,N] = lines[0].split(" ").map((num) => num = Number(num));

for (let i = 1; i <= N; i++){
    const m = lines[i];
    move(direct[dcount%4],m);//move関数実行
    console.log(sx + " " + sy); 
}
```
# 解答例(Python3の場合参考)
`directions = ["N","E","S","W"]`と`now_direction = 0`で方角を管理します。
Lなら`now_direction + 3`、Rなら`now_direction + 1`で方向転換をします。4以上になっても良いように`%4`します。
方角に応じてx,y方向に進みます。移動が終わった時のx,yが答えです。
```javascript:JavaScript
const fs = require("fs");
const input = fs.readFileSync("/dev/stdin", "utf-8").trim();
const lines = input.split("\n");
//開始時点の x , y 座標を表す X , Y, 移動の回数 N 
let [x,y,N] = lines[0].split(" ").map((num) => num = Number(num));
//方角
const directions = ["N","E","S","W"];
//方角を決めるインデックス
let now_direction = 0;

//移動
for (let i = 1; i <= N; i++) {
    //LかRか
    const lr = lines[i];
    if (lr === "L") {
        now_direction = (now_direction + 3) % 4;
    } else {
        now_direction = (now_direction + 1) % 4;
    }

    if (directions[now_direction] === "N") {
        y -= 1;
    } else if (directions[now_direction] === "E") {
        x += 1;
    } else if (directions[now_direction] === "S") {
        y += 1;
    } else if (directions[now_direction] === "W") {
        x -= 1;  
    }    
    console.log(x,y);
}
```

# 解答例(Ruby の場合参考)
方角移動を決める move は先頭から順に 北、東、南、西 になっています。
```javascript
const fs = require("fs");
const input = fs.readFileSync("/dev/stdin", "utf-8").trim();
const lines = input.split("\n");
let [x, y, N] = lines[0].split(" ").map(Number);
//方角[x, y]
const move = [[0, -1], [1, 0], [0, 1], [-1, 0]];//北東南西
let dir = 0;//向き

for (let i = 1; i <= N; i++) {
    const d = lines[i];
    //方向転換
    if (d === "L") {
        dir = (dir + 3) % 4;
    } else {
        dir = (dir + 1) % 4;
    }
    //移動
    [x, y] = [x + move[dir][0], y + move[dir][1]];
    console.log(x, y);
}
```

# 解答例(switch文)
switch文を使いました。東西南北と右左で場合分けをしました。
```javascript:JavaScript
const fs = require("fs");
const input = fs.readFileSync("/dev/stdin", "utf-8").trim();
const lines = input.split("\n");
//開始時点の x , y 座標を表す X , Y, 移動の回数 N 
const [X,Y,N] = lines[0].split(" ").map((num) => num = Number(num));

//開始時点の y , x 座標
let [x,y] = [X,Y];

//移動者ははじめ北を向いています。
let direction = 'N';
//移動
for (let i = 1; i <= N; i++) {
    //移動の向き d
    const d = lines[i];
    switch (direction) {
        case 'N':
            switch (d) {
                case 'L':
                    x -= 1;
                    direction = 'W';
                    break;
                case 'R':
                    x += 1;
                    direction = 'E';
                    break;
            }
            break;
        
         case 'S':
            switch (d) {
                case 'L':
                    x += 1;
                    direction = 'E';
                    break;
                case 'R':
                    x -= 1;
                    direction = 'W';
                    break;
            }
            break;
        
        case 'E':
            switch (d) {
                case 'L':
                    y -= 1;
                    direction = 'N';
                    break;
                case 'R':
                    y += 1;
                    direction = 'S';
                    break;
            }
            break;  
        
        case 'W':
            switch (d) {
                case 'L':
                    y += 1;
                    direction = 'S';
                    break;
                case 'R':
                     y -= 1;
                    direction = 'N';
                    break;
            }
            break; 
    
    } //switch          
    //各移動後の x , y 座標
    console.log(`${x} ${y}`);            
} //for   
```