다트 게임 문서의 문제 1 풀이 코드다. if __name__ == "__main__": 아래가 자체 테스트다.
"""다트 게임 (프로그래머스 17682) 풀이와 검증."""
import random
import re
def solution(dartResult):
power = {"S": 1, "D": 2, "T": 3}
scores = []
for num, bonus, opt in re.findall(r"(\d+)([SDT])([*#]?)", dartResult):
s = int(num) ** power[bonus]
if opt == "*":
s *= 2
if scores:
scores[-1] *= 2
elif opt == "#":
s = -s
scores.append(s)
return sum(scores)
def other(s):
"""한 글자씩 읽어 조각을 만들고, 조각마다 배수를 따로 모아 마지막에 곱한다."""
parts, i = [], 0
while i < len(s):
j = i
while s[j].isdigit():
j += 1
num, bonus = int(s[i:j]), s[j]
j += 1
opt = s[j] if j < len(s) and s[j] in "*#" else ""
j += len(opt)
parts.append((num, bonus, opt))
i = j
mult = [1] * len(parts)
for k, (_, _, opt) in enumerate(parts):
if opt == "*":
mult[k] *= 2
if k > 0:
mult[k - 1] *= 2
elif opt == "#":
mult[k] *= -1
return sum(num ** "_SDT".index(b) * m for (num, b, _), m in zip(parts, mult))
if __name__ == "__main__":
ex = [("1S2D*3T", 37), ("1D2S#10S", 9), ("1D2S0T", 3), ("1S*2T*3S", 23),
("1D#2S*3S", 5), ("1T2D3D#", -4), ("1D2S3T*", 59)]
for s, want in ex:
assert solution(s) == want == other(s), s
rng = random.Random(17682)
for _ in range(3000):
s = "".join(f"{rng.randint(0, 10)}{rng.choice('SDT')}{rng.choice(['', '*', '#'])}" for _ in range(3))
assert solution(s) == other(s), s
print("ALL CHECKS PASSED")