코드
import re
def solution(dartResult):
dr = re.split('([0-9][0-9]?[A-Z][#|*]?)', dartResult)
dr = ' '.join(dr).split()
# print(dr)
num = []
for i in dr:
n = 0
for j in range(len(i)):
if i[j] == 'S':
n = (int(i[:j]) ** 1)
if i[j] == 'D':
n = (int(i[:j]) ** 2)
if i[j] == 'T':
n =(int(i[:j]) ** 3)
num.append(n)
# print(num)
for i in range(len(dr)):
if '*' in dr[i]:
if i == 0:
num[i] *= 2
else:
num[i] *= 2
num[i-1] *= 2
if '#' in dr[i]:
num[i] *= (-1)
# print(num)
return sum(num)
문제를 파악하는 것은 아래 사진처럼 예시 몇 가지만 직접 풀어보면 쉽게 이해할 수 있다.
하지만 난관은 '1S2D*3T'와 같은 문자열을 어떻게 분리하느냐에 있었다.
옵션이 없으면 1S, 옵션이 있으면 2D* 까지 분리를 해야 하는데 이 규칙을 구현하기 위해 정규표현식을 사용하였다.
점수는 0부터 10점까지 주어지기 때문에 두자리 수를 정규표현식으로 나타내면 [0-9][0-9]가 된다.
항상 두 자리인 것은 아니니 [0-9][0-9]? 와 같이 나타내어 두 번째 자리는 있을 수도 있고, 없을 수도 있음을 표현한다.
점수 다음에는 보너스를 나타내는 대문자 한자리가 위치하므로 [A-Z]로 나타낼 수 있다.
보너스 다음에 오는 옵션은 * 또는 #이므로 [*|#]으로 나타낼 수 있다. 옵션 역시 경우에 따라 있을 수도 있고 없을 수도 있으므로 [*|#]?로 나타낸다.
dr = re.split('([0-9][0-9]?[A-Z][#|*]?)', dartResult)
위 코드와 같이 re.split을 사용하여 주어진 문자열 dartResult를 분리할 수 있다.
분리한 문자열 dr을 출력해 보면 필요 없는 빈 문자열이 추가되어 있다.
이를 제거하기 위해서 dr을 연결하되 공백을 하나씩 추가해 주고, 연결된 문자열을 다시 공백을 기준으로 분리해 준다.
dr = ' '.join(dr).split()
이제 dr의 요소를 하나씩 가져와 점수를 계산해 주면 된다.
옵션은 마지막으로 계산하기 위해 보너스 점수만 먼저 계산하였다.
num = []
for i in dr:
n = 0
for j in range(len(i)):
if i[j] == 'S':
n = (int(i[:j]) ** 1)
if i[j] == 'D':
n = (int(i[:j]) ** 2)
if i[j] == 'T':
n =(int(i[:j]) ** 3)
num.append(n)
dr에서 첫 번째 요소인 '1S'를 가져왔다고 해보자.
'1S'에서 S의 위치를 찾는다.
위치를 찾는 이유는 해당 문자열(=보너스) 앞까지의 문자열이 점수를 의미하기 때문이다.
따라서 보너스 문자열 전까지를 슬라이싱 하면 점수가 될 것이고, 이 점수는 현재 문자열 형태이므로 int로 바꿔 해당 보너스만큼 제곱을 해준다.
한 자릿수이면 i[0]으로 접근할 수 있지만, 두 자리 수인 경우에는 그럴 수가 없다. 그래서 슬라이싱을 통해 보너스를 의미하는 문자열 전까지를 점수로 추출한 것이다.
이렇게 하면 완료한 보너스 계산을 num 리스트에 추가한다.
이제 옵션을 계산하기 위해 dr에서 옵션이 위치한 곳을 찾는다.
for i in range(len(dr)):
if '*' in dr[i]:
if i == 0:
num[i] *= 2
else:
num[i] *= 2
num[i-1] *= 2
if '#' in dr[i]:
num[i] *= (-1)
dr과 num은 길이가 같다. 그러므로 dr의 0번은 num의 0번이다.
*은 전 요소와 해당 요소에 모두 2배씩 해주되, 첫 번째 요소(=0번 인덱스)에 *이 있다면 해당 요소만 2배를 해준다.
#은 해당 요소에만 마이너스를 해주면 되므로 -1을 곱해준다.
이렇게 옵션까지 계산이 완료되면 점수 합계인 sum(num)을 리턴해주면 된다.