문제
문제 설명
다트 게임
카카오톡에 뜬 네 번째 별! 심심할 땐? 카카오톡 게임별~
카카오톡 게임별의 하반기 신규 서비스로 다트 게임을 출시하기로 했다. 다트 게임은 다트판에 다트를 세 차례 던져 그 점수의 합계로 실력을 겨루는 게임으로, 모두가 간단히 즐길 수 있다.
갓 입사한 무지는 코딩 실력을 인정받아 게임의 핵심 부분인 점수 계산 로직을 맡게 되었다. 다트 게임의 점수 계산 로직은 아래와 같다.
- 다트 게임은 총 3번의 기회로 구성된다.
- 각 기회마다 얻을 수 있는 점수는 0점에서 10점까지이다.
- 점수와 함께 Single(S), Double(D), Triple(T) 영역이 존재하고 각 영역 당첨 시 점수에서 1제곱, 2제곱, 3제곱 (점수1 , 점수2 , 점수3 )으로 계산된다.
- 옵션으로 스타상(*) , 아차상(#)이 존재하며 스타상(*) 당첨 시 해당 점수와 바로 전에 얻은 점수를 각 2배로 만든다. 아차상(#) 당첨 시 해당 점수는 마이너스된다.
- 스타상(*)은 첫 번째 기회에서도 나올 수 있다. 이 경우 첫 번째 스타상(*)의 점수만 2배가 된다. (예제 4번 참고)
- 스타상(*)의 효과는 다른 스타상(*)의 효과와 중첩될 수 있다. 이 경우 중첩된 스타상(*) 점수는 4배가 된다. (예제 4번 참고)
- 스타상(*)의 효과는 아차상(#)의 효과와 중첩될 수 있다. 이 경우 중첩된 아차상(#)의 점수는 -2배가 된다. (예제 5번 참고)
- Single(S), Double(D), Triple(T)은 점수마다 하나씩 존재한다.
- 스타상(*), 아차상(#)은 점수마다 둘 중 하나만 존재할 수 있으며, 존재하지 않을 수도 있다.
0~10의 정수와 문자 S, D, T, *, #로 구성된 문자열이 입력될 시 총점수를 반환하는 함수를 작성하라.
입력 & 출력
입출력 예제
예제 dartResultanswer설명
1 | 1S2D*3T | 37 | 11 * 2 + 22 * 2 + 33 |
2 | 1D2S#10S | 9 | 12 + 21 * (-1) + 101 |
3 | 1D2S0T | 3 | 12 + 21 + 03 |
4 | 1S*2T*3S | 23 | 11 * 2 * 2 + 23 * 2 + 31 |
5 | 1D#2S*3S | 5 | 12 * (-1) * 2 + 21 * 2 + 31 |
6 | 1T2D3D# | -4 | 13 + 22 + 32 * (-1) |
7 | 1D2S3T* | 59 | 12 + 21 * 2 + 33 * 2 |
새로 사용한 함수
eval() 함수 : 해당 함수 안에 있는 문자열의 계산을 하여서 그 결괏값을 반환하는 함수입니다.
풀이 과정
1. 최대한 문제와 비슷한 형태로 구성합니다. 점수 | 보너스 | 옵션에 맞는 배열을 선언하여주고 보너스와 배열에 속하지 않은 경우에는 점수일 것이라고 생각하고 계산을 수행합니다.
2. 처음에는 숫자의 범위를 0~9까지만이라고 생각하고 문제를 풀고 있다가 10까지의 범위이기 때문에 테스트 케이스에서 문제점이 생겼습니다. 이것을 해결하기 위하여 enumerate 함수를 이용하여서 현재 숫자의 index번호를 추적하고 다음 숫자와 현재 숫자의 구조를 파악합니다 만약 현재 숫자가 1이고 다음 숫자가 0일 경우에는 두 개의 result에는 다음 숫자까지 생각해서 +10을 넣어주도록 합니다.
3. 2번의 로직을 수행하게 된다면 0이 나올 때 중복적인 일을 수행하게 될 것입니다. 이 효과는 자릿수를 바꾸는 상태를 발생시키게 되므로 만약 자신의 숫자가 0일 때 이전 숫자가 1이라면 이것은 아무것도 추가하지 않는다는 로직이 추가돼야 할 것입니다.
4. 2,3번의 경우를 생각하면서 나머지를 살펴보면 각각의 보너스는 알맞은 수식으로 변경합니다 "S"의 경우에는 **1 "D"는 **2 "T"는 **3으로 변경합니다.
5. "#"은 일괄적으로 *(-1)으로 변경하면 간단합니다.
6. "*"의 경우에는 자신이 첫 번째 경우의 수에서 나왔는지만 중요합니다. 첫번째 로직에서 나온 경우와 2번째 3번째 로직에서 나온 경우만을 다르게 하기 위해서 i가 몇번째인지만 판별합니다. 만약 2번째에서 *이 나온다면 첫번째 경우에서 나온 경우이므로 *2로 해당 값을 치환하면 되지만 아닌 경우에는 그전에 + 나온 값을 "*2+"로 변환해주는 로직을 추가합니다. 배열로 변경하여 만들어주고 join을 이용하여 다시 문자열로 치환하여주고 마지막에는 "*2"를 붙여줍니다.
7. 6번까지의 경우를 빠짐없이 구성하게 된다면 계산할 수 있는 문자열 수식이 완성됩니다. 이것을 eval() 함수를 이용하여 계산하여 리턴하도록 합니다.
** 문제 해결하면서 코드 실행으로 실행하였을 때는 문제없이 통과가 되었지만 제출하였을 때 4,6,7에서 문제가 생기는 것을 발견하여서 한번 수정을 마친 코드입니다.
만약 혼자서 풀이를 해보다가 문제가 같은 번호에서 문제가 발생하게 된다면
테스트 케이스에
"10 D4 S10 D" 결괏값 : 204
를 넣고 문제를 해결해 보면 되겠습니다.
코드
def solution(dartResult):
bonus = ["S", "D", "T"]
option = ["*", "#"]
result = ""
for i, dart in enumerate(dartResult):
if dart in bonus:
if dart == "S":
result += "**1"
elif dart == "D":
result += "**2"
elif dart == "T":
result += "**3"
elif dart in option:
if dart == "*":
if i == 2:
result += "*2"
else:
tmp = list(result)
tmp[-5] = "*2+"
result = "".join(tmp)
result += "*2"
elif dart == "#":
result += "*(-1)"
else:
if dartResult[i] == "1" and dartResult[i + 1] == "0":
if len(result) == 0:
result += "10"
else:
result += "+10"
elif len(result) == 0:
result += f"{dart}"
elif dart == "0":
if dartResult[i - 1] == "1" and dartResult[i] == "0":
result += ""
else:
result += "+0"
else:
result += f"+{dart}"
print(result)
answer = eval(result)
return answer
solution("10D4S10D")
'Algorithm' 카테고리의 다른 글
[프로그래머스] 문자열 내림차순으로 배치하기 (0) | 2022.08.17 |
---|---|
[프로그래머스] 문자열 내 p와 y의 개수 (0) | 2022.08.17 |
[프로그래머스] 실패율 (0) | 2022.08.17 |
[프로그래머스] 문자열 내 마음대로 정렬하기 (0) | 2022.08.16 |
[프로그래머스] 자릿수 더하기 (0) | 2022.08.15 |