📝 문제 요약
> 다트 게임의 점수 계산 로직을 구현하라.
🎯 다트 게임 룰 요약 (이해하기 쉽게 핵심만 정리)
- 입력값 : "점수|보너스|[옵션]"으로 이루어진 문자열 3세트. 예) 1S2D*3T
- 다트는 총 3번 던진다.
- 점수는 0점에서 10점까지이다.
- 보너스 부분은 S는 1제곱, D는 2제곱, T는 3제곱으로 계산된다. (해당 점수에서 바로 제곱함)
- 옵션 부분 중 *은 해당 점수 2배, 바로 전 점수 2배로 계산된다. (맨 처음에 나오면 해당 점수만 2배)
- 옵션 중 #은 해당 점수가 마이너스로 계산된다. (*과 중첩되면 -2배로 됨)
- 보너스 부분은 필수고, 옵션은 나올 수도 안 나올 수도 있다.
https://programmers.co.kr/learn/courses/30/lessons/17682
코딩테스트 연습 - [1차] 다트 게임
programmers.co.kr
🎨 풀이
💡 첫번째 시도 = 성공
import re
dic = {'S':1,'D':2,'T':3}
dic2 = {'*':2,'#':-1}
def solution(dartResult):
answer = [] # 합계 낼거임.
num = 0
index = -1
numbers = re.findall("\d+", dartResult) # 숫자 따로 추출
dartResult = re.sub(r"[^SDT*#]","",dartResult) # 숫자 제거
for char in dartResult:
if char in dic :
answer.append(num)
index += 1
num = int(numbers[index])
num = num ** dic[char]
continue
if char in dic2 :
if char == '*':
if len(answer) != 1:
answer[-1] *= 2
num *= 2
else:
num *= -1
answer.remove(answer[0])
answer.append(num)
return sum(answer)
> 코드가 좀 복잡해보이지만, 그래도 성공한 코드는 맞다. 거의 문제 그대로 써뒀기 때문에 이해하면 조금 쉬울 거다.
1. 딕셔너리 구성
- 먼저, 보너스인 문자들(S,D,T)이나 옵션인 문자들(*,#)이나 다 한 숫자에 매치되는 건 같다고 생각해서, 각 요구사항의 키워드 숫자와 엮어서 딕셔너리를 구성해보았다. D와 *이 2로 겹치기 때문에 딕셔너리를 나눠둔 것이고, 딕셔너리를 이용하면 if char == 'S', if char == 'D' 이런 식으로 나열하는게 줄어들기 때문에 딕셔너리를 이용한 것이다.
2. 숫자와 문자를 나눠 담았다.
- 숫자는 re.findall을 이용해 숫자를 찾아서 numbers에 담았다. ex) numbers = [1,2,3] 이런식으로 담겨있다.
- 숫자를 나눠 담아뒀기 때문에, dartResult에서 숫자를 제거했다. ex) dartResult = "SD*D"
3. num과 index를 변수로 추가해주었다.
- 내 코드는 이 전에 계산했던 num을 append 해주고 시작하는 거라서 num을 미리 설정한 후 넣어줬다.
- index가 -1인 이유도 비슷하다. index도 +1을 해주는 부분이 있어서 초기값을 그렇게 설정한 것이다.
index는 numbers를 가리키기 위해 사용한다.
4. dartResult를 하나씩 for문을 돌린다.
5. 만약 보너스 부분이라면,
5-1. num 계산해둔것 (혹은 초기값) 을 answer에 append 한다.
5-2. index를 높여준다.
5-3. numbers[index]를 num에 넣어준다. (앞으로 나올 보너스 + [옵션]에 맞게 계산한 후 다시 5-1로 돌아왔을 때 넣음)
5-4. num ** dic[char] 한 값을 num에 넣어준다. ( num ** dic['D'] == num ** 2 )
5-5. continue
6. 만약 옵션 부분이라면,
6-1. 그 중에서도 * 이라면, 그리고 len(answer)이 미리 넣어둔 초기값만 있는 게 아니라면 제일 최근 값을 2배 곱해준다.
6-1-2. 현재 num 값도 2배 곱해준다.
6-3. *이 아니라면, num에 -1을 곱해준다. (#인 경우)
7. 마무리 단계
7-1. 맨 처음에 num 초기값을 넣어주었던 걸 remove 한다.
7-2. 맨 마지막에 계산해줬던 num은 아직 들어가지 않은 상태다. 그 num을 append 해준다.
(for문 돌 때마다 그 전꺼를 넣어주고 초기화하는 식으로 사용했기 때문)
7-3. answer에 있는 모든 값들을 sum을 통해 합해서 return한다.

끝~
⭐ 느낀점
> 솔직히 문제 설명하기가 좀 벅찰 것 같아서 포기하고 다른 거 할까 생각도 조금씩 했었는데, 끝까지 리뷰하게 되어서 좀 많이 뿌듯하다. 이정도면 그래도 10명중에 6명은 이해할 수 있지 않을까 싶다. 그리고, 이 문제를 좀 꼼수를 써서 푼 느낌이 있는데 어떻게 해야 꼼수를 쓰지 않고 깔끔하게 풀 수 있는지 고민을 좀 해봐야겠다. (꼼수쓴 곳 2개 수정했다 ㅎ.ㅎ)
'🎲 알고리즘 공부 > 프로그래머스' 카테고리의 다른 글
[프로그래머스 / Level 1] 나누어 떨어지는 숫자 배열 (파이썬) (0) | 2022.04.18 |
---|---|
[프로그래머스 / Level 1] 같은 숫자는 싫어 (파이썬) (0) | 2022.04.17 |
[프로그래머스 / Level 1] 가운데 글자 가져오기 (파이썬) (0) | 2022.04.15 |
[프로그래머스 / Level 1] [1차] 비밀지도 (파이썬) (0) | 2022.04.15 |
[프로그래머스 / Level 1] 부족한 금액 계산하기 (파이썬) (0) | 2022.04.13 |