[paiza]みんなでしりとり (paizaランク B 相当)

# 条件がめんどくせぇんよ
指定された単語リストがあるのに、そのリストから選ばない（入力例2）とかサイコパス集団がしりとりしとるんか？
もう少しルールわかる奴らでしりとりあえよ。


https://paiza.jp/works/mondai/b_rank_skillcheck_archive/word_chain

# 面倒くさいので画面パタメータをListでもらった後のFunctionだけ
ちなみに引数のListを作ってる箇所は[こっちの記事](https://qiita.com/AsilHatake/items/842548e48ae4a0eae119)に書いてあるYO!!

```javascript:wordChain.js
// [問題文（原文）]
// あなたは友達たちと N 人でしりとりを行うことにしました。
// 1 人目、 2 人目、...、 N 人目、 1 人目、2 人目、... という順序で発言をします。
// 
// ここで、それぞれの人は、次に挙げる 4 つのしりとりのルールを守って発言をする必要があります。
// 
// 1. 発言は、単語リストにある K 個の単語のうちのいずれかの単語でなければならない。
// 2. 最初の人以外の発言の頭文字は、直前の人の発言の最後の文字と一緒でなければならない。
// 3. 今までに発言された単語を発言してはならない。
// 4. z で終わる単語を発言してはならない。
// 
// ここで、発言の途中で上のルールを破った場合、ルールを破った人はしりとりから外れます。
// そして、その人を抜いて引き続きしりとりを続けていきます。このとき、後続の人は、ルール 2 を守る必要はありません。
// 
// N 人がしりとりを行ったログが M 行分与えられます。
// このとき、M 回の発言が終わった後、しりとりから脱落せずに残っている人のリストを表示するプログラムを書いてください。
function wordChain(lines) {
  // 入力は以下のフォーマットで与えられます。
  // 
  // N K M
  // d_1
  // d_2
  // ...
  // d_K
  // s_1
  // s_2
  // ...
  // s_M
  // 
  // ・1 行目にしりとりをする人数を表す整数 N、単語リストに乗っている単語の数を表す整数 K、しりとりで行われた発言の数を表す整数 M がこの順にスペース区切りで与えられます。
  // ・続く K 行のうちの i 行目 (1 ≦ i ≦ K) には、単語リストに乗っている i 番目の単語を表す文字列 d_i が与えられます。
  // ・続く M 行のうちの j 行目 (1 ≦ j ≦ M) には、しりとりで行われた j 番目の発言を表す文字列 s_j が与えられます。
  // ・入力は合計で K + M + 1 行となり、入力値最終行の末尾に改行が 1 つ入ります。

  // 現在処理中のプレイヤー番号
  let palyerIndex = 0;

  // 入力チェック面倒くさいので正常系のみ対応するよ
  const [playerCnt, wordCnt, playCnt] = lines[0].split(" ").map(v => Number(v));
  // プレイヤー（生きてるプレーヤーを管理）
  let players = Array.from({ length: playerCnt }, (_, index) => index + 1);
  // 選択可能単語設定
  const words = lines.slice(1, wordCnt + 1).map(w => ({ word: w, isUsed: false }));
  let isStart = true;
  let preWord = '';
  lines.slice(wordCnt + 1).forEach(word => {
    const w = words.find(w => w.word === word);
    const isErr = w ? (w.isUsed || word.endsWith('z') || (!isStart && !word.startsWith(preWord.slice(-1)))) : true;
    // if (w) {
    //   if (w.isUsed) {
    //     // 3. 今までに発言された単語を発言してはならない。
    //     isErr = true;
    //   } else if (word.endsWith('z')) {
    //     // 4. z で終わる単語を発言してはならない。
    //     isErr = true;
    //   } else if (!isStart && !word.startsWith(preWord.slice(-1))) {
    //     // 2. 最初の人以外の発言の頭文字は、直前の人の発言の最後の文字と一緒でなければならない。
    //     isErr = true;
    //   }
    // } else {
    //   // 1. 発言は、単語リストにある K 個の単語のうちのいずれかの単語でなければならない。
    //   isErr = true;
    // }

    if (isErr) {
      preWord = "";
      isStart = true;
      players = players.filter((_, i) => i !== palyerIndex);
    } else {
      w.isUsed = true;
      preWord = word;
      isStart = false;
      palyerIndex = (palyerIndex + 1) >= players.length ? 0 : palyerIndex + 1;
    }
  });

  // 最終的にしりとりから脱落せずに残っている人の番号を以下の形式で出力してください。
  // N'
  // a_1
  // a_2
  // ...
  // a_N'
  // 
  // 期待する出力は N' + 1 行からなります。
  // 1 行目には、最終的にしりとりから脱落せずに残っている人の人数を表す整数 N' を出力してください。
  // 続く N' 行のうち、i 行目 (1 ≦ i ≦ N') には、最終的にしりとりから脱落せずに残っている人の番号のうち、小さい方から i 番目のものを出力してください。
  console.log(players.length);
  players.forEach(player => console.log(player));
}

module.exports = {
  wordChain
};
```

とりあえず、現在の単語にたいしてエラーが有るかどうか判定した後に、
発言者の処理をするという割と普通な解き方になってしまった。。。
`const isErr = ～`の部分をクソ真面目にifで書くとコメントアウトみたいな感じになる。
※if文で書く場合は`let isErr = false;`で宣言しないと、定数設定エラーになるZ!!