본문 바로가기
Coding Test/Python

[프로그래머스] [1차] 다트 게임 Python Code

by giem 2022. 8. 27.
반응형

 

프로그래머스의 2018년 카카오 코딩 테스트 문제 1차 다트게임을 Python으로 풀어보겠다.


문제

문제는 쭉 읽어보면 이해하기 쉽다.


구현

입력 문자열을 반복문으로 돌며

1. 숫자인지 확인

2. 보너스 확인

3. 옵션 확인

이 세 가지를 한다.

보너스 다음에 숫자가 온다면 숫자에 보너스 값을 제곱하여 chance(기회) 리스트에 넣는다.

옵션을 받으면 숫자에 보너스 값을 제곱하고 옵션 처리를 해준다.

 

시뮬레이션 문제라 구현은 간단하게 할 수 있다.


코드
bonus = {'S':1, 'D':2, 'T':3}
def solution(dartResult):
    chance=[]
    n=""
    for i, c in enumerate(dartResult):
        o=1
        if c.isdigit():
            n+=c
        elif c in ['S','D','T']:
            b=bonus[c]
            if i+1 == len(dartResult) or dartResult[i+1].isdigit():
                chance.append((int(n)**b))
                n=''
        else:
            if c == '*':
                if len(chance):
                    chance[-1]*=2
                chance.append((int(n)**b)*2)
                n=''
            else:
                chance.append(-(int(n)**b))
                n=''

    return sum(chance)

보너스를 if로 따로 처리하기 귀찮아서 dict를 사용했다.

한번 오류가 떴었는데 10을 처리해주지 않았기 때문이어서

n에 대한 보수작업을 하면서 n=''가 여러 번 들어가서 코드가 좀 지저분해진 것 같다.

 

나머지는 구현한 부분과 같고

*옵션일 때 이전 값이 있는지 확인하기 위해 if len(chance)를 써서

이전 값이 있다면 이전 값도 두 배를 해주었다.


다른 풀이
import re

def solution(dartResult):
    bonus = {'S' : 1, 'D' : 2, 'T' : 3}
    option = {'' : 1, '*' : 2, '#' : -1}
    p = re.compile('(\d+)([SDT])([*#]?)')
    dart = p.findall(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

이것도 생각했던 방법 중 하나인데 정규표현식이 헷갈려서 하지 못했다.

정규표현식으로 추출해내면 각 기회의 문자열이 튜플 리스트로 반환된다.

 

ex) 1S2D*3T -> [ (1, S), (2, D,*), (3, T) ]

 

이 리스트를 돌며 각각 처리를 해준 것이다.

 


여기서 추가로 내 방법에서 조금 더 정리된 코드도 보겠다.

def solution(dartResult):
    point = []
    answer = []
    dartResult = dartResult.replace('10','k')
    point = ['10' if i == 'k' else i for i in dartResult]
    print(point)

    i = -1
    sdt = ['S', 'D', 'T']
    for j in point:
        if j in sdt :
            answer[i] = answer[i] ** (sdt.index(j)+1)
        elif j == '*':
            answer[i] = answer[i] * 2
            if i != 0 :
                answer[i - 1] = answer[i - 1] * 2
        elif j == '#':
            answer[i] = answer[i] * (-1)
        else:
            answer.append(int(j))
            i += 1
    return sum(answer)

dartResult를 replace 하고 point로 나누어서 코드를 조금 더 깔끔하게 구현했다.

시간 복잡도 측면에서는 아주 약간 더 걸릴 수 있지만

점수가 10점까지 있을 때는 아주 좋은 코드라고 생각한다.

반응형

댓글