今回は paiza の「座標系での向きの変わる移動」の問題に挑戦!
🧩 問題概要
- スタート位置 (
X,Y) と移動回数Nが与えられる - 続く
N行にL/Rが順に与えられる-
L= 現在向いている方向から 左向いて1マス進む -
R= 現在向いている方向から 右向いて1マス進む
-
- 開始時の向きは 北
- 座標系の向きにも注意
- 右が x 正
- 下が y 正
- 各移動後の座標を毎回出力する
入力例:
-18 45 6
L
L
R
R
L
R
出力例:
-19 45
-19 46
-20 46
-20 45
-21 45
-21 44
✅ OK例:
const rl = require('readline').createInterface({ input: process.stdin });
const lines = [];
rl.on('line', input => lines.push(input));
rl.on('close', () => {
const [X, Y, N] = lines[0].split(' ').map(Number);
const d = lines.slice(1);
let x = X;
let y = Y;
let dir = 'N';
for (let i = 0; i < N; i++) {
if (dir === 'N') {
if (d[i] === 'L') {
x--;
dir = 'W'
} else { // d[i] === 'R'
x++;
dir = 'E';
}
}
else if (dir === 'S') {
if (d[i] === 'L') {
x++;
dir = 'E'
} else {
x--;
dir = 'W';
}
} else if (dir === 'E') {
if (d[i] === 'L') {
y--;
dir = 'N'
} else {
y++;
dir = 'S';
}
} else { // dir === 'W'
if (d[i] === 'L') {
y++;
dir = 'S'
} else {
y--;
dir = 'N';
}
}
console.log(x, y);
}
});
🔍 コードの流れ
- 1 行目から開始座標 (
X,Y) と移動回数Nを読み取る - 移動方向の配列
dに 2 行目以降の文字列(L/R)を格納 - 初期位置
x,yを設定し、向きdirを北(N)に設定 -
N回ループし、以下を行う- 現在の向き
dirと入力d[i]により- 向きを更新
-
xまたはyを ±1 移動
- 移動後の
x, yを出力
- 現在の向き
- 全移動が終わったら終了
✅ OK例 2:
const rl = require('readline').createInterface({ input: process.stdin });
const lines = [];
rl.on('line', line => lines.push(line));
rl.on('close', () => {
const [X, Y, N] = lines[0].split(' ').map(Number);
const moves = lines.slice(1);
// 方角: 0=北,1=東,2=南,3=西
let dir = 0;
let x = X;
let y = Y;
// dx,dy 表
const dx = [0, 1, 0, -1];
const dy = [-1, 0, 1, 0]; // 下が正なので北は y-1
for (let i = 0; i < N; i++) {
if (moves[i] === 'R') dir = (dir + 1) % 4;
else dir = (dir + 3) % 4; // L は -1 と同じ
x += dx[dir];
y += dy[dir];
console.log(x, y);
}
});
🔍 コードの流れ
- 1 行目から開始座標 (
X,Y) と移動回数Nを取得 - 移動方向を
movesに格納 - 方向を数値
dirで管理(0=北, 1=東, 2=南, 3=西) - 移動ベクトル
dx,dyを定義 -
N回ループし、以下を実行- 移動指示が
R→dir = (dir + 1) % 4 - 移動指示が
L→dir = (dir + 3) % 4 x += dx[dir]-
y += dy[dir]で座標更新 - 更新後の
x, yを出力
- 移動指示が
- 全移動終了
🗒️ まとめ
- 方向は毎回変わる → 移動前の向きが重要
- 向きに応じて
L/Rの進む方向が変わる
例)北向きだと L=西, R=東 - 向きの管理方法は2種類ある
- 文字列(
N,E,S,W)で分岐 - 数値(
0~3)+dx/dy配列で計算
- 文字列(
- 数値化すると、方向操作が簡単
-
R→+1 -
L→-1(+3 と同じ)
→dir = (dir + 1) % 4/dir = (dir + 3) % 4
-
-
dx/dy配列により、座標更新が1行でできる - 毎回、移動後の座標を出力すること