[テストコード][1ラウンド目]ダーツゲーム

9919 ワード

ダーツゲーム


問題の説明


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例



    私の答え


    ランキング:29217
    まず、dartResultで受信したパラメータは、文字列からなる文字の組合せである.
    文字列を制御するには、正規表現を理解する必要があります.
    正規表現を使用して、各値を必要な値に分割し、各値を必要な演算に変換します.
    ちなみに、正規表現に対する理解が足りないため、進行速度が少し遅い.
    また,新しい認識のmatch()APIは非常に使いやすい.matchは正規表現をパラメータとして受け入れ,その値を配列に返す.splitとは異なり、見つかった文字を配列に返します.
    // S = single, D = Double, T = Triple
    // *은 각 2배, 2개 나올 경우 중첩 결과가 중첩
    // #은 -1을 곱함
    // #과 *이 나온경우 #은 2배가 됨 
    
    function solution(dartResult) {
        //match APIs를 이용하여 3번의 게임 결과를 나누어 준다. 이때 match의 매개변수는 정규표현식을 받는다.
        let dr = dartResult.match(/\d{1,2}[SDT][*|#]?/g );
        //게임은 총 세번으로 3개의 배열이 최대이다. 
        //각 게임의 계산 결과를 담는 배열공간을 만든다.
        let result = [];
        //숫자, SDT, #*를 별도로 찾아서 각 값에 맞는 연산을 해주면 결과가 나온다.
        for (let i = 0; i < dr.length; i++) {
            //3개의 value가 나옴으로 3번 반복한다. 
            // num에는 숫자만 찾아서 담는다.
            let num = dr[i].match(/\d{1,2}/g)
            // sdt에는 SDT만 찾아서 담는다.
            let sdt = dr[i].match(/[SDT]/g)
            // sign에는 *, # 만 찾아서 담는다.
            let sign = dr[i].match(/[*|#]/g)
    
            //dr[0] 의 값끼리, dr[1]의 값끼리 계산해야 함으로 for문안에 if문을 만들었다.
            //타입 비교까지는 안해야 됨으로 ==으로 비교해야지 값을 찾을 수 있다. 타입은 문자열이기 때문에 타입비교를 하면 오류가 발생함.
            if(sdt == 'S'){
                //S일때는 해당 숫자에 1을 곱한다. 
                num = num * 1;
                //D일때는 해당 숫자를 제곱으로 곱한다. Math.pow를 사용해도 됨. 
            }else if(sdt == 'D'){
                num = Math.pow(num, 2)
                //T일때는 해당 숫자를 세제곱으로 곱한다.
            } else if(sdt == 'T'){
                num = Math.pow(num, 3)
            }
            //*이 나오면 해당 숫자에 2를 곱한다.
            if(sign == '*'){
                num  = num * 2;
                //첫번째 배열이 아닌 배열에서 sign *이 있다면 이전 배열에 2를 추가로 곱한다.
                if(i != 0){
                    result[i-1] = result[i-1] * 2; 
                }
                //#이 나오면 해당 숫자에 -1을 곱하여 부호를 바꿔준다.
            }else if(sign == '#'){
                num = num * (-1)
            }
            //각각의 수들을 사전에 만든 배열공간에 담는다. 
            result.push(num)
        }
        //담긴 배열들을 전부 더하여 value로 리턴한다. 
        return result.reduce((a,b) => a+b)
    }
    
    

    正规表现的短片