[Python] 17215번: 볼링 점수 계산 풀이

두비니

·

2022. 2. 21. 10:54

 

 

백준 풀이

13783번: 합 구하기 풀이


 

볼링? 절 대 못 참 아

문제 Link: https://www.acmicpc.net/problem/17215

 

17215번: 볼링 점수 계산

첫째 줄에 각 기회마다 소현이가 쓰러뜨린 볼링핀의 개수가 공백없이 주어진다. 이때 스트라이크는 S, 스페어는 P, 핀을 하나도 못 쓰러뜨린 것은 -으로 주어진다.

www.acmicpc.net

 

문제 설명

 

단순하게 볼링 점수 계산을 하는 프로그램을 만드는 것입니다. 저는 볼링을 쳐본적이 있어서 따로 점수 계산에 대한 이해가 필요 없었지만, 볼링 점수 체계에 대해서 잘 모르시는 분은 참고 부탁드립니다.

참고: https://blog.naver.com/PostView.nhn?isHttpsRedirect=true&blogId=jababa74&logNo=40110841989 

 

볼링 점수 계산 하는법

볼링핀은 처음에 10개가 서 있습니다. 우리는 이 핀들을 공을 투구해서 넘기는 숫자에 따 라 점수로 계산 ...

blog.naver.com

 

 

일단 기본적으로 볼링은 스페어나 스트라이크가 발생하면, 보너스 점수가 스페어/스트라이크가 발생한 라운드의 점수로 추가됩니다. 따라서 저는 길이가 10인 score배열을 통해 점수를 관리했고, 마지막에 배열의 합을 반환하도록 함수를 구현했습니다.

 

저는 이 프로그램을 다음과 같이 구현했습니다.

1. 단순 합계 시스템 구현

2. 스트/스페어 보너스 시스템 추가

3. 10라운드 보너스 시스템 추가

 

의 방식을 따랐습니다. 각각의 내용을 코드와 함께 설명하겠습니다.

1. 단순 합계 시스템 구현

 

일단 보너스 없이 단순히 점수만 더해주는 틀을 먼저 짰습니다. 이건 그냥 case를 나눠주면 되니깐 문제될 게 없죠?

 

def get_score(result):
    score = []
    # cnt : round, cnt_flag : 0; 1st shot | 1; 2nd shot
    cnt, cnt_flag = 0, 0
    for s in result:
        if s == "S":
            score.append(10)
            cnt += 1
        elif s == "P":
            score[-1] = 10
            cnt += 1
            cnt_flag = 0
        elif s == "-":
            if cnt_flag == 1:
                cnt += 1
                cnt_flag = 0
            else:
                score.append(0)
                cnt_flag = 1
        else:
            int_score = int(s)
            if cnt_flag == 1:
                score[-1] += int_score
                cnt += 1
                cnt_flag = 0
            else:
                cnt_flag = 1
                score.append(int_score)
        print(cnt, sum(score), score)
    return sum(score)

if __name__ == "__main__":
    result = input()
    score = get_score(result)
    print(score)

 

이렇게 구현하면 보너스 없이 그 라운드의 점수들만 잘 계산이 되는 것을 확인할 수 있습니다.

변수 설명을 하자면, cnt는 라운드를 뜻하는 것이고, cnt_flag는 각 라운드마다 두 번의 기회가 주어지니 그걸 구분하기 위해서 사용했습니다.

 

2. 스트/스페어 보너스 시스템 추가

 

다음은 스트라이크 및 스페어를 쳤을 때, 보너스 시스템을 추가하여야 합니다.

쉽게 이야기하면 스트라이크를 쳤을 때는 그 다음으로 발생하는 2번의 점수가 보너스로, 스페어가 발생했을 때는 그 다음으로 발생하는 1번의 점수가 보너스로 추가되게 됩니다. 따라서 이는 따로 flag라는 배열을 통해 관리를 했습니다.

글을 쓰면서 설명을 하다보니 다른 변수로 설정하는게 더 나았을 것 같네요.

 

def get_score(result):
    score = []    
    # flag - 2: strike, 1: spare, 0: nothing
    flag = [0] * 12
    # cnt : round, cnt_flag : 0; 1st shot | 1; 2nd shot
    cnt, cnt_flag = 0, 0
    for s in result:
        if s == "S":            
            if cnt >= 2 and flag[cnt-2] != 0:
                score[-2] += 10
                flag[cnt-2] -= 1
            if cnt >= 1 and flag[cnt-1] != 0:
                score[-1] += 10
                flag[cnt-1] -= 1
            score.append(10)
            flag[cnt] = 2
            cnt += 1
        elif s == "P":
            if cnt >= 1 and flag[cnt-1] != 0:
                score[-2] = score[-2] + 10 - score[-1]
                flag[cnt-1] -= 1
            score[-1] = 10
            cnt += 1
            cnt_flag = 0
        elif s == "-":
            if cnt >= 1 and flag[cnt-1] != 0:
                flag[cnt-1] -= 1
            if cnt_flag == 1:
                cnt += 1
                cnt_flag = 0
            else:
                score.append(0)
                cnt_flag = 1
        else:
            int_score = int(s)
            if cnt >= 1 and flag[cnt-1] != 0:
                score[-1] += int_score
                flag[cnt-1] -= 1
            if flag[cnt] != 0:
                score[-1] += int_score
                flag[cnt] -= 1
            if cnt_flag == 1:
                score[-1] += int_score
                cnt += 1
                cnt_flag = 0
            else:
                cnt_flag = 1
                score.append(int_score)
        print(flag)
        print(cnt, sum(score), score)
    return sum(score)

if __name__ == "__main__":
    result = input()
    score = get_score(result)
    print(score)

 

아무튼 이 코드를 실행시키면 보너스 점수들이 정상적으로 잘 더하고 지워지는 것을 확인할 수 있습니다. 

 

 

다만 마지막 10라운드의 경우에는 보너스 점수가 적용이 되지 않습니다. 따라서 마지막으로 이에 대한 예외 처리를 해줍시다.

 

 

3. 10라운드 보너스 시스템 추가

 

10라운드 보너스 시스템에 대해서는, 마지막 라운드에서는 보너스 플래그가 추가되지 않도록 처리했습니다. 내용들을 찍어보면서 확인하면 더 보기 쉬울 것 같습니다.

def get_score(result):
    score = []    
    # flag - 2: strike, 1: spare, 0: nothing
    flag = [0] * 12
    # cnt : round, cnt_flag : 0; 1st shot | 1; 2nd shot
    cnt, cnt_flag = 0, 0
    for s in result:
        if s == "S":
            if cnt >= 2 and flag[cnt-2] != 0:
                score[-2] += 10
                flag[cnt-2] -= 1
            if cnt >= 1 and flag[cnt-1] != 0:
                score[-1] += 10
                flag[cnt-1] -= 1
            score.append(10)
            if cnt <= 8:
                flag[cnt] = 2
            cnt += 1
        elif s == "P":
            if cnt >= 1 and flag[cnt-1] != 0:
                score[-2] = score[-2] + 10 - score[-1]
                flag[cnt-1] -= 1
            score[-1] = 10
            if cnt != 9:
                flag[cnt] = 1
            cnt += 1
            cnt_flag = 0
        elif s == "-":
            if cnt >= 1 and flag[cnt-1] != 0:
                flag[cnt-1] -= 1
            if cnt_flag == 1:
                cnt += 1
                cnt_flag = 0
            else:
                score.append(0)
                cnt_flag = 1
        else:
            int_score = int(s)
            if cnt >= 2 and flag[cnt-2] != 0:
                score[-2] += int_score
                flag[cnt-2] -= 1
            if cnt >= 1 and flag[cnt-1] != 0:
                score[-1] += int_score
                flag[cnt-1] -= 1
            if flag[cnt] != 0:
                score[-1] += int_score
                flag[cnt] -= 1
            if cnt_flag == 1:
                score[-1] += int_score
                cnt += 1
                cnt_flag = 0
            else:
                cnt_flag = 1
                score.append(int_score)
        print("flag:", flag)
        print(cnt, sum(score), score)
    return sum(score)

if __name__ == "__main__":
    result = input()
    score = get_score(result)
    print(score)

 

검수용 test set

9-8P72S9P-9S-P9-SS8 : 150
SSSSSSSSSSSS : 300
SSSSSSSSSS4P : 284
9-449P44-5S9P8P9P7PS : 138

이 문제를 풀면서 중간에 오답이 발생하는 경우가 많이 생길텐데, 저는 저 4가지 테스트 케이스에 대해서 해결했더니 정답이 나왔습니다. 

전체 코드는 깃허브에도 올려놨으니 참고하실 분들은 참고하시면 좋을 것 같습니다. (스타도..ㅎ)

 

 

full code(github): https://github.com/dubini0/progamming_stuff/blob/main/baekjoon/%5B3%5D%2015000-19999/17215_%EB%B3%BC%EB%A7%81%20%EC%A0%90%EC%88%98%20%EA%B3%84%EC%82%B0.py

 

GitHub - dubini0/progamming_stuff: programming examples

programming examples. Contribute to dubini0/progamming_stuff development by creating an account on GitHub.

github.com

 

 

끝!