[파이썬] 프로그래머스 LV1 다트게임

청수동햄주먹·2023년 2월 10일
0

파이썬코딩테스트

목록 보기
17/35

프로그래머스 다트게임

내 풀이

def checkSDT (result):
    value = result[0]
    if result[0] == 'X': value = 10
    if result[1]=='D': value = int(value)**2
    elif result[1]=='T': value = int(value)**3
    return str(value)+result[2:]

def solution(result):
    result = result.replace('10','X')
    idx = []
    for i, x in enumerate(result):
        if x.isdigit() or x == 'X':
            idx.append(i)

    first = checkSDT(result[:idx[1]])
    second = checkSDT(result[idx[1]:idx[2]])
    third = checkSDT(result[idx[2]:])
    
    if '*' in second:
        first += '*'
    if '*' in third:
        second += '*'

    score = []
    for x in [first,second,third]:
        x = x.replace('**','$')
        x = x.replace('#*','^')
        if x.isdigit():
            score.append(int(x))
        else:
            value = int(x[:-1])
            if x[-1]=='*': score.append(value*2)
            elif x[-1]=='$': score.append(value*4)
            elif x[-1]=='^': score.append(value*-2)
            else:score.append(value*-1)
    return sum(score)

별로 효율적인것 같지 않지만 문자열의 길이가 길지 않은 점.
다뤄야할 아이템?개수가 항상 3개라는 점 때문에 그대로 진행하였다.

  1. 10이 있으면 우선 X로 치환해줌.
  2. 왜냐하면.. 숫자이거나 X일 때마다 인덱스를 모을 것이기 때문
  3. 인덱스를 기준으로 인풋 문자열에서 first, second, third를 설정해준다. 그리고 그 세개의 문자열들을 checkSDT로 보내주기
  4. SDT에서는.. 첫번째 문자가 X일 경우 여기에서 10으로 바꿔준다. 각 청크의 두번째 문자에 따라 첫번째 문자의 정수 값에 ^1,^2,^3 해준다. 이 값을 문자열변환 해주고 청크의 나머지값과 합쳐서 리턴해준다.
  5. second나 third에 가 있으면 first, second의 점수도 두배를 해줘야 하므로 이 경우 각각 앞 순서의 문자열에 를 더해준다.
  6. 이제 점수를 계산할 단계이다. *을 더해주는 과정에서 **, #*가 만들어 질 수 있다. 이 때 다른 특수문자 하나로 치환해주게 된다.
    a. 숫자로만 구성된 경우 바로 정수로 치환해서 score리스트에 추가
    b. 그 밖의 경우 계산법에 따라 정수로 치환해서 계산해준 후
    score리스트에 추가
  7. score 리스트의 값을 sum()해서 리턴

다른 사람의 풀이

regex를 이용

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

    answer = sum(dart)
    return answer

인덱스를 활용한 풀이

def solution(dartResult):
    point = []
    answer = []
    dartResult = dartResult.replace('10','k')
    point = ['10' if i == 'k' else i for i in dartResult]
    print(point)

    i = -1
    sdt = ['S', 'D', 'T']
    for j in point:
        if j in sdt :
            answer[i] = answer[i] ** (sdt.index(j)+1)
        elif j == '*':
            answer[i] = answer[i] * 2
            if i != 0 :
                answer[i - 1] = answer[i - 1] * 2
        elif j == '#':
            answer[i] = answer[i] * (-1)
        else:
            answer.append(int(j))
            i += 1
    return sum(answer)

간단하게 문제를 푼 풀이

def solution(dartResult):
    dart = {'S':1, 'D':2, 'T':3}
    scores = []
    n = 0

    for i, d in enumerate(dartResult):
        if d in dart:
            scores.append(int(dartResult[n:i])**dart[d])
        if d == "*":
            scores[-2:] = [x*2 for x in scores[-2:]]
        if d == "#":
            scores[-1] = (-1)*scores[-1]
        if not (d.isnumeric()):
            n = i+1

    return sum(scores)

성능 비교

내 풀이regexindexsimple
테스트 1 〉통과 (0.03ms, 10.3MB)통과 (0.15ms, 10.5MB)통과 (0.03ms, 10.4MB)통과 (0.04ms, 10.5MB)
테스트 2 〉통과 (0.04ms, 10.4MB)통과 (0.16ms, 10.3MB)통과 (0.04ms, 10.4MB)통과 (0.03ms, 10.4MB)
테스트 3 〉통과 (0.04ms, 10.3MB)통과 (0.14ms, 10.3MB)통과 (0.03ms, 10.4MB)통과 (0.03ms, 10.4MB)
테스트 4 〉통과 (0.04ms, 10.4MB)통과 (0.22ms, 10.4MB)통과 (0.02ms, 10.3MB)통과 (0.03ms, 10.5MB)
테스트 5 〉통과 (0.03ms, 10.4MB)통과 (0.15ms, 10.3MB)통과 (0.03ms, 10.4MB)통과 (0.04ms, 10.5MB)
테스트 6 〉통과 (0.04ms, 10.4MB)통과 (0.15ms, 10.3MB)통과 (0.04ms, 10.4MB)통과 (0.03ms, 10.3MB)
테스트 7 〉통과 (0.04ms, 10.4MB)통과 (0.21ms, 10.3MB)통과 (0.03ms, 10.1MB)통과 (0.03ms, 10.4MB)
테스트 8 〉통과 (0.04ms, 10.3MB)통과 (0.15ms, 10.4MB)통과 (0.04ms, 10.5MB)통과 (0.03ms, 10.5MB)
테스트 9 〉통과 (0.03ms, 10.4MB)통과 (0.15ms, 10.3MB)통과 (0.04ms, 10.2MB)통과 (0.04ms, 10.3MB)
테스트 10 〉통과 (0.04ms, 10.5MB)통과 (0.20ms, 10.4MB)통과 (0.04ms, 10.2MB)통과 (0.05ms, 10.4MB)
테스트 11 〉통과 (0.04ms, 10.4MB)통과 (0.15ms, 10.4MB)통과 (0.04ms, 10.5MB)통과 (0.03ms, 10.4MB)
테스트 12 〉통과 (0.04ms, 10.4MB)통과 (0.16ms, 10.4MB)통과 (0.03ms, 10.1MB)통과 (0.03ms, 10.3MB)
테스트 13 〉통과 (0.03ms, 10.5MB)통과 (0.17ms, 10.4MB)통과 (0.03ms, 10.3MB)통과 (0.03ms, 10.4MB)
테스트 14 〉통과 (0.02ms, 10.4MB)통과 (0.15ms, 10.3MB)통과 (0.04ms, 10.5MB)통과 (0.04ms, 10.6MB)
테스트 15 〉통과 (0.04ms, 10.4MB)통과 (0.21ms, 10.3MB)통과 (0.04ms, 10.3MB)통과 (0.04ms, 10.3MB)
테스트 16 〉통과 (0.04ms, 10.4MB)통과 (0.15ms, 10.4MB)통과 (0.04ms, 10.3MB)통과 (0.03ms, 10.3MB)
테스트 17 〉통과 (0.03ms, 10.4MB)통과 (0.22ms, 10.3MB)통과 (0.03ms, 10.2MB)통과 (0.04ms, 10.5MB)
테스트 18 〉통과 (0.05ms, 10.3MB)통과 (0.25ms, 10.3MB)통과 (0.03ms, 10.4MB)통과 (0.04ms, 10.5MB)
테스트 19 〉통과 (0.03ms, 10.4MB)통과 (0.23ms, 10.3MB)통과 (0.04ms, 10.4MB)통과 (0.03ms, 10.4MB)
테스트 20 〉통과 (0.03ms, 10.4MB)통과 (0.24ms, 10.3MB)통과 (0.03ms, 10.3MB)통과 (0.04ms, 10.4MB)
테스트 21 〉통과 (0.04ms, 10.3MB)통과 (0.15ms, 10.3MB)통과 (0.04ms, 10.2MB)통과 (0.03ms, 10.4MB)
테스트 22 〉통과 (0.06ms, 10.3MB)통과 (0.21ms, 10.3MB)통과 (0.04ms, 10.2MB)통과 (0.04ms, 10.3MB)
테스트 23 〉통과 (0.03ms, 10.3MB)통과 (0.15ms, 10.4MB)통과 (0.03ms, 10.3MB)통과 (0.03ms, 10.5MB)
테스트 24 〉통과 (0.03ms, 10.3MB)통과 (0.16ms, 10.4MB)통과 (0.04ms, 10.3MB)통과 (0.04ms, 10.4MB)
테스트 25 〉통과 (0.04ms, 10.4MB)통과 (0.17ms, 10.4MB)통과 (0.04ms, 10.4MB)통과 (0.03ms, 10.4MB)
테스트 26 〉통과 (0.04ms, 10.4MB)통과 (0.23ms, 10.4MB)통과 (0.03ms, 10.4MB)통과 (0.04ms, 10.3MB)
테스트 27 〉통과 (0.03ms, 10.5MB)통과 (0.15ms, 10.5MB)통과 (0.03ms, 10.1MB)통과 (0.04ms, 10.4MB)
테스트 28 〉통과 (0.03ms, 10.4MB)통과 (0.22ms, 10.3MB)통과 (0.04ms, 10.2MB)통과 (0.02ms, 10.5MB)
테스트 29 〉통과 (0.03ms, 10.4MB)통과 (0.20ms, 10.4MB)통과 (0.03ms, 10.4MB)통과 (0.04ms, 10.4MB)
테스트 30 〉통과 (0.03ms, 10.2MB)통과 (0.15ms, 10.5MB)통과 (0.07ms, 10.2MB)통과 (0.04ms, 10.3MB)
테스트 31 〉통과 (0.03ms, 10.4MB)통과 (0.21ms, 10.3MB)통과 (0.04ms, 10.2MB)통과 (0.03ms, 10.4MB)
테스트 32 〉통과 (0.05ms, 10.3MB)통과 (0.19ms, 10.4MB)통과 (0.04ms, 10.3MB)통과 (0.03ms, 10.5MB)
  • regex가 다른것보다 2-3배는 더 걸리는 것을 확인할 수 있는데 아마도 re.findall()에서 O(n^2)가 걸리기 때문인 것 같다..코딩테스트에서는 웬만하면 쓰지 말아야..
profile
코딩과 사별까지

0개의 댓글