티스토리 뷰

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

 

프로그래머스

코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.

programmers.co.kr

문제내용

카카오톡 게임별의 하반기 신규 서비스로 다트 게임을 출시하기로 했다. 다트 게임은 다트판에 다트를 세 차례 던져 그 점수의 합계로 실력을 겨루는 게임으로, 모두가 간단히 즐길 수 있다.
갓 입사한 무지는 코딩 실력을 인정받아 게임의 핵심 부분인 점수 계산 로직을 맡게 되었다. 다트 게임의 점수 계산 로직은 아래와 같다.

1. 다트 게임은 총 3번의 기회로 구성
2. 각 기회마다 0 ~ 10
3. 점수와 함께 Single(S), Double(D), Triple(T) 영역이 존재하고 각 영역 당첨 시 점수에서 1제곱, 2제곱, 3제곱 (점수1 , 점수2 , 점수3 )으로 계산된다.
4. 옵션으로 스타상(*) , 아차상(#)이 존재하며 스타상(*) 당첨 시 해당 점수와 바로 전에 얻은 점수를 각 2배로 만든다. 아차상(#) 당첨 시 해당 점수는 마이너스된다.
5. 스타상(*)은 첫 번째 기회에서도 나올 수 있다. 이 경우 첫 번째 스타상(*)의 점수만 2배가 된다. (예제 4번 참고)
6. 스타상(*)의 효과는 다른 스타상(*)의 효과와 중첩될 수 있다. 이 경우 중첩된 스타상(*) 점수는 4배가 된다. (예제 4번 참고)
7. 스타상(*)의 효과는 아차상(#)의 효과와 중첩될 수 있다. 이 경우 중첩된 아차상(#)의 점수는 -2배가 된다. (예제 5번 참고)
8. Single(S), Double(D), Triple(T)은 점수마다 하나씩 존재한다.
9. 스타상(*), 아차상(#)은 점수마다 둘 중 하나만 존재할 수 있으며, 존재하지 않을 수도 있다.

 

0~10의 정수와 문자 S, D, T, *, #로 구성된 문자열이 입력될 시 총점수를 반환하는 함수를 작성하라.

 

입력 형식

"점수|보너스|[옵션]"으로 이루어진 문자열 3세트.
예) 1S2D*3T

점수는 0에서 10 사이의 정수이다.
보너스는 S, D, T 중 하나이다.
옵선은 *이나 # 중 하나이며, 없을 수도 있다.

 

출력 형식

37

 

접근 방법

한글자씩 읽어 조건에 따라 조건에 따라 계산.

[*] 옵션값의 경우 그전 스코어에 연산이 필요하므로, List를 생성하여 계산하였다. 

 

처음 소스코드 

def solution(dartResult):
    answer = 0

    dartResult = list(dartResult)
    scoreList = [0] * 3
    doubleStr = {'S': 1, 'D': 2, 'T': 3}
    optionStr = {'#': -1, '*': 2}

    number = -1
    while len(dartResult) != 0:
        item = dartResult.pop(0)
        if item.isdigit(): 			# 한글자씩 읽어올경우 10에 대한 처리 필요
            number += 1
            if dartResult[0].isdigit():
                item = 10
                dartResult.pop(0)
            scoreList[number] = int(item)
        elif doubleStr.get(item) != None:
            scoreList[number] **= int(doubleStr.get(item))
        elif optionStr.get(item) != None:
            scoreList[number] *= int(optionStr.get(item))

        if number > 0 and item == '*':	# * option이고, 첫 기회가 아닐경우 그전 기회에도 2배
            scoreList[number - 1] *= 2
    return sum(scoreList)

 

점수가 10점일 경우 어떻게 처리해야할지 고민하였다.. 

 

정규표현식을 이용하면 깔끔하게 작성할 수 있다.

 

#정규표현식을 이용한 리펙터링 소스코드
import re


def solution(dartResult):
    answerList = [0] * 3
    p = re.compile('(\d+)([SDT])([*#]?)')

    doubleStr = {'S': 1, 'D': 2, 'T': 3}
    optionStr = {'': 1, '#': -1, '*': 2}

    dart = p.findall(dartResult)

    for idx, value in enumerate(dart):
        # print('idx : ', idx , ' value : ', value)
        score = int(value[0])
        score **= int(doubleStr.get(value[1]))
        score *= int(optionStr.get(value[2]))

        answerList[idx] = score

        if value[2] == "*" and idx > 0:
            answerList[idx - 1] *= optionStr.get(value[2])

    print(answerList)
    return sum(answerList)

 

정규표현식 : '(\d+)([SDT])([*#]?)') 

입력값 : "1S2D*3T"

dart  : [('1', 'S', ''), ('2', 'D', '*'), ('3', 'T', '')]

 

공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/07   »
1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30 31
글 보관함