이게 레벨 1인가 싶기는 한데... 너무 어려운 문제였다
이 문제를 풀때 가장 중요한것은 이 조건문을 잘 이해하고 정리하는것이었다.
조건을 보면

1. 총 3번의 기회로 구성된다. --> 점수가 [ 0 , 0 , 0 ] 이런식으로 3번의 기회로 주어진다고 해석하면된다.
3. 점수와 함께 ~ 계산된다 --> String("S"), String("D"), String("T")에 따라 제곱하는 수가 달라진다.
4. 옵션으로 ~ 마이너스된다. --> 스타상(*)이면 해당 점수와 그 앞의 점수를 2배로 만든다. 아차상(#)이면 마이너스
5. 스타상 ~ 2배가 된다 --> 첫번째로 스타상(*)이 나오면 첫번째 스타상(*)의 점수만 2배가 된다.
6. 스타상 ~ 4배가된다 --> 스타상(*)이 두개 있으면 4배가 된다.
7. 스타상 ~ -2배가 된다 --> 스타상(*)과 아차상(#)이 있으면 아차상(#)의 점수는 -2배가 된다.
이렇게 가장 중요한 조건들만 뽑아봤는데... 어떻게 적용이 되는지 확인해보자

푸는 방법에 대해선 여러가지 방법이 있겠지만
저는 .split(whereSeparator:)를 이용했습니다.
저도 처음 사용하는 것이라 공식문서를 찾아봤는데... 역시 공식문서 짱...

해석을 해보면 "지정된 조건자를 만족하는 요소를 포함하지 않는 컬렉션의 가능한 가장 긴 하위 시퀀스를 순서대로 반환합니다."
음... 그러니까 조건에 해당하는 것은 포함하지 않고 리턴한다.
공식문서 보면 예제가 있었습니다. 한번 같이 보시죠

조건에 $0 == " " 공백을 가지는 것이 있냐 --> 조건에 해당하지 않는것만 리턴
음... 이런식이군요 좋습니다. 그렇다면 적용을 해보겠습니다.
func solution(_dartResult: String) -> Int {
// 숫자만 걸러내기
var numbers = dartResult.split(whereSeparator: { $0.isLetter || $0 == "*" || $0 == "#" })
// 문자만 걸러내기
var letters = dartResult.split(whereSeparator: { $0.isNumber })
print(numbers)
print(letters)
return 0
}
/*
["1", "2", "3"]
["S", "D*", "T"]
*/
이렇게 하면 numbers와 letters를 만들수 있습니다.
처음 나왔던 조건들중 가장 첫번째인 1번 사항을 보면 총 3번의 기회로 구성된다... 즉, 값이 3개다

값이 Int이기 때문에 numbers를 Int로 형 변환 해줍니다.
형 변환 하는 방법은 여러가지가 있지만 map을 사용했습니다.
// 문자열을 Int로 형 변환할때는 옵셔널 바인딩이 필요합니다.
var answer = numbers.map { Int($0)! }
/*
[1, 2, 3]
*/
자 이렇게 나왔으면 이제 나머지 조건들로 식을 만들어 보겠습니다.
func solution(_dartResult: String) -> Int {
// 숫자만 걸러내기
var numbers = dartResult.split(whereSeparator: { $0.isLetter || $0 == "*" || $0 == "#" })
// 문자만 걸러내기
var letters = dartResult.split(whereSeparator: { $0.isNumber })
print(numbers)
print(letters)
// 문자열을 Int로 형 변환할때는 옵셔널 바인딩이 필요합니다.
var answer = numbers.map { Int($0)! }
// letters를 반복문을 통해 하나씩 빼온다.
// 여기서 enumerated()를 사용하는 이유는 index를 받기 위해서입니다.
for (index, element) in letters.enumerated() {
// 여기서 반복문을 한번 더 사용합니다. 이유는? -> letters를 보면 "D*" 이렇게 붙어 있는 녀석을 하나씩
// 분리하기 위해서 입니다.
// ex) "S" , "D*", "T"
for j in element {
// switch 문으로 문자마다 식을 분리해줍니다.
switch j {
case "D":
// element에 해당하는 index
answer[index] = answer[index] * answer[index]
case "T":
answer[index] = answer[index] * answer[index] * answer[index]
case "*":
// "*" 나온게 0번째가 아니라면 조건 4를 실행
if index != 0 {
answer[index] *= 2
// 바로 전에 얻은 점수를 2배 한다.
answer[index-1] *= 2
// "*" 나온게 0번째라면 조건 5를 실행
} else {
answer[index] *= 2
}
case "#":
answer[index] *= -1
default:
break
}
}
}
return answer.reduce(0, +)
}
어렵고도 뭔가 쉬워보이는 문제를 풀어봤는데요 도움이 되었으면 좋겠습니다 감사합니다.
'알고리즘' 카테고리의 다른 글
프로그래머스 LV.1 숫자 짝꿍 스위프트 (0) | 2023.05.05 |
---|---|
번외) for문 발전 에라토스테네스의 체에 대해 공부하다. (0) | 2023.05.04 |
프로그래머스 LV.1 기사단원의 무기 (0) | 2023.05.03 |
프로그래머스 LV.1 덧칠하기 스위프트 (0) | 2023.05.02 |
프로그래머스 LV.1 카드 뭉치 (0) | 2023.04.30 |