[파이썬 / Algorithm] 프로그래머스 KAKAO BLIND RECRUITMENT 1차 다트게임

waterlyn·2022년 1월 3일
0
post-thumbnail
post-custom-banner

문제

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

입력 형식

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

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

풀이

가장 중요하다고 생각하는 부분? 🤔

이 문제를 풀면서 가장 중요한 부분이 바로 문자열을 나누는 것이라고 생각한다 !!

문자열 3세트가 어떤 기준에 의해 적혀져 있지도 않아서 쉽게 split으로 나눌 수도 없어서 이것이 아마 풀이의 가장 큰 비중을 차지 하지 않을까 라고 생각했다 ㅎㅎ

사실 내가 여기서 가장 많이 헤맸다!! 꺄하하

파이썬의 정규표현식

정규표현식은 일련의 규칙을 이용하는 것이다.

복잡한 문자열의 검색과 치환을 위해 사용되고, 파이썬뿐만 아니라 문자열을 처리하는 모든 곳에서 사용이 된다고 한다.

이 문제도 점수(숫자)|보너스(대문자 3개)|옵션(문자 2개)의 형식으로 반복되는 문자열을 사용하기 때문에 정규표현식을 사용하기에 정말 적절하다!

정규 표현식은 자세하게 잘 나와있는 블로그를 참고했다.

import re
p = re.compile('(\d*)([SDT])([*#]?)')
    result = p.findall(dartResult)

re 모듈의 compile 함수를 통해 정규표현식의 패턴 객체를 얻을 수 있다. 이 객체를 통해 문자열을 매칭하여 원하는 형식의 문자열을 얻을 수 있다.

패턴 객체를 p라는 변수에 담았고 그것을 통해 모든 매치를 찾아내는 함수를 통해 3개의 문자열 세트를 분리할 수 있게 되었다! 🥳

이제 3번의 다트 게임 결과를 분리해냈으므로 점수를 계산하는 일만 남았다.

우선 공통적인 계산 과정은 한번에 해결하고자 하였다.

이는 딕셔너리 자료구조와 함께 활용하여 구현하고자 하였다. 키값을 문자로 두어 그 문자에 해당하는 경우 보너스할 값을 가져오도록 하여 코드의 효율성을 높였다.

공통적으로 해결 가능한 경우는

  • 각 기회에 얻은 점수와 보너스
  • 옵션 적용

특수하게 조건을 따져줘야 하는 경우는

  • 스타상 * 을 얻고, 그 전 기회에서도 스타상 * 을 얻은 경우

그렇게 해서 작성한 최종 코드는 다음과 같다.

import re
def solution(dartResult):
    score = []
    # 라운드마다 점수 나누기 -> 정규표현식 사용
    p = re.compile('(\d*)([SDT])([*#]?)')
    result = p.findall(dartResult)
    
    bonus = {'S': 1, 'D': 2, 'T': 3}
    options = {'': 1, '*': 2, '#': -1}
    
    for i, res in enumerate(result):
        if i>0 and res[2] == '*':
            score[i-1] = score[i-1]*options[res[2]]
        score.append(int(res[0])**bonus[res[1]]*options[res[2]])
    
    return sum(score)

점수를 나타내는 변수로는 리스트를 사용하여 각 기회마다 점수를 입력하는 방식으로 했는데 그 이유는,

앞서 말한 특수한 조건을 가진 경우 때문에 이전 기회에서 얻은 점수를 활용해야 하기 때문이었다.

그래서 마지막에 sum 함수로 리스트의 모든 원소 값을 합한 값을 전달하도록 하며 마무리했다!

level1 문제이기 때문에 어렵지 않은 문제였지만 처음 풀어본 kakao 문제이기 때문에 너무 뿌듯했당 😆

profile
Hello there 🖤
post-custom-banner

0개의 댓글