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

2023. 4. 16. 15:58·Algorithm/프로그래머스
 

프로그래머스

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

programmers.co.kr

 

코드

import re

def solution(dartResult):  
    dr = re.split('([0-9][0-9]?[A-Z][#|*]?)', dartResult)
    dr = ' '.join(dr).split()
    # print(dr)
    
    num = []
    for i in dr:
        n = 0
        for j in range(len(i)):
            if i[j] == 'S':
                n = (int(i[:j]) ** 1)
            if i[j] == 'D':
                n = (int(i[:j]) ** 2)
            if i[j] == 'T':
                n =(int(i[:j]) ** 3)
        num.append(n)
    # print(num)
    
    for i in range(len(dr)):
        if '*' in dr[i]:
            if i == 0:
                num[i] *= 2
            else:
                num[i] *= 2
                num[i-1] *= 2
        if '#' in dr[i]:
            num[i] *= (-1)
    # print(num)
    
    return sum(num)

 

문제를 파악하는 것은 아래 사진처럼 예시 몇 가지만 직접 풀어보면 쉽게 이해할 수 있다.

하지만 난관은 '1S2D*3T'와 같은 문자열을 어떻게 분리하느냐에 있었다.

옵션이 없으면 1S, 옵션이 있으면 2D* 까지 분리를 해야 하는데 이 규칙을 구현하기 위해 정규표현식을 사용하였다.

점수는 0부터 10점까지 주어지기 때문에 두자리 수를 정규표현식으로 나타내면 [0-9][0-9]가 된다.

항상 두 자리인 것은 아니니 [0-9][0-9]? 와 같이 나타내어 두 번째 자리는 있을 수도 있고, 없을 수도 있음을 표현한다.

점수 다음에는 보너스를 나타내는 대문자 한자리가 위치하므로 [A-Z]로 나타낼 수 있다.

보너스 다음에 오는 옵션은 * 또는 #이므로 [*|#]으로 나타낼 수 있다. 옵션 역시 경우에 따라 있을 수도 있고 없을 수도 있으므로 [*|#]?로 나타낸다.

dr = re.split('([0-9][0-9]?[A-Z][#|*]?)', dartResult)

위 코드와 같이 re.split을 사용하여 주어진 문자열 dartResult를 분리할 수 있다.

분리한 문자열 dr을 출력해 보면 필요 없는 빈 문자열이 추가되어 있다.

df

이를 제거하기 위해서 dr을 연결하되 공백을 하나씩 추가해 주고, 연결된 문자열을 다시 공백을 기준으로 분리해 준다.

dr = ' '.join(dr).split()

dr

이제 dr의 요소를 하나씩 가져와 점수를 계산해 주면 된다.

옵션은 마지막으로 계산하기 위해 보너스 점수만 먼저 계산하였다.

num = []
for i in dr:
    n = 0
    for j in range(len(i)):
        if i[j] == 'S':
            n = (int(i[:j]) ** 1)
        if i[j] == 'D':
            n = (int(i[:j]) ** 2)
        if i[j] == 'T':
            n =(int(i[:j]) ** 3)
    num.append(n)

dr에서 첫 번째 요소인 '1S'를 가져왔다고 해보자.

'1S'에서 S의 위치를 찾는다.

위치를 찾는 이유는 해당 문자열(=보너스) 앞까지의 문자열이 점수를 의미하기 때문이다.

따라서 보너스 문자열 전까지를 슬라이싱 하면 점수가 될 것이고, 이 점수는 현재 문자열 형태이므로 int로 바꿔 해당 보너스만큼 제곱을 해준다.

한 자릿수이면 i[0]으로 접근할 수 있지만, 두 자리 수인 경우에는 그럴 수가 없다. 그래서 슬라이싱을 통해 보너스를 의미하는 문자열 전까지를 점수로 추출한 것이다.

이렇게 하면 완료한 보너스 계산을 num 리스트에 추가한다.

dr, 보너스 계산을 한 num

이제 옵션을 계산하기 위해 dr에서 옵션이 위치한 곳을 찾는다. 

    for i in range(len(dr)):
        if '*' in dr[i]:
            if i == 0:
                num[i] *= 2
            else:
                num[i] *= 2
                num[i-1] *= 2
        if '#' in dr[i]:
            num[i] *= (-1)

dr과 num은 길이가 같다. 그러므로 dr의 0번은 num의 0번이다.

*은 전 요소와 해당 요소에 모두 2배씩 해주되, 첫 번째 요소(=0번 인덱스)에 *이 있다면 해당 요소만 2배를 해준다.

#은 해당 요소에만 마이너스를 해주면 되므로 -1을 곱해준다.

dr, 보너스 계산 num, 옵션 계산 num

이렇게 옵션까지 계산이 완료되면 점수 합계인 sum(num)을 리턴해주면 된다.

반응형
저작자표시
'Algorithm/프로그래머스' 카테고리의 다른 글
  • 프로그래머스 | 2021 Dev-Matching: 웹 백엔드 개발자(상반기) | 로또의 최고 순위와 최저 순위 [파이썬 python]
  • 프로그래머스 | 카드 뭉치 [파이썬 python]
  • 프로그래머스 | 2019 KAKAO BLIND RECRUITMENT | 실패율 [파이썬 python]
  • 프로그래머스 | 과일 장수 [파이썬 python]
dduniverse
dduniverse
  • dduniverse
    dduniverse
    dduniverse
  • 전체
    오늘
    어제
    • 분류 전체보기 (242)
      • Algorithm (123)
        • 알고리즘 이론 (8)
        • 백준 (19)
        • 프로그래머스 (83)
        • 구름 알고리즘 먼데이 챌린지 (13)
      • 빅데이터분석기사 (10)
        • 통계 (4)
        • 실기 (6)
      • KT에이블스쿨 (26)
      • FrontEnd (11)
        • React (5)
        • 기타 (6)
      • BackEnd (18)
        • Django (15)
        • Spring (3)
      • DS & ML (11)
        • Machine Learning (9)
        • Kaggle (2)
      • TIL (43)
        • python (22)
        • javascript (3)
        • 오류해결 (10)
        • 기타 (7)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
    • 관리
    • 글쓰기
  • 링크

  • 인기 글

  • hELLO· Designed By정상우.v4.10.0
dduniverse
프로그래머스 | 2018 KAKAO BLIND RECRUITMENT | [1차] 다트 게임 [파이썬 python]
상단으로

티스토리툴바