今回は paizaの「「ビームの反射」を解くために:part1」の問題に挑戦!
「ビームの反射」では、箱の状態を受け取り、壁によって適切に場合分けする必要があるので、まずは、前段階の問題を解いていく!
問題概要
- 箱の中の状態を表す文字列が与えられる。
- それぞれの記号を 数値に変換して出力 するプログラムを作る。
🔸 入力
1行目:
H W
-
H… 箱の高さ(行数) -
W… 箱の幅(列数)
2行目以降:
-
H行分の文字列 - 各行の長さは
W - 含まれる文字は '
_', '/', '\' の3種類
(環境によって \ (バックスラッシュ)が円マークに見えることあり)
🔸 出力
入力された箱の状態を、次の規則で数値化して出力:
- '
_' →0 - '
/' →1 - '
\' →2
出力形式:
- 各行を スペース区切り にして出力。
- 出力行数は
H行。
入力例:
4 5
/_\/\
_/__\
/\/\_
_\\/_
出力例:
1 0 2 1 2
0 1 0 0 2
1 2 1 2 0
0 2 2 1 0
❌NG例:
const rl = require('readline').createInterface({ input: process.stdin});
const lines = [];
rl.on('line', (input) => lines.push(input));
rl.on('close', () => {
const [H, W] = lines[0].split(' ').map(Number);
const s = lines.slice(1).map(line => line.split(''));
for (let i = 0; i < H; i++) {
const row = [];
for (let j = 0; j < W; j++) {
const wall = s[i][j];
if (wall === '_') row.push('0');
if (wall === '/') row.push('1');
if (wall === '\') row.push('2'); // ❌
}
console.log(row.join(' '));
}
});
JavaScript では \ はエスケープ文字なので、
単体では文法エラーになる。
→ バックスラッシュ(\)を文字として扱うには、
'\\' のように 2つ重ねる 必要がある。
✅OK例:
// readlineモジュールで標準入力を行単位で取得
const rl = require('readline').createInterface({ input: process.stdin });
const lines = [];
// 1行ずつ配列に格納
rl.on('line', (input) => lines.push(input));
// 入力終了後に処理開始
rl.on('close', () => {
// 1行目:高さH・幅W
const [H, W] = lines[0].split(' ').map(Number);
// 2行目以降:各マスの情報を2次元配列に格納
const s = lines.slice(1).map(line => line.split(''));
// 各行を処理
for (let i = 0; i < H; i++) {
const row = [];
for (let j = 0; j < W; j++) {
const beam = s[i][j];
// 条件分岐して数値化
if (beam === '_') row.push('0');
if (beam === '/') row.push('1');
if (beam === '\\') row.push('2'); // ← 修正ポイント!
}
// 結果をスペース区切りで出力
console.log(row.join(' '));
}
});
💻 コードの流れ
- 入力準備
- readline モジュールで標準入力を1行ずつ読み取る設定をする。
- 読み取った行を
lines配列に順に格納。
- 入力完了後 (
closeイベント)- 最初の1行目を分解して、
-
H(高さ)とW(幅)を数値として取得。 - 2行目以降(
lines.slice(1))を1行ずつ分割して、各文字を2次元配列sに格納(箱の中身)。
- 変換処理
- 外側ループ:高さ(行)方向に
for (let i = 0; i < H; i++) - 内側ループ:幅(列)方向に
for (let j = 0; j < W; j++) - 各文字を取得 → 変換規則に従って数値化:
- '
_' →0 - '
/' →1 - '
\\' →2(← バックスラッシュは \ で書く必要あり!)
- '
- 外側ループ:高さ(行)方向に
- 出力
- 各行の変換結果を
row配列に追加。 -
row.join(' ')でスペース区切りにして出力。
- 各行の変換結果を
📝 まとめ
-
\は エスケープ文字 →'\\'と書く必要あり。 -
readlineで入力を行単位で扱い、最後にまとめて処理。 - 各文字を
if文で条件分岐して数値化。 - 出力形式は スペース区切り+改行あり、余分な空白・空行なし。