3가지 인수를 받는다. 가진 병의 개수n, 특정 개수마다 바꿔주는 a, a만큼 받으면 특정개수만큼 돌려주는 b
세가지 인수를 통하여 교환동안 받은 콜라의 합을 구하는 것이 문제의 핵심이다.
먼저 작성한 코드
function solution(a, b, n) {
var answer = 0;
let flag = false;
for (let i = n; i>=a; i/=a){
let remain = i%a
answer += Math.floor(i/a)
i += remain
if (i> a){
flag = true
} else {
flag = false
}
}
if (flag) {
answer++
}
return answer;
}
먼저 for문으로 문제를 해결해보려 했다. 수학적으로 어떻게 계산해야 해결되는지 감이 잡히지 않아 고생을 많이 했지만
테스트 코드를 통과하였다.
이때 발생했던 문제는, for문의 마지막으로 간주된 반복단계에서 i에 remain값을 더했음에도 이미 마지막으로 간주되어 한번 더 진행하지 않는 것이었다.
그리하여 for문 외부에 flag라는 boolean변수를 만들어 각 반복마다 flag를 체크하게 하고(의도된 기능은아님) 마지막 반복에서 처리하지 못한 나머지값에 대한 계산을 외부if문을 통해 진행하게 하였다.
테스트코드는 통과하였지만 본 실행에서 1개를 제외하고 모두 실패를 받았다.
솔직히 왜 실패했는지에 대한 이유는 생각나지 않았다. 하지만, 계산에 for문이 부적합하다는 것은 느꼈다.
그래서 while(true)문과 continue를 사용하여 나머지를 관리해보고자 하였다.
두번째로 작성한 코드
function solution(a, b, n) {
var answer = 0;
//n개로 시작하여 a개를 주면 b개를 준다.
//따라서 n개를 시작부터 나머지로 잡고 시작한다.
let remain = n;
//무한정 while문이 실행되게하되, continue와 break를 적절히 사용하여
//의도에 맞는 코드를 작성한다.
while (true) {
//만약 남은 개수가 바꿔주는 최소개수보다 작다면
if (remain < a) {
//반복문을 끝낸다.
break;
}
//총합에 최소단위*돌려주는개수를 더한다.
answer += Math.floor(remain/a)*b
//남은것 = 원래에서 최소단위로 나눈 것의 나머지 + 돌려받은 개수
remain = Math.floor(remain%a) + Math.floor(remain/a)*b
}
return answer;
}
주석으로 설명이 되어있지만, 먼저 작성했던 코드는 계산하는 방식이 틀렸다. 주어진 테스트예제에는 적합한 코드였지만, 계산 방식 자체가 틀렸었다.
받은것과 나머지를 더해 그것을 최소단위로 나누어서 돌려주는 배수를 곱해야했으며 for문이 적합하지도 않았다.