본문 바로가기
프로그래머스/Lv.1

2018 KAKAO BLIND RECRUITMENT > 다트 게임 - Pyton, re, compile, findall, 정규식

by 아찌방 2024. 12. 6.

 

 

https://school.programmers.co.kr/learn/courses/30/lessons/17682

 

프로그래머스

SW개발자를 위한 평가, 교육, 채용까지 Total Solution을 제공하는 개발자 성장을 위한 베이스캠프

programmers.co.kr

 

코드

def solution(dartResult):
    num = ""
    score = []
    bonus = {"S":1, "D":2, "T":3}
        
    for round in dartResult:
        if round.isdigit():
            num += round
        elif round in bonus:
            score.append(int(num) ** bonus[round])
            num = ""
        elif round == "*":
            if score:
                score[-1] *= 2
                if len(score) > 1:
                    score[-2] *= 2
        elif round == "#":
            score[-1] *= -1
                
    return sum(score)

 

그냥 주어진 문제를 차근차근 풀었습니다.

 

1. 숫자 처리

 

isdigit()로 숫자일 경우에는 변수에 저장합니다.

 

이때 2자리 수 숫자가 올 수도 있기때문에 일단 문자열로 받고

 

나중에 int로 변환 후 저장했습니다.

 

2. bonus 처리

 

bonus를 딕셔너리로 미리 저장해뒀는데

 

조건문을 조금이라도 줄이고 싶었습니다.

 

그래서 bonus에 해당하면 아까 저장한 숫자를 bonus에 맞춰 저장해줍니다.

 

3. option 처리

 

마지막으로 option처리는 명확하기위해 명시를 해뒀고

 

3-1. "*" 처리

 

"*"의 경우 두배 처리를 해줘야하는데

 

어차피 socre의 맨뒤는 무조건 있을테고

 

리스트가 2개 이상이면 socre[-2]의 값도 두배 처리를 해줬습니다.

 

3-2. "#" 처리

 

"#"의 경우는 

 

score[-1] 값을 음수로 바꿔주기만 하면 됩니다.

 

4. 합

 

sum을 이용해 score의 합을 return 해주면 마무리 됩니다.

 

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)):
        score = int(dart[i][0]) ** bonus[dart[i][1]]
        if dart[i][2] == '*':
            score *= option[dart[i][2]]
            if i > 0:
                dart[i-1] = dart[i-1] * 2
        elif dart[i][2] == '#':
            score *= option[dart[i][2]]
        dart[i] = score
        
    return sum(dart)

 

정규식 사용

 

re.compie을 통해 정규식 패턴( (\d+)([SDT])([*#]?))을 컴파일 합니다.

 

(\d+) : 하나 이상의 숫자 (점수)

 

([SDT]) : 보너스 문자인 'S', 'D', 'T'

 

([*#]?) : 옵션 문자로 '*' 또는 '#', 없을 수도 있습니다.

 

 re.findall을 사용하여 정규식 패턴으로 각 라운드를 분리합니다.

 

이렇게 각 라운드를 분리하면

"1S2D*3T" => [('1', 'S', ''), ('2', 'D', '*'), ('3', 'T', '')]

 

이런식으로 됩니다.

 

그러면 이거를 반복문으로 돌렸을때

 

dart[i][0] : 숫자

 

dart[i][1] : bonus

 

dart[i][2] : option

 

이겠죠?

 

이를 바탕으로 반복문을 통해 문제에 맞춰서 처리를 해주면 끝이 납니다.

 

위의 코드와 비교했을때 

 

메모리 사용량은 비슷합니다만 좀 더 높습니다.

 

하지만 속도가 압도적으로 느립니다.

 

그래도 테케는 다 통과를 하니 마음에 드는 방식으로 사용하시면 됩니다.

 

 

다음에 또 봐요

 

728x90