문제 설명

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

  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 중 하나이다.

  • 옵선은 *이나 # 중 하나이며, 없을 수도 있다.

 

출력 형식

3번의 기회에서 얻은 점수 합계에 해당하는 정수값을 출력한다.
예) 37

 

입출력 예제

예제 dartResult answer 설명
1 1S2D*3T 37 11 * 2 + 22 * 2 + 33
2 1D2S#10S 9 12 + 21 * (-1) + 101
3 1D2S0T 3 12 + 21 + 03
4 1S*2T*3S 23 11 * 2 * 2 + 23 * 2 + 31
5 1D#2S*3S 5 12 * (-1) * 2 + 21 * 2 + 31
6 1T2D3D# -4 13 + 22 + 32 * (-1)
7 1D2S3T* 59 12 + 21 * 2 + 33 * 2

 

코드

import re

def solution(dartResult):
    answer = 0
    p = re.compile("(\d+)([a-zA-Z])(\*|#)?")
    scores = p.findall(dartResult)
    result = []
    
    for idx, score in enumerate(scores):
        point = score[0]
        bonus = score[1]
        option = score[2]
        if bonus == 'S':
            bonus = 1
        elif bonus == 'D':
            bonus = 2
        elif bonus == 'T':
            bonus = 3
        if option == '*':
            if idx == 0:
                result.append(int(point)**bonus*2)
            else:
                result[-1] *= 2
                result.append(int(point)**bonus*2)
        elif option == '#':
            result.append(int(point)**bonus*-1)
        else: 
            result.append(int(point)**bonus)
            
    answer = sum(result)
    return answer

 

풀이 방법

  파이썬 내장 모듈인 정규 표현식(re)를 이용해 "점수 | 보너스 | [옵션]"을 한덩이로 나누어 준다.

p = re.compile("(\d+)([a-zA-Z])(\*|#)?")

  • (\d+) : 1개 이상의 숫자에 대응

      ([a-zA-Z]) : 알파벳 하나에 대응

      (\*|#)? : * 또는 #에 대응하고 있을 수도 있고 없을 수도 있기 때문에 ?를 붙여서 표현

    scores = p.findall(dartResult)

  • scores는 [('1', 'D', '#'), ('2', 'S', '*'), ('3', 'S', '')] 형태가 나온다.

  • for문과 if문을 사용해 값을 result 배열에 저장 후 원소의 합을 answer에 저장하여 반환한다.

   

문제 설명

슈퍼 게임 개발자 오렐리는 큰 고민에 빠졌다. 그녀가 만든 프렌즈 오천성이 대성공을 거뒀지만, 요즘 신규 사용자의 수가 급감한 것이다.

원인은 신규 사용자와 기존 사용자 사이에 스테이지 차이가 너무 큰 것이 문제였다.

이 문제를 어떻게 할까 고민 한 그녀는 동적으로 게임 시간을 늘려서 난이도를 조절하기로 했다. 역시 슈퍼 개발자라 대부분의 로직은 쉽게 구현했지만, 실패율을 구하는 부분에서 위기에 빠지고 말았다. 오렐리를 위해 실패율을 구하는 코드를 완성하라.

  • 실패율은 다음과 같이 정의한다.

    • 스테이지에 도달했으나 아직 클리어하지 못한 플레이어의 수 / 스테이지에 도달한 플레이어 수

전체 스테이지의 개수 N, 게임을 이용하는 사용자가 현재 멈춰있는 스테이지의 번호가 담긴 배열 stages가 매개변수로 주어질 때, 실패율이 높은 스테이지부터 내림차순으로 스테이지의 번호가 담겨있는 배열을 return 하도록 solution 함수를 완성하라.

 

제한 사항

  • 스테이지의 개수 N은 1 이상 500 이하의 자연수이다.

  • stages의 길이는 1 이상 200,000 이하이다.

  • stages에는 1 이상 N + 1 이하의 자연수가 담겨있다.

    • 각 자연수는 사용자가 현재 도전 중인 스테이지의 번호를 나타낸다.

    • 단, N + 1 은 마지막 스테이지(N 번째 스테이지)까지 클리어 한 사용자를 나타낸다.

  • 만약 실패율이 같은 스테이지가 있다면 작은 번호의 스테이지가 먼저 오도록 하면 된다.

  • 스테이지에 도달한 유저가 없는 경우 해당 스테이지의 실패율은 0 으로 정의한다.

입출력 예

N stages result
5 [2, 1, 2, 6, 2, 4, 3, 3] [3,4,2,1,5]
4 [4, 4, 4, 4, 4] [4,1,2,3]

 

입출력 예 설명

입출력 예 #1
1번 스테이지에는 총 8명의 사용자가 도전했으며, 이 중 1명의 사용자가 아직 클리어하지 못했다.

따라서 1번 스테이지의 실패율은 다음과 같다.

  • 1 번 스테이지 실패율 : 1/8

2번 스테이지에는 총 7명의 사용자가 도전했으며, 이 중 3명의 사용자가 아직 클리어하지 못했다.

따라서 2번 스테이지의 실패율은 다음과 같다.

  • 2 번 스테이지 실패율 : 3/7

마찬가지로 나머지 스테이지의 실패율은 다음과 같다.

  • 3 번 스테이지 실패율 : 2/4

  • 4번 스테이지 실패율 : 1/2

  • 5번 스테이지 실패율 : 0/1

각 스테이지의 번호를 실패율의 내림차순으로 정렬하면 다음과 같다.

  • [3,4,2,1,5]

입출력 예 #2

모든 사용자가 마지막 스테이지에 있으므로 4번 스테이지의 실패율은 1이며 나머지 스테이지의 실패율은 0이다.

  • [4,1,2,3]

 

코드

def solution(N, stages):
    fail_rate = {}
    total_user = len(stages)

    for stage in range(1, N+1):
        if total_user != 0:
            fail_user = stages.count(stage)
            fail_rate[stage] = fail_user / total_user
            total_user -= fail_user
        else:
            fail_rate[stage] = 0

    return sorted(fail_rate, key=lambda x : fail_rate[x], reverse=True)

 

풀이 방법

  • 스테이지 번호하고 같으면 도달은 하였으나 클리어하지 못한 플레이어이기 때문에

fail_user = stages.count(stage)

  • 스테이지 번호하고 같거나 커야 스테이지에 도달한 플레이어이기 때문에 단계마다 스테이지에 도달한 플레이어 수를 구한다.

total_user -= fail_user

  실패율 = 스테이지에 도달했으나 아직 클리어하지 못한 플레이어의 수 / 스테이지에 도달한 플레이어 수

fail_rate[stage] = fail_user / total_user

  • 실패율을 내림차순 정렬하여 스테이지 번호를 출력하기 위해 딕셔너리를 이용해 값에 실패율을 넣는다.

fail_rate[stage] = fail_user / total_user

  • 마지막으로 딕셔너리의 값에 있는 실패율을 내림차순 정렬한 다음 키 값을 반환한다.

sorted(fail_rate, key=lambda x : fail_rate[x], reverse=True)

문제 설명

자연수 n이 주어졌을 때, n의 다음 큰 숫자는 다음과 같이 정의합니다.

  • 조건 1. n의 다음 큰 숫자는 n보다 큰 자연수입니다.

  • 조건 2. n의 다음 큰 숫자와 n은 2진수로 변환했을 때 1의 개수가 같습니다.

  • 조건 3. n의 다음 큰 숫자는 조건 1, 2를 만족하는 수 중 가장 작은 수입니다.

예를 들어서 78(1001110)의 다음 큰 숫자는 83(1010011)입니다.

자연수 n이 매개변수로 주어질 때, n의 다음 큰 숫자를 return 하는 solution 함수를 완성해주세요.

제한 사항

  • n은 1,000,000 이하의 자연수입니다.

 

입출력 예

n result
78 83
15 23

 

코드

def change(num):
    num_list = []
    while num > 0:
        num_list.append(num % 2)
        num = num // 2
    return num_list

def solution(n):
    answer = 0
    b = n
    a = change(n)
    
    while True:
        b += 1
        a_1 = change(b)
        if a.count(1) == a_1.count(1):
            answer = b
            break
    
    return answer

 

풀이 방법

  • 십진수를 이진수로 전환해주는 change 함수를 만들었다.

def change(num):
    num_list = []
    while num > 0:
        num_list.append(num % 2)
        num = num // 2
    return num_list

  • b에 n(입력 값)을 저장하고 a에는 n의 이진수를 저장한 후, 무한루프를 이용해 b값을 1씩 증가시키고 a_1에 이진수로 전환된 b를 저장

  • a의 1의 개수와 a_1의 1의 개수가 같을 시 b를 반환한다.

문제 설명

괄호가 바르게 짝지어졌다는 것은 '(' 문자로 열렸으면 반드시 짝지어서 ')' 문자로 닫혀야 한다는 뜻입니다. 예를 들어

  • ()() 또는 (())() 는 올바른 괄호입니다.

  • )()( 또는 (()( 는 올바르지 않은 괄호입니다.

'(' 또는 ')' 로만 이루어진 문자열 s가 주어졌을 때, 문자열 s가 올바른 괄호이면 true를 return 하고, 올바르지 않은 괄호이면 false를 return 하는 solution 함수를 완성해 주세요.

제한사항

  • 문자열 s의 길이 : 100,000 이하의 자연수

  • 문자열 s는 '(' 또는 ')' 로만 이루어져 있습니다.

 

입출력 예

s answer
"()()" true
"(())()" true
")()(" false
"(()(" false

 

코드

def solution(s):
    stack = []
    
    for i in s:
        if i == "(":
            stack.append(i)
        else:
            if len(stack) == 0:
                 return False
            else:
                stack.pop()
                
    if len(stack) == 0:
        return True
    else:
        return False

 

풀이 방법

  • stack을 사용해서 풀었다.

  • for문을 사용해 "("이면 stack에 저장하고 아니면 빼내는 방식으로 하였다.

  단, 처음에 ")"가 들어가면 "()"짝이 안맞기 때문에 스택의 길이가 0이면 False를 반환

  • for문을 다 돌고 stack의 길이가 0이면 "()"짝이 맞으므로 True를 반환하고 아니면 False를 반환한다.

 

+ Recent posts