[アルゴリズム][初めて]ダーツゲーム-JS


問題のショートカット

問題の説明


ダーツゲーム
KakaoTalkの4番目の星!退屈な時?KakaoTalkゲームスター~
Game Star
KakaoTalkゲームスターは下半期にダーツゲームを新サービスとして発売する.ダーツゲームは、ボードに3回ダーツを投げ、点数の和で実力を競うゲームで、簡単に楽しめます.
入社したばかりの武智はコード力が認められ、ゲームの核心部分である採点ロジックを担当した.ダーツゲームの得点ロジックは以下の通りです.
  • ダーツゲームは3回のチャンスがあります.
  • の機会ごとに0点から10点を得ることができます.
  • 点は単(S)、双(D)、三(T)領域が同時に存在し、各領域で当選した場合、スコアから1平方、2平方、3平方(スコア1、スコア2、スコア3)を算出する.
  • オプションでは、スター賞()、阿差賞(#)、スター賞()の当選時に該当する点数と、それまでに獲得した点数がそれぞれ2倍になります.阿次賞(#)が当選した時、この点数は負数だった.
  • スター賞()も最初の機会に登場することができます.このような状況で、最初のスター賞()の点数は2倍になった.(例4参照)
  • スター賞()の効果は、他のスター賞()の効果と重なる可能性があります.そんな中、重なるスター賞(*)の点数は4倍.(例4参照)
  • スター賞(*)の効果は「アチャ賞」(#)の効果と重なる可能性があります.この場合、重なったアッチャ賞(#)の点数は-2倍です.(例5参照)
  • 単一(S)、二重(D)、三(T)の各スコアは1つ存在する.
  • スター賞(*)、雅察賞(#)は1点ごとに1つしか存在しないし、存在しないかもしれない.
  • 0~10の整数と、アルファベットS、D、T、*、および#からなる文字列を入力すると、合計スコアが返される関数を作成します.

    入力フォーマット


    「スコア|加算|オプション」からなる文字列3組.
    例)1 S 2 D*3 T
  • 分は0から10の整数です.
  • ボーナスはS、D、Tの1つです.
  • オプティカル(光学式)ドライブは*または#のいずれかで、ない場合があります.
  • 出力フォーマット


    3回の機会で得られたスコアの合計の整数値を出力します.
    例)37

    I/O例



    Solution


    しょかい
    function solution(result) {
        //다트 3번
        //0점~10점
        //S,D,T,*,#
        let answer =[];
        for(let i=0;i<result.length;i++){
            if(result[i]==='S'){
                result[i-2]=='1' ? answer.push(Number(10)) : answer.push(Number(result[i-1]));
                if(result[i+1]==='*'){
                    answer.length>1 ? answer.push(answer.pop()*2+answer.pop()*2) :
                    answer.push(answer.pop()*2);
                }else if(result[i+1]==='#'){
                    answer.push(answer.pop()*-1);
                }
            }else if(result[i]==='D'){
                result[i-2]=='1' ? answer.push(Number(Math.pow(10,2))) :answer.push(Number(Math.pow(result[i-1],2)));
                if(result[i+1]==='*'){
                    answer.length>1 ? answer.push(answer.pop()*2+answer.pop()*2) :
                    answer.push(answer.pop()*2);
                }else if(result[i+1]==='#'){
                    answer.push(answer.pop()*-1);
                }
            }else if(result[i]==='T'){
                result[i-2]=='1' ? answer.push(Number(Math.pow(10,3))) : answer.push(Number(Math.pow(result[i-1],3)));
                if(result[i+1]==='*'){
                    answer.length>1 ? answer.push(answer.pop()*2+answer.pop()*2) :
                    answer.push(answer.pop()*2);
                }else if(result[i+1]==='#'){
                    answer.push(answer.pop()*-1);
                }
            }
            
        }
        console.log(answer);
        return answer.reduce((a,b)=> a+b)
    }
    試験例は合格したが、試験18、22で合格しなかった精度は93.8であった.
    どうしてこんなことになったの?
    次に,より可読性のあるコードを記述した.

    適切なソリューション

  • 配列値が0から9の場合、分割点数が10の場合、配列値をtempに予め入れる.
  • 以降、状況に応じてコードが記述される.
  • function solution(result) {
        let answer =[];
        let temp;
        for(let i=0;i<result.length;i++){
            if(result[i]>='0' && result[i]<='9'){
                if(result[i]==='1' && result[i+1]==='0'){
                    temp=10;
                    //0부분을 건너뛰기 위해서 i++
                    i++;
                }
                else temp=result[i];
            }
            temp = Number(temp);//숫자로 변경
            
            //S,D,T
            if(result[i]==='S'){
                answer.push(temp);
            }
            else if(result[i]==='D'){
                answer.push(Math.pow(temp,2));
            }
            else if(result[i]==='T'){
                answer.push(Math.pow(temp,3));
            }
            //*,#
            if(result[i]==='*'){
                answer[answer.length-1] *=2;
                answer[answer.length-2] *=2;
            }
            else if(result[i]==='#'){
                answer[answer.length-1] *=-1;
            }
            
        }
        console.log(answer);
        return answer.reduce((a,b)=> a+b)
    }
    このほかにもスタックがあり、正規の方法で解く方法があります!