프로그래머스 공부/Python

[Level 1 / Python] 다트 게임(2018 KAKAO BLIND RECRUITMENT)

#자유의날개 2020. 11. 13. 14:30
반응형

문제 설명

카카오톡 게임별의 하반기 신규 서비스로 다트 게임을 출시하기로 했다. 다트 게임은 다트판에 다트를 세 차례 던져 그 점수의 합계로 실력을 겨루는 게임으로, 모두가 간단히 즐길 수 있다.
갓 입사한 무지는 코딩 실력을 인정받아 게임의 핵심 부분인 점수 계산 로직을 맡게 되었다. 다트 게임의 점수 계산 로직은 아래와 같다.

  1. 다트 게임은 총 3번의 기회로 구성된다.

  2. 각 기회마다 얻을 수 있는 점수는 0점에서 10점까지이다.

  3. 점수와 함께 Single(S), Double(D), Triple(T) 영역이 존재하고 각 영역 당첨 시 점수에서 1제곱, 2제곱, 3제곱 (점수1 , 점수2 , 점수3 )으로 계산된다.

  4. 옵션으로 스타상(*) , 아차상(#)이 존재하며 스타상(*) 당첨 시 해당 점수와 바로 전에 얻은 점수를 각 2배로 만든다. 아차상(#) 당첨 시 해당 점수는 마이너스된다.

  5. 스타상(*)은 첫 번째 기회에서도 나올 수 있다. 이 경우 첫 번째 스타상(*)의 점수만 2배가 된다. (예제 4번 참고)

  6. 스타상(*)의 효과는 다른 스타상(*)의 효과와 중첩될 수 있다. 이 경우 중첩된 스타상(*) 점수는 4배가 된다. (예제 4번 참고)

  7. 스타상(*)의 효과는 아차상(#)의 효과와 중첩될 수 있다. 이 경우 중첩된 아차상(#)의 점수는 -2배가 된다. (예제 5번 참고)

  8. Single(S), Double(D), Triple(T)은 점수마다 하나씩 존재한다.

  9. 스타상(*), 아차상(#)은 점수마다 둘 중 하나만 존재할 수 있으며, 존재하지 않을 수도 있다.

0~10의 정수와 문자 S, D, T, *, #로 구성된 문자열이 입력될 시 총점수를 반환하는 함수를 작성하라.

출처 : programmers.co.kr/learn/courses/30/lessons/17682

풀이 방법

예를 들어 "1S2D*3T" 라는 dartResult 값이 가지고 식을 만든다고 가정했을 때, 연산을 하면서 바로 답이 나오게 만들기에는 "*"과 "#"에 대한 처리가 어려울 것 같아서 "S, D, T"를 기준으로 나누어 ["1S", "2D", "3T"]처럼 리스트를 만들어 나중에 연산하도록 했다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
dartResult = "1S2T*3S"
 
bonus = {"S":"1""D":"2""T":"3"}
answer = []
for i in dartResult:
    if i.isalpha():
        temp = dartResult[:dartResult.index(i)+1
        dartResult = dartResult[dartResult.index(i)+1:]
        answer.append(temp.replace(i, "**" + bonus[i]))
print(answer)
 
"""
['1**1', '2**3', '*3**1']
"""
cs

위의 12번째 줄을 보면 "S, D, T"를 기준으로 나눠진 리스트를 확인할 수 있다. 아직 "*"에 대한 처리를 안했기 때문에 3번째 원소값은 "*"가 앞에 붙게 된다. "*"는 해당 점수와 바로 전에 얻은 점수를 2배로 만들게 되므로 answer[-1]과 answer[-2]에 대해서 문자열 "*2"가 붙도록 했다. answer[-2]의 경우는 리스트에 원소가 한 개만 추가된 경우가 있을 수 있으므로 len(answer) 값을 확인해서 2개 이상일 경우에만 문자열을 붙이도록 했다. "#"은 해당 점수를 마이너스로 바꾸므로 answer[-1]에 문자열 "*(-1)"이 붙도록 했다. 아래 코드를 보면 순차적으로 answer 리스트 원소 값들이 변경되는 것을 확인할 수 있다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
dartResult = "1D#2S*3S"
 
bonus = {"S":"1""D":"2""T":"3"}
answer = []
for i in dartResult:
    if i.isalpha():
        temp = dartResult[:dartResult.index(i)+1
        dartResult = dartResult[dartResult.index(i)+1:]
        answer.append(temp.replace(i, "**" + bonus[i]))
        print(answer)
    elif i == "*":
        dartResult = dartResult[dartResult.index(i)+1:]
        answer[-1+= "*2"
        print(answer)
        if len(answer) > 1:
            answer[-2+= "*2"
            print(answer)
    elif i == "#":
        dartResult = dartResult[dartResult.index(i)+1:]
        answer[-1+= "*(-1)"
        print(answer)
 
"""
['1**2']
['1**2*(-1)']
['1**2*(-1)', '2**1']
['1**2*(-1)', '2**1*2']
['1**2*(-1)*2', '2**1*2']
['1**2*(-1)*2', '2**1*2', '3**1']
"""
cs

결과에 join() 함수를 사용하면 특정 문자열을 기준으로 리스트 원소 값들을 한 개의 값으로 만들 수 있다. 마지막으로 문자열을 수식으로 변환해주는 eval() 함수를 사용해서 결과를 반환했다.

1
2
3
4
5
6
7
8
9
10
11
print("+".join(answer))
 
"""
1**2*(-1)*2+2**1*2+3**1
"""
 
print(eval("+".join(answer)))
 
"""
5
"""
cs

소스 코드

전체 코드는 아래와 같다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
def solution(dartResult):
    bonus = {"S":"1""D":"2""T":"3"}
    answer = []
    for i in dartResult:
        if i.isalpha():
            temp = dartResult[:dartResult.index(i)+1
            dartResult = dartResult[dartResult.index(i)+1:]
            answer.append(temp.replace(i, "**" + bonus[i]))
        elif i == "*":
            dartResult = dartResult[dartResult.index(i)+1:]
            answer[-1+= "*2"
            if len(answer) > 1:
                answer[-2+= "*2"
        elif i == "#":
            dartResult = dartResult[dartResult.index(i)+1:]
            answer[-1+= "*(-1)"
    return eval("+".join(answer))
cs
반응형