알고리즘

프로그래머스 LV.1 [1차] 다트 게임

Thor_yeom 2023. 4. 29. 20:41

 

이게 레벨 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"]
*/

 

이렇게 하면 numbersletters를 만들수 있습니다.

 

처음 나왔던 조건들중 가장 첫번째인 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, +)
}

 

어렵고도 뭔가 쉬워보이는 문제를 풀어봤는데요 도움이 되었으면 좋겠습니다 감사합니다.