ドンドン人間離れしていく。。。
あなたはこれから友人と N 回じゃんけんをします。しかし、あなたは全てを見通す千里眼の持ち主なので、友人がこれから出す N 回のじゃんけんの手が全て分かってしまいました。
何年もたつのだから もう気が付かなきゃいけない
もう 心に刻まなきゃいけない……!
勝つことがすべてだと……
勝たなきゃゴミ…… 勝たなければ…… 勝たなければ……
勝たなければ………!
面倒くさいので画面パタメータをListでもらった後のFunctionだけ
ちなみに引数のListを作ってる箇所はこっちの記事に書いてあるYO!!
janken.js
// [問題文(原文)]
// あなたはこれから友人と N 回じゃんけんをします。しかし、あなたは全てを見通す千里眼の持ち主なので、友人がこれから出す N 回のじゃんけんの手が全て分かってしまいました。
//
// ただただ全勝してしまうのは面白くないので、あなたは、N 回のじゃんけんで出した指の本数の合計がちょうど M 本になるようにじゃんけんをすることにしました。
// このとき、あなたは最高で何回じゃんけんに勝つことができるでしょうか。
//
//
// ここで、上の文中に出てくる「出した指の本数」というのは、じゃんけんで出した手の何本の指が立っていたか、ということであり、グー、チョキ、パーそれぞれ
//
// ・グー のとき ... 0 本
// ・チョキのとき ... 2 本
// ・パー のとき ... 5 本
//
// の指を出していたということになります。
// 例えば、あなたが 4 回のじゃんけんで グー、パー、チョキ、グー と出したとすると、出した指の本数の合計は、
//
// 0 + 5 + 2 + 0 = 7
//
// で 7 本となります。
/// 定数
// 勝った時の指の本数
const FingerType = Object.entries({ 'G': 0, 'C': 2, 'P': 5 });
// こっちの勝ちパターン
const WinPattern = { 'G': 'C', 'C': 'P', 'P': 'G' };
function janken(lines) {
// 入力は以下のフォーマットで与えられます。
//
// N M
// s
//
// 1 行目にそれぞれじゃんけんを行う回数を表す整数 N、あなたが出す指の本数の合計を表す整数 M がこの順で半角スペース区切りで与えられます。
//
// 続いて 2 行目に長さ N の文字列 s が与えられます。s の i 番目 (1 ≦ i ≦ N) の文字は i 回目のじゃんけんで相手が出す手を表し、それぞれグーが "G"、チョキが "C"、パーが "P" で表されます。
//
// 入力は合計で 2 行となり、2 行目の末尾に改行が 1 つ入ります。
const [N, M] = lines[0].split(" ").map(Number);
const hands = lines[1].split("");
console.log(maxWinCoount(N, M, hands, 0, 0, 0));
}
// 最大勝利集計
function maxWinCoount(N, M, hands, round, fingers, wins) {
if (round === N)
return fingers === M ? wins : -1;
let maxWins = -1;
// 全パターンじゃんけん
for (const [move, requiredFingers] of FingerType) {
// 出した指の本数が超えてなかったら次の勝負へ、勝っていたらwinsに1足す
if (fingers + requiredFingers <= M)
maxWins = Math.max(maxWins, maxWinCoount(N, M, hands, round + 1, fingers + requiredFingers, wins + (WinPattern[move] === hands[round] ? 1 : 0)));
}
return maxWins;
}
module.exports = {
janken
};
指の本数をトラッキングしながら各じゃんけんの手の組み合わせをチェックしてる感じです。
Gで勝てば0、Cで勝てば2、Pで勝てば5 なので、
最大勝つためには G > C > P の順に勝てばいいという仕組みなのはわかってはいるけど、
最大勝つ のと 指定数で勝つ だと勝手が違うため、総当たり戦で割り出した感じになりまして、なかなか不本意な実装だったけど、とりあえず動くから良し!