今回は paiza の「移動が可能かの判定・方角」の問題に挑戦!
似たような問題だけど、新たなシリーズに突入!
🧩 問題概要
-
H×Wのマップが与えられる -
'.'= 移動可能,'#'= 障害物 - 現在の位置 (
sy,sx) と移動方向m(N/S/E/W) が与えられる - 1 マスだけ、
mの方向に移動できるか判定する
※ 移動可能とは、移動先が「マップの範囲内」かつ「'.'」であること
入力例:
3 3 1 1 E // H W sy sx m
..# // S_i
..#
...
出力例:
No
✅ OK例:
const rl = require('readline').createInterface({ input: process.stdin });
const lines = [];
rl.on('line', input => lines.push(input));
rl.on('close', () => {
const [H, W, sy, sx, m] = lines[0].split(' ');
const gridS = lines.slice(1).map(line => line.split(''));
const y = Number(sy);
const x = Number(sx);
if (m === 'N') {
if (y-1 >= 0 && gridS[y-1][x] === '.') {
console.log('Yes');
} else { // === '#'
console.log('No');
}
} else if (m === 'S') {
if (y+1 < Number(H) && gridS[y+1][x] === '.') {
console.log('Yes');
} else {
console.log('No');
}
} else if (m === 'E') {
if (x+1 < Number(W) && gridS[y][x+1] === '.') {
console.log('Yes');
} else {
console.log('No');
}
} else { // === 'W'
if (x-1 >= 0 && gridS[y][x-1] === '.') {
console.log('Yes');
} else {
console.log('No');
}
}
});
🔍 コードの流れ
- 入力を
linesに読み込む - 1 行目から
-
H, W, sy, sx, mを取得(マップサイズ・現在座標・移動方向) - 2 行目以降をマップ
gridSとして配列化 - 現在位置
y,xを数値に変換して設定 - 移動方向
mに応じて以下を判定- 北なら
y-1が範囲内かつ移動先が'.'か - 南なら
y+1が範囲内かつ移動先が'.'か - 東なら
x+1が範囲内かつ移動先が'.'か - 西なら
x-1が範囲内かつ移動先が'.'か
- 北なら
- 条件を満たせば
"Yes"、満たさなければ"No"を出力
✨ 短縮例:
const rl = require('readline').createInterface({ input: process.stdin });
const lines = [];
rl.on('line', input => lines.push(input));
rl.on('close', () => {
const [H, W, sy, sx, m] = lines[0].split(' ');
const gridS = lines.slice(1).map(line => line.split(''));
let y = Number(sy);
let x = Number(sx);
if (m === 'N') {
y--;
} else if (m === 'S') {
y++;
} else if (m === 'E') {
x++;
} else { // === 'W'
x--;
}
if (y >= 0 && y < Number(H) && x >= 0 && x < Number(W) && gridS[y][x] === '.') {
console.log('Yes');
} else {
console.log('No');
}
});
🔍 コードの流れ
- 標準入力を1行ずつ受け取り、
lines配列に格納する - 入力が終わったら
closeイベントが発火して処理開始 - 1行目をスペース区切りで分解し、以下の値を取得
-
H: 高さ -
W: 幅 -
sy: 初期 y 座標 -
sx: 初期 x 座標 -
m: 移動方向(N/S/E/W)
-
- 残りの行を 1文字ずつに分解して
gridSという2次元配列にする(マップ) - 現在位置 (
y,x) を数値に変換して設定 -
mの方向に応じてyまたはxを1マス移動 - 最後に 移動後の位置が
- 配列の範囲内であるか?
-
'.'(通れるマス)か?
をチェック
- 条件を満たせば
Yes、そうでなければNoを出力
🗒️ まとめ
- マップは
yが行、xが列 - 範囲外チェック →
0 ≤ y < H,0 ≤ x < W - 方向ごとに座標を変化
- 移動先が
'.'ならYes、'#'or 範囲外ならNo