今回は paiza の「陣地取りゲーム」の問題に挑戦!
問題概要
A くんと B くんが、一直線に並んだ N 個のマスを取り合うゲームを行う。
● マスの状態
ゲーム開始時、すべてのマスは「どちらの陣地でもない」状態。
● ルール
Q ターンの間、入力に書かれた順番で各プレイヤーが指定マス x を獲得しようとする。
- マスが「どちらの陣地でもない」場合 → そのプレイヤー(
P) の陣地になる。 - すでに 自分の陣地 → 何も起こらない(変化なし)。
- 相手の陣地は奪えない → 何も起こらない。
● 出力
最終的に
- A の陣地が多ければ
"A" - B の陣地が多ければ
"B" - 同数なら
"Draw"
入力例:
5 4 // N Q
A 4 // P_1 x_1
A 4
B 2
A 2
出力例:
Draw
✅OK例:
const rl = require('readline').createInterface({ input:process.stdin });
const lines = [];
rl.on('line', (input) => lines.push(input));
rl.on('close', () => {
const [N, Q] = lines[0].split(' ').map(Number);
const turn = lines.slice(1).map(line => line.split(' '));
const spaces = Array(N).fill(null);
for (let i = 0; i < Q; i++) {
const [p, x] = turn[i];
if (spaces[x-1] === null) {
spaces[x-1] = p;
}
}
const A = spaces.filter(x => x === 'A').length;
const B = spaces.filter(x => x === 'B').length;
console.log(A === B ? 'Draw' : A > B ? 'A' : 'B');
});
🧭 コードの流れ
-
readlineを使い、標準入力の全行をlinesに読み込む。 - 入力読み込み終了後 (
close)、1 行目からN(マス数)とQ(ターン数) を取り出す。 - 2 行目以降を
turnとしてまとめ、
各行を[p, x](プレイヤー名とマス番号)に分解して配列化。 -
spacesという長さNの配列を作り、すべてnull(無所属)で初期化。 -
Qターンについて順番に処理し、
指定マスx(配列ではx-1)がnullなら、そのマスをプレイヤーpの陣地にする。
すでに誰かの陣地なら何もしない(奪えないルール)。 - 全ターン終了後、
配列spacesの中で'A'の数、'B'の数をfilterで数える。 - A と B の陣地数を比較し、
- 同じ →
"Draw" - A の方が多い →
"A" - B の方が多い →
"B"
を出力する。
- 同じ →
🔍 ちょっと改良?
const rl = require('readline').createInterface({ input: process.stdin });
const lines = [];
rl.on('line', (input) => lines.push(input));
rl.on('close', () => {
const [N, Q] = lines[0].split(' ').map(Number);
// 全マスを null(無所属)で初期化
const spaces = Array(N).fill(null);
// ターン処理
for (let i = 1; i <= Q; i++) { // turn配列を省略
const [p, x] = lines[i].split(' ');
const idx = Number(x) - 1; // index
if (spaces[idx] === null) {
spaces[idx] = p;
}
}
// カウント
const A = spaces.filter(s => s === 'A').length;
const B = spaces.filter(s => s === 'B').length;
// 結果出力
console.log(A === B ? 'Draw' : A > B ? 'A' : 'B');
});
📝まとめ
- 配列で状態を保持:
spaces = Array(N).fill(null)のように、最初は誰の陣地でもない。 - マス番号は 1-indexed → 配列は 0-indexed
→spaces[x-1]を使うのが大事。 - 奪えないルール:
空(null)のときだけ代入、それ以外は無視。 - A と B の集計:
filterで数えるのがシンプル。 - 最終結果の判定は三項演算子で短く書ける:
A === B ? 'Draw' : A > B ? 'A' : 'B'