미경이 스터디 6.10

코변·2022년 6월 9일
0
post-thumbnail

Photo by Pietro Mattia on Unsplash

다트게임

def solution(dartResult):
    string_grade = {
        'S' : '**1',
        'D' : '**2',
        'T' : '**3',}
    mark_grade = ['*', '#']
    answer = []
    dartResult = list(dartResult)
    for idx, point in enumerate(dartResult):
        if point in mark_grade:
            if point == '*':
                answer[-2:] = [x*2 for x in answer[-2:] ]
            else:
                answer[-1:] = [x *-1 for x in answer[-1:]]
        elif point in string_grade.keys():
            if (dartResult[idx-2] + dartResult[idx-1]).isdigit():
                answer.append(eval((dartResult[idx-2] + dartResult[idx-1]) + string_grade[point]))
            else:
                answer.append(eval(dartResult[idx-1]+ string_grade[point]))
    return sum(answer)

내가 정리한 조건

  1. 다트 리절트에는 숫자와 그 숫자에 얼마를 제곱할지가 문자열로 담긴다
  2. 숫자는 1부터 10까지의 수이다.
  3. 문자열은 각각 S , D, T 로 순서대로 1제곱 2제곱 3제곱이다.
  4. * 표시는 바로 직전 점수와 지금 점수에 2를 곱한다.
  5. 만약 첫번째 숫자에 * 표시가 나왔다면 첫번째 숫자만 2를 곱한다.
  6. * 표시는 중복 가능하다.
  7. # 표시는 지금 점수만 -1로 만든다.
  8. * # 중첩이 가능하다
  9. 그러나 두 표시가 한 점수에 중복으로 나오진 않는다.

이를 토대로 처음에 접근한 방식은 다음과 같다.

  1. * # 표시를 지움과 동시에 숫자에 접근해 값을 바꾼다.
    -> 인덱스로 값에 접근하려고 하니까 10이라는 두자리 숫자가 나오기도 하고 그리고 *을 지우다보면 인덱스가 달라져 for문 안에서 길을 잃을 것 같아서 이 가설은 지웠다.
  2. (문자열은 특정 인덱스에 값을 담는게 안되니까) answer라는 빈 리스트를 초기화하고 거기 안에 변경된 값을 담아보자
    -> 문자열 값을 조회해서 앞 숫자와 계산되는 로직을 먼저 짜고 answer에 담아보았다. 이제 * # 이 놈들을 어떻게 하지?
  3. answer에 이미 담긴 점수를 활용하자!
    -> 담긴 점수를 슬라이싱으로 가져오면 마크들이 처음에 나오는 상황에서도 대처가 가능하고 일일이 확인할 필요가 없다.
    -> eval함수를 통해서 문자열로 이루어진 계산식의 결과를 얻을 수 있다.
  4. 10을 생각못했네!
    -> 10이 있다는 사실에 주의하자고 생각은 해놓고 막상 코딩을 하다보니 까먹었다. 마지막 eval식에서 10을 생각하지않고 문제를 풀었더니 터무니없는 수가 나와서 당황했다.
    -> 문자열의 전 인덱스 값과 전전 인덱스값을 묶어 isdigit에 넣고 숫자인지 검사한 후에 숫자라면 10이기 때문에 10으로 값을 넣어주고 아니라면 전 인덱스의 값만 넣어주는 로직을 짰다.
    -> 10을 검사하는 로직이 너무 못생겨서 슬프다. 10이라는 예외변수 하나 때문에 저 if문을 계속 돌려야 한다는게 너무 비효율적이라고 생각한다. 레벨1 모든 문제를 다 풀고나면 내가 고치고 싶다고 했던 코드들을 묶어서 한 번 고치려고 한다.
profile
내 것인 줄 알았으나 받은 모든 것이 선물이었다.

0개의 댓글