0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

今回は paiza の「格闘ゲーム」の問題に挑戦!

スライドウィンドウのアルゴリズムを自然と使えるようになった!


📘問題概要

格闘ゲームで、特定のコマンド入力(5文字のボタン入力)に応じて技を出したい。

◯ 技:コマンド

  • rolling:"LLLRB"
  • upper:"DDRRA"
  • rush:"AAAAA"

◯ 入力

  • 1行目:長いボタン入力の文字列 S

◯ やること

  • S を左から順に見て、5文字のコマンドが一致したらその技を発動(出力)する。
  • 一致した5文字は“消費される”ので、次の検索はその5文字後から始まる。
  • コマンドが一致しない場合は、1文字右にずらして再チェック。
  • 最後まで見て、発動した技を順に出力。

※ 注意点

  • 一つのボタン入力は一つのコマンドだけに使える。
    • 例:DDRRAAAAA
      • DDRRA」→ upper を発動
      • 残り「AAAA
      • AAAAA」が無いので rush は出ない



入力例:

DDRRAAAAALLLRB

出力例:

upper
rolling






✅ OK例:

const rl = require('readline').createInterface({ input :process.stdin });

const lines = [];

rl.on('line', (input) => lines.push(input));

rl.on('close', () => {
    const s = lines[0];
    
    let start = 0;
    let end = 5;
    
    while (end <= s.length) {
        const command = s.slice(start, end);
        
        if (command === "LLLRB") {
            console.log("rolling");
            start = end;
            end = end + 5;
        } else if (command === "DDRRA") {
            console.log("upper");
            start = end;
            end = end + 5;
        } else if (command === "AAAAA") {
            console.log("rush")
            start = end;
            end = end + 5;
        } else {
            start++;
            end++;
        }
    }
});

🔍 コードの流れ

  1. 標準入力から文字列 S を受け取る準備をする。

  2. 入力が完了したら(close)、
    1行目の文字列(S)を s に代入。

  3. start = 0end = 5
    最初の 5 文字のウィンドウ(区間)を作る。

  4. while文で
    end が文字列の長さ以内の間、ずっとループ。

  5. s.slice(start, end)
    現在の 5 文字を command として取り出す。

  6. その 5 文字が
    "LLLRB" → rolling
    "DDRRA" → upper
    "AAAAA" → rush
    のどれかと一致するか判定。

  7. 一致した場合:

    • 対応する技名を出力
    • 使った5文字は消費される扱い →
      • start = end
      • end = end + 5
        (次の5文字区間に一気にジャンプ)
  8. 一致しなかった場合:

    • コマンドではないので
      • start++
      • end++
        → 1文字ずつ右にスライドして再チェック
  9. end が文字列長を超えたらループ終了。

  10. 終了。






✨ 改善版

const rl = require('readline').createInterface({ input: process.stdin });
const lines = [];

rl.on('line', (input) => lines.push(input));

rl.on('close', () => {
    const s = lines[0];
    const moves = {
        "LLLRB": "rolling",
        "DDRRA": "upper",
        "AAAAA": "rush"
    };

    let start = 0;
    let end = 5;

    while (end <= s.length) {
        const command = s.slice(start, end);

        if (moves[command]) {
            console.log(moves[command]);
            start = end;
            end = start + 5;
        } else {
            start++;
            end++;
        }
    }
});

💡 ポイント

① 条件分岐(if 〜 else if)が1つに集約された

  • "LLLRB", "DDRRA", "AAAAA" の判定を
    オブジェクト moves にまとめた。
  • 結果的に if (moves[command]) だけで判定が完結。
  • コードが 短くなる・読みやすい・追加が簡単 になった。

② コマンド→技名の対応をデータとして管理

  • コマンド文字列と技名の対応を
const moves = { "LLLRB": "rolling", ... }

という辞書(オブジェクト)にまとめた

  • 新しい技を追加するときは
moves["XXXXX"] = "newMove",

だけでOK

③ 出力の簡潔化

console.log(moves[command]);

でそのまま技名を出力できるため、以前のような長い if 文が不要。


④ 「使った文字を5文字飛ばす」処理が明確に

  • コマンド一致時:
start = end;
end = start + 5;

と書いており、「5文字消費して次へ」 が、以前より読みやすく、ミスしにくい形に改善。






🗒️ まとめ

🔍 スライドウィンドウ(5文字区間)でチェック

  • start から end = start + 5 までの5文字を切り取って判定。
    • コマンド一致 → 5文字まとめて消費(start=end
    • 不一致 → 1文字スライド(start++

🔍 オブジェクトを「辞書」として使うと判定が超スッキリ

const moves = {
    "LLLRB": "rolling",
    "DDRRA": "upper",
    "AAAAA": "rush"
};
  • キー:コマンド
  • 値:技名
    moves[command] の有無で判定ができる。

🔍 if 文が大量に並ぶのを防げる

  • 改善版では if (moves[command]) の1行で判定が完了。
  • 可読性アップ・追加が簡単・ミスが減る。

🔍 コマンド一致時に5文字飛ばす仕組みが、とても大切

  • コマンドは オーバーラッピング してはいけないため、
    start = end を行って次へ進む。

🔍 文字列の部分取り出しは .slice(start, end)

  • JS 標準で扱いやすい
  • end は「含まれない」ことに注意(半開区間)
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?