yooom 2023. 9. 17. 17:20
문제 설명
카카오톡 게임별의 하반기 신규 서비스로 다트 게임을 출시하기로 했다. 다트 게임은 다트판에 다트를 세 차례 던져 그 점수의 합계로 실력을 겨루는 게임으로, 모두가 간단히 즐길 수 있다. 갓 입사한 무지는 코딩 실력을 인정받아 게임의 핵심 부분인 점수 계산 로직을 맡게 되었다. 다트 게임의 점수 계산 로직은 아래와 같다. 다트 게임은 총 3번의 기회로 구성된다. 각 기회마다 얻을 수 있는 점수는 0점에서 10점까지이다. 점수와 함께 Single(S), Double(D), Triple(T) 영역이 존재하고 각 영역 당첨 시 점수에서 1제곱, 2제곱, 3제곱 (점수1 , 점수2 , 점수3 )으로 계산된다. 옵션으로 스타상(*) , 아차상(#)이 존재하며 스타상(*) 당첨 시 해당 점수와 바로 전에 얻은 점수를 각 2배로 만든다. 아차상(#) 당첨 시 해당 점수는 마이너스된다. 스타상(*)은 첫 번째 기회에서도 나올 수 있다. 이 경우 첫 번째 스타상(*)의 점수만 2배가 된다. (예제 4번 참고) 스타상(*)의 효과는 다른 스타상(*)의 효과와 중첩될 수 있다. 이 경우 중첩된 스타상(*) 점수는 4배가 된다. (예제 4번 참고) 스타상(*)의 효과는 아차상(#)의 효과와 중첩될 수 있다. 이 경우 중첩된 아차상(#)의 점수는 -2배가 된다. (예제 5번 참고) Single(S), Double(D), Triple(T)은 점수마다 하나씩 존재한다. 스타상(*), 아차상(#)은 점수마다 둘 중 하나만 존재할 수 있으며, 존재하지 않을 수도 있다. 0~10의 정수와 문자 S, D, T, *, #로 구성된 문자열이 입력될 시 총점수를 반환하는 함수를 작성하라.

 

풀이
def divider(string):   # 문자를 3개 구역으로 나눈다
    arr = list(string)
    cal = []
    print(cal)
    for i in range(3):
        split = []
        split_word = ''
        if arr[-1] != '*' and arr[-1] != '#':
            for j in range(2):
                split += arr.pop()
            split.reverse()
        else:
            for j in range(3):
                split += arr.pop()
            split.reverse()
        split_word = ''.join(split)
        cal.append(split_word)
    cal.reverse()
    return cal

def solution(dartResult):
    arr = divider(dartResult)
    for i in arr:
        for j in i:
            if j.isdigit():  # 중도포기
                
        ...

이런 식으로 작성하려다가. 어차피 조건 복잡해질 거. 앞에서부터 전부 조건문 붙여버리는 게 낫지 않을까 생각했다.

def solution(dartResult):
    arr = dartResult
    cal = []
    n = ''
    
    for i in arr:
        if i == '0' and n == '1':
            n = 10   # 앞에 1이 나오고, 0이 나오면 10을 반환
        elif i.isdigit():
            n += i   # 이 식만 적어두면 3번 케이스에서 오류가 난다. 0이 10이 됨.
        elif i == 'S':
            cal.append(int(n)**1)
            n = ''  # n을 초기화
        elif i == 'D':
            cal.append(int(n)**2)
            n = ''
        elif i == 'T':
            cal.append(int(n)**3)
            n = ''
        elif i == '#':
            cal[-1] = cal[-1]*(-1)
        elif i == '*':
            if len(cal) == 1:
                cal[-1] = cal[-1]*2  # *가 첫 번재에 나오면 첫 번째 수만
            else:
                cal[-1] = cal[-1]*2  #*가 그 외에서 나오면 최근 2개 갱신
                cal[-2] = cal[-2]*2
    print(cal)
    return sum(cal)

이게 맞나....일단 정답은 맞다.

카카오 신입 공채 1차 코딩 테스트에서 7 문제 중 2번 째로 쉬운 문제다. 프로그래밍 하는 사람들 다들 대단하다..

 

내가 본 정답 중에 가장 깔끔했던 정답은

def solution(dartResult):
    point = []
    answer = []
    dartResult = dartResult.replace('10','k')   # 10을 k로 변환.
    point = ['10' if i == 'k' else i for i in dartResult] 
    print(point) #2번 케이스, ['1', 'D', '2', 'S', '#', '10', 'S'] 로 묶인다

    i = -1
    sdt = ['S', 'D', 'T']
    for j in point:
        if j in sdt :
            answer[i] = answer[i] ** (sdt.index(j)+1)  # SDT를 인덱스로 ^2, ^3 을 묶어 표현
        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   #이런 방식으로 이중 for 구문을 흉내낼 수 있음
    return sum(answer)

10을 하나의 값으로 묶는 방법,  SDT를 인덱스로 참조하는 방법을 배워간다 !

 

 

출처

https://school.programmers.co.kr/learn/courses/30/lessons/17682

 

프로그래머스

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

programmers.co.kr

 

728x90