[kata][python] 필요한 설탕봉지 갯수 구하기
- 4 mins필요한 설탕 봉지 갯수 구하기
출처: 백준 알고리즘 2839번 문제
상근이는 설탕을 배달한다.
설탕 N킬로그램을 3킬로그램 봉지와 5킬로그램 봉지에 나누어 담으려한다.
설탕 N그램이 입력으로 주어졌을때, 설탕을 담기위해 필요한 최소 봉지 갯수를 출력하라.
예를들어 설탕 18킬로그램은 3킬로짜리 봉지 6개에 담을 수도 있지만,
3킬로짜리 봉지 1개와 5킬로짜리 봉지 3개에 담아 총 4개의 봉지만 사용할수도 있다.
만약 N그램이 딱 맞아떨어지지 않는 경우는 -1을 출력하라.
입력
18
4
6
출력
4
-1
2
내 풀이
1 import sys
2
3 bag_5 = 0
4 bag_3 = 0
5 N = int(sys.stdin.readline())
6
7 bag_5 = N // 5
8 remains = N % 5
9
10 if remains == 0:
11 print(bag_5)
12 elif remains % 3 == 0:
13 bag_3 = 1
14 print(bag_5 + bag_3)
15 elif bag_5 == 0:
16 print(-1)
17 else:
18 for i in range(bag_5):
19 bag_5 -= 1
20 remains += 5
21
22 if remains % 3 == 0:
23 bag_3 += (remains // 3)
24 print(bag_5 + bag_3)
25 break
26 elif bag_5 == 0:
27 print(-1)
우선 5킬로그램짜리 봉지에 담을 수 있을만큼 다 담는다.
그리고 몫과 나머지를 각각 변수에 저장한다 (7, 8)
나머지가 없다면 5킬로그램 봉지에 다 들어간 것이므로 bag_5를 그대로 출력한다. (10~11)
나머지가 3으로 나누어떨어진다면, 이 때의 몫(1)을 bag_5에 더해서 출력한다. (12~14)
5로 나눈 몫이 0이라면, -1을 출력한다. (15)
그 외의 경우는 5로 나누었을때 몫이 1 이상이며 나머지가 3이 아닌 경우이므로,
몫을 하나씩 빼고 나머지에 5씩 더해주면서, 나머지가 3으로 나누어지는지 테스트한다.
나머지가 3으로 나누어떨어진다면, 당시의 몫을 bag_3에 넣고, bag_5와 더해서 출력해준다. (22~25)
몫이 바닥날때까지 3으로 나누어 떨어지는 값이 발견되지 않는다면, -1을 반환한다. (26~27)
다른사람 풀이
1 A = int(input())
2 N = A % 5
3 if A in [4, 7]:
4 print(-1)
5 elif N == 0:
6 print(A // 5)
7 elif N in [1, 3]:
8 print((A // 5) + 1)
9 elif N in [2, 4]:
10 print((A // 5) + 2)
설탕의 무게를 5로 나눈 나머지를 N이라는 변수에 저장.
4와 7의 경우에는 나누어떨어지지 않으므로 -1을 출력했다.
나머지가 0이면 몫을 그대로 출력.
나머지가 1 또는 3이면 봉지의 갯수를 하나 더해서 출력.
나머지가 2 또는 4이면 봉지의 갯수를 두 개 더해서 출력했다.
분석
조금 뜬금 없을 수도 있는데,
난 이 문제를 풀며 테스트 코드 작성의 중요성을 잠깐 되새김질해보았다.
실제 상황을 생각해보니 4와 7을 제외한 숫자는 모두 3과 5의 조합으로 딱 떨어지게 나눌 수 있었다.
그리고 5로 나누었을때 나머지가 1 또는 3인 경우는 무조건 봉지가 1개씩 더해지고,
나머지가 2 또는 4인 경우는 무조건 봉지가 2개씩 더해졌다.
즉, 규칙이 있는 것이다.
실제로 이 프로그램이 완성했을때 동작할만한 몇 가지 테스트 케이스를 미리 만들어보고,
그 테스트 케이스를 분석해 규칙을 발견했다면 더 깔끔한 프로그램을 짤 수 있지 않았을까 생각했다.
근데 다시 생각해보니 이 문제는 과정에서 규칙을 찾을 수 있지만,
입력과 출력만 두고 보았을때에는 특별한 상관관계가 보이지 않는다.
즉, 몇가지 케이스에 대한 흐름을 간단히 종이에 적어보는 것으로 규칙을 어렵지않게 발견할 수 있었다.
그렇다면 테스트 케이스가 단순히 입출력을 표현하는 수준이 아니라,
그 과정에 대해서도 기술할 수 있다면 더 좋을 것 같다는 생각이 들었다.
물론 세밀한 과정을 전부 기술하는 것은 원본 코드를 중복 작성하는 것과 다를 바 없어지므로,
적절한 수준으로 테스트 코드를 세분화해야할 것이다.
발생할 수 있는 여러 이슈에대해 조금 더 유연하게 대처할 수 있지 않을까 하는 생각이 들었다.