[Algorithm🧬] 다트 게임

또상·2021년 12월 15일
0

Algorithm

목록 보기
11/133
post-thumbnail

문제 / 풀이.py

from functools import reduce

def solution(dartResult):
    answer = 0
    
    calculates = {'S': 1, 'D': 2, 'T': 3};
    sum = 0
    temp = []
    previous = ''
    c = ''
    

    for i in range(len(dartResult)):
        # 10 처럼 두자리 숫자가 들어올 때를 대비해서 이전 것을 저장.
        previous = c
        c = dartResult[i]
        
        # 숫자가 들어오면 일단 넣는다.
        if c.isdecimal():
            # 근데 두자리 수 인 경우 1, 10 이렇게 두번 들어가므로
            # 앞의 것을 하나 pop 하고 넣는다.
            if previous.isdecimal():
                temp.pop()
                c = previous + c # 두자리 수로 만든다.
            temp.append(int(c))
        
        # 알파벳이라면 앞에 들어간 숫자에 알파벳에 따라 제곱해준다.
        # 알파벳에 따른 숫자는 딕셔너리로 저장해둠.
        elif c.isalpha():
            temp[len(temp)-1] **= calculates[c]
            
        # #이라면 이전 점수만큼 잃어야 하므로 이전 것에 * -1
        elif c == '#':
            temp[len(temp)-1] *= -1
        
        # * 이라면 이전 두개만큼 영향을 미치는데,
        # 배열에 아직 숫자가 2개가 없는 경우는 파이썬의.. 멋진 인덱싱에 의해 *2가 두번 일어나므로,
        # if else 문으로 경우를 나누었다.
        elif c == "*":
            if len(temp) >= 2:
                temp[len(temp)-1] *= 2
                temp[len(temp)-2] *= 2
            else:
                temp[0] *= 2
    
    
    # temp를 sum 함수로 sum 변수에 합침.
    # from functools import reduce 필수.
    def sum(a, b):
        return a + b
    sum = reduce(sum, temp)
    
    return sum

뭔가 후위표기식을 이용해야겠다는 생각이 들긴 했는데, 기억이 안나서 그냥 배열로 이용했는데 이 문제는 그렇게 풀어도 충분했다. 그런데 다른 사람들 풀이를 보니...

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

정규 표현식... 진짜... 깔끔하다...



+ 수업 풀이

for (let i = 0; i < dartResult.length; i++) {
    // console.log(dartResult[i]);
    if (dartResult[i] >= 0 && dartResult[i] <=9 ) {
        if (dartResult[i] == 1 && dartResult[i+1] == 0) {
            temp = 10;
            i++;
        } else {
            temp = parseInt(dartResult[i]);
        }
    } else if (dartResult[i] == 'S'){
        answer.push(temp);
    } else if (dartResult[i] == 'D'){
        // answer.push(Math.pow(temp, 2));
        answer.push(temp**2);
    } else if (dartResult[i] == 'T'){
        // answer.push(Math.pow(temp, 3));
        answer.push(temp**3);
    } else if (dartResult[i] == '*'){
        answer[answer.length-1] *= 2
        answer[answer.length-2] *= 2
    } else if (dartResult[i] == '#'){
        answer[answer.length-1] *= -1
    }
}
for (let i = 0; i < answer.length; i++) {
    result += answer[i];
}

0124 py (정규식 풀이)

import re
from functools import reduce

def solution(dartResult):
    sum = 0
    pattern = re.compile("[0-9]+[SDT][*#]?")
    arr = []
    bonuses = {'S':1, 'D':2, 'T':3}
    options = {'#':-1, '*':2, '':1} # 다른 사람 풀이 보고 고친 것.
    
    splited = pattern.findall(dartResult)
    
    for s in splited:
        num = int(re.compile("[0-9]+").match(s).group())
        bonus = bonuses[re.compile("[SDT]").search(s).group()]
        option = re.compile("[*#]").search(s)
        option = option.group() if option != None else ''
        
        if option == '*' and len(arr) > 0:
            arr[-1] *= 2
        
        arr.append(num ** bonus * options[option])
        
        
    sum = reduce(lambda x, y: x+y, arr, sum) # 그냥 sum(arr) 하면 되넹...
    
    
    return sum

정규식을 사용하면 10을 거르는게 훨씬 쉬워질 것 같아서 정규식을 써봤다. 사실 swift 로 풀려고 했는데 정규식 메서드까지 생각할려니까 그냥 머리 터질거같아서 차라리 파이썬으로 다시 풀어보자 하고 파이썬으로 풀었다.

그리고 지금 몇번째 말하는 건지 모르겠지만... 정규식보다 match search 쓰는게 더 헷갈림.. 반은 찾아서 풀었다.

findall - 정규식 매칭되는거 모두 찾아서 배열로
re.compile(정규식).match / search - match 는 처음부터 매치되는지 찾음, search 는 매치되는 첫 인덱스 찾음 -> 여기서 문자열로 바꾸려면.group() 못찾은 경우엔 None 이라 group() 을 못써서 option 처럼 분기처리.

다른 사람의 풀이 중 찢었다고 생각한건 아래의 것. 10을 손쉽게 배열로 빼냈다. 뒤는 내 처음 풀이나 멋사에서 풀었던 풀이와 동일하다.

    dartResult = dartResult.replace('10','k')
    point = ['10' if i == 'k' else i for i in dartResult]
profile
0년차 iOS 개발자입니다.

0개의 댓글