PROGRAMMERS Python Lv1. 다트게임
이번 문제는 다트게임이다.
정답 코드는 다음과 같다.
def solution(dartResult):
answer = 0
for idx in range(1, len(dartResult)):
if dartResult[idx] == "S":
if idx+1 != len(dartResult):
if dartResult[idx+1] == "*":
answer += (int(dartResult[idx-1])^1) * 2
elif dartResult[idx+1] == "#":
answer += (int(dartResult[idx-1])^1) * (-1)
else:
answer += int(dartResult[idx-1])^1
else:
answer += int(dartResult[idx-1])^1
elif dartResult[idx] == "D":
if idx+1 != len(dartResult):
if dartResult[idx+1] == "*":
answer += (int(dartResult[idx-1])^2) * 2
elif dartResult[idx+1] == "#":
answer += (int(dartResult[idx-1])^2) * (-1)
else:
answer += int(dartResult[idx-1])^2
else:
answer += int(dartResult[idx-1])^2
elif dartResult[idx] == "T":
if idx+1 != len(dartResult):
if dartResult[idx+1] == "*":
answer += (int(dartResult[idx-1])^3) * 2
elif dartResult[idx+1] == "#":
answer += (int(dartResult[idx-1])^3) * (-1)
else:
answer += int(dartResult[idx-1])^3
else:
answer += int(dartResult[idx-1])^3
else:
pass
return answer
처음에 나는 위의 코드처럼 문제에 접근했었다. 결과는 당연히 실패였고, 코드 실행 결과 중 단 하나만 맞췄다.
내가 생각했던 방식은 우선 주어진 리스트를 하나씩 읽어 들여서,
알파벳을 기준으로 구분 하려했다.
알파벳이 아닐 경우는 pass 시키고 각각의 알파벳일 때, 두 가지로 나눴다.
하나는 알파벳 뒤에 *나 #가 따라올 경우, 하나는 아무것도 없이 알파벳만 있을 경우이다.
그렇지만 여기서 내가 고려하지 못한 것은 10과 같이 2자리 점수일 경우이다. 또한 이 코드가 다른 테스트들에서 거의 제대로 작동하지 않았던 것도 문제였다.
그래서 정규표현식을 활용한 정답을 분석하고, 다시 한번 리뷰해보려고 한다.
정규 표현식 정답
import re
def solution(dartResult):
bonus = {'S' : 1, 'D' : 2, 'T' : 3}
option = {'' : 1, '*' : 2, '#' : -1}
p = re.compile('(\d+)([SDT])([*#]?)')
dart = p.findfall(dartResult)
for i in range(len(dart)):
if dart[i][2] == '*' and i > 0:
dart[i-1] *= 2
dart[i] = int(dart[i][0]) ** bonus[dart[i][1]] * option[dart[i][2]]
answer = sum(dart)
return answer
우선 정규표현식 사용을 위해 re를 import 시켜준다. 여기선 알파벳과 보너스 기호를 각각 dictionary로 만들어줬다.
p = re.compile('(\d+)([SDT])([*#]?)')
위 코드는 p에 re.compile의 결과를 돌려주는 것이다.
\d는 숫자와 매치한다는 것이고 +는 한번 이상 매치한다는 의미이다.
[SDT] 는 각각의 문자와 매칭한다는 것이고,
[*#]?는 ?가 붙어 있어 * 혹은 #이 포함될 수도 아닐 수도 있다는 것이다.
findfall은 정규식과 매치되는 모든 문자열(substring)을 리스트로 돌려준다.
예시 1번으로 주어진 것과 같이 1S2D*3T가 주어지면
dart = p.findfall(dartResult)는
[[“1”,”S”,””],[“2”,”D”,”*”],[“3”,”T”,””]] 과 같이 나타난다.
따라서, 2차원의 리스트로 되어 있으므로,
dart의 원소들을 숫자로 변환해준 후 sum함수를 통해 더해주면 된다.
이 코드는 사실 다시 내가 작성해서 풀기는 매우 어려울 것 같다고 느껴졌다.
그러나, spark를 배우고 있고, 정규표현식을 많이 사용해서
정규표현식에 대한 공부를 더 할 필요는 있을 것 같다.
댓글남기기