다트 게임은 총 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 지식이 모자란 것이 큰 것 같다.