프로그래머스_[1차]다트게임

임정민·2023년 8월 4일
1

알고리즘 문제풀이

목록 보기
80/173
post-thumbnail

프로그래머스 구현/문자열 문제입니다.실전에 대비하기 위해 60분 시간제한을 두고 풀었습니다.

문제

https://school.programmers.co.kr/learn/courses/30/lessons/17682?language=python3

[나의 풀이]

⌛ 소요 시간 36분

def solution(dartResult):

	# 옵션이 '*'일때 이전값, 현재값 x2배 해주어야하므로 
    # index out of range error를 방지하기 위함
    answer = [0]
    
    # queue 구조로 앞~뒤 순서대로 연산함
    from collections import deque

    dartResult = deque(list(dartResult))
	
    # 수식을 위한 parser
    parser = {'S':1,'D':2,'T':3,'*':2,'#':-1}

    score = ''
    while dartResult:

        v = dartResult.popleft()

        score += v

        if v in ['S','D','T']:
            answer.append(int(score[:-1])**parser[v])

            if dartResult:

                v2 = dartResult.popleft()
                if v2 == '*':
                    answer[len(answer)-1] *= 2
                    answer[len(answer)-2] *= 2
                elif v2 == '#':
                    answer[-1] *= -1
				
                # 옵션이 아닐 시 다시 appendleft()
                else: 
                    dartResult.appendleft(v2)

                score = ''

    return sum(answer)

주어진 문자열 형태의 점수표를 연산하는 문제입니다. 주어진 점수표를 순서대로 연산 목록 리스트 (answer)에 append 하기 위해 queue 구조로 구현하였습니다.

또한 점수를 계산하는 연산 과정에서 옵션 '*'으로 인해 이전값/현재값에 2배 연산을 할 때, index out of range 오류가 발생하는 것을 방지하기 위해 연산 목록 리스트 (answer)에 미리 0 (어떠한 수식을 계산해도 0)을 추가하는 것이 저의 풀이의 포인트였습니다.

[다른 사람의 풀이1]

def solution(dartResult):
    stack = []
    dartResult = dartResult.replace("10", "A")
    bonus = {'S': 1, 'D': 2, 'T': 3}
    
    for i in dartResult:
        if i.isdigit() or i=='A':
            stack.append(10 if i == 'A' else int(i))
        elif i in ('S', 'D', 'T'):
            num = stack.pop()
            stack.append(num ** bonus[i])
        elif i == '#':
            stack[-1] *= -1
        elif i == '*':
            num = stack.pop()
            if len(stack):
                stack[-1] *= 2
            stack.append(2 * num)
    return sum(stack)

문제에서 획득할 수 있는 점수는 1~10점이므로 두글자인 점수 '10' 값 하나만 replace한 후 if문으로만 해결할 수 있는 풀이입니다.

str.isdigit()함수를 활용하여 해당 문자열(str)이 숫자로 이루어진 문자열인지 판단하는 방식이었습니다.

[다른 사람의 풀이2]

def solution(dartResult):
    res = []
    cnt = 0 #한판 점수
    dartResult=dartResult.replace("10", "t")
    
    for n in dartResult:
        if n.isnumeric():
            cnt += int(n)
            continue
        elif n == 't': #10점
            cnt += 10
            continue
        elif n == 'S':
            res.append(cnt)
        elif n == 'D':
            res.append(cnt ** 2)
        elif n == 'T':
            res.append(cnt ** 3)
        elif n == '*': #스타상이고 두 판 이상했을 때
            if len(res)>1:
                res[-1] *= 2  #해당점수 2배
                res[-2] *= 2  #바로 전 점수 2배
            else : # 한판만 했으면
                res[-1] *= 2
        elif n == '#': 
            res[-1] *= -1
        cnt=0 #한판점수 초기화
    return(sum(res))

'다른 사람의 풀이1'과 유사한 방식으로 '10'점만 replace 하되, 다른점은 str.isnumberic()함수로 문자열(str)이 숫자로만 이루어진 함수인지 파악하는 방식이었습니다.

문자열이 숫자로만 이루어져있는지 판별하는 함수들을 확인할 결과

isdigit(),
isdecimal(),
isnumberic()

을 비교해보자면

ex)

a = '3²'
print(a.isdigit()) 
# True

print(a.isdecimal())
# False

print(a.isnumeric())
# True

isdigit() : 해당 str이 숫자 '모양'으로만 이루어졌을 때 True
isdemical() : 해당 str이 int형으로 반환가능할 때 True
isnumberic() : 해당 str이 제곱근,분수,거듭제곱 등으로도 표현가능한 숫자일때 True

의 차이가 있다는 것을 알게 되었습니다.

감사합니다.

profile
https://github.com/min731

0개의 댓글