[프로그래머스(LV1)] 다트 게임

희희희·2022년 1월 12일

문제 설명

다트 게임은 총 3번의 기회로 구성된다.

각 기회마다 얻을 수 있는 점수는 0점에서 10점까지이다.

점수와 함께 Single(S), Double(D), Triple(T) 영역이 존재하고 각 영역 당첨 시 점수에서 1제곱, 2제곱, 3제곱으로 계산된다.

옵션으로 스타상() , 아차상(#)이 존재하며 스타상() 당첨 시 해당 점수와 바로 전에 얻은 점수를 각 2배로 만든다. 아차상(#) 당첨 시 해당 점수는 마이너스된다.

스타상()은 첫 번째 기회에서도 나올 수 있다. 이 경우 첫 번째 스타상()의 점수만 2배가 된다.

스타상()의 효과는 다른 스타상()의 효과와 중첩될 수 있다. 이 경우 중첩된 스타상(*) 점수는 4배가 된다.

스타상(*)의 효과는 아차상(#)의 효과와 중첩될 수 있다. 이 경우 중첩된 아차상(#)의 점수는 -2배가 된다. (예제 5번 참고)

Single(S), Double(D), Triple(T)은 점수마다 하나씩 존재한다.

스타상(*), 아차상(#)은 점수마다 둘 중 하나만 존재할 수 있으며, 존재하지 않을 수도 있다.

0~10의 정수와 문자 S, D, T, *, #로 구성된 문자열이 입력될 시 총점수를 반환하는 함수를 작성하라.


내가 작성한 코드

func solution(_ dartResult: String) -> Int {

    var result: String = dartResult
    var results: [String] = []
    var arr1: String = ""
    var arr2: String = ""
    var arr3: String = ""
    var num: Int = 0
    var score: [Int] = []

    for i in result {
        
        arr1.append(i)
        if (arr1.last)!.isNumber && arr1.filter({$0.isNumber}).count >= 2 {
            if arr1.count > 2 {
                arr1.removeLast()
                break
            }
        }
        result.remove(at: result.startIndex)
    }
    
    for i in result {

        arr2.append(i)
        if (arr2.last)!.isNumber && arr2.filter({$0.isNumber}).count >= 2 {
            if arr2.count > 2 {
                arr2.removeLast()
                break
            }
        }
        result.remove(at: result.startIndex)
    }
    
    for i in result {
        
        arr3.append(i)
        if (arr3.last)!.isNumber && arr1.filter({$0.isNumber}).count >= 2 {
            if arr3.count > 2 {
                arr3.removeLast()
                break
            }
        }
    }
    results.append(arr1)
    results.append(arr2)
    results.append(arr3)
    
    for i in 0...2 {

        if results[i].filter({$0.isNumber}).count == 2 {
            score.append(10)
        } else {
            score.append(Int(results[i].filter({$0.isNumber}))!)
        }
        
        switch results[i].filter({$0.isLetter}) {
        case "S":
            score[i] += 0
        case "D":
            score[i] *= score[i]
        case "T":
            score[i] = score[i] * score[i] * score[i]
        default:
            break
        }
        if results[i].last == "*" {
            score[i] *= 2
            if i > 0 {
                score[i-1] *= 2
            }
        } else if results[i].last == "#"{
            score[i] *= -1
        }
    }
    for i in 0...2 {
        num += score[i]
    }
    return num
}

지금까지 몇 문제 풀 진 않았지만 이번 문제가 가장 어려웠다. 머리속으로는 이렇게 하면 되겠다고 생각이 들지만 쉽지 않았다. 또한 코드에서 볼 수 있듯이 복잡하고 지저분하게 느껴지는 코드이다ㅠ

먼저 세 번의 점수를 각각 토큰화 시키기 위해 세 번의 for문을 사용하였다. 이 코드가 쓸 데 없이 길어 보이므로 더 간단하게 하는 법을 찾아봐야겠다. 일단 dartResult를 수정 가능하도록 새로운 배열에 불러와서 하나의 for문이 끝날때마다 넣어준 요소들을 지워주었다. 아직까지 for문을 각각 돌리는 방법말고는 분리할 수 있는 코드가 생각이 나지 않아 이렇게 작성하였다. 두 자리 숫자는 10밖에 없으므로 10을 제외하면 하나의 점수에는 숫자가 하나만 존재해야한다. 이를 이용하여 마지막 들어온 요소가 숫자이고 그 배열에 숫자가 두 개일때, 만약 10이라면 전체 count가 1, 0으로 2여야 하므로 이를 이용해 확인해주었다.

다음으로 score라는 배열에 각각의 점수를 계산하여 세 개의 요소를 더해준 뒤 리턴해주었다. 이때 숫자인 요소의 개수가 2라면 무조건 10이고 아닌 경우엔 하나의 숫자의 요소만 있으므로 이를 score에 넣어주었다.


아직 실력이 많이 모자란 것 같다. Swift 지식이 모자란 것이 큰 것 같다.

profile
iOS 어플 개발 연습

0개의 댓글