본문 바로가기

코딩테스트

[JavaScript] 거스름돈 구하기

자바스크립트 문제 풀이 - 거스름돈 구하기

Floor 함수, 반복문 등을 활용하여 문제 풀이

 


🔍 문제

 

현태는 현명하게 거스름돈을 계산해 주는 프로그램을 만들려고 합니다.

예를 들어 33,000원짜리 물건을 사기 위해 100,000원을 냈다면,

  • 50,000원 1장
  • 10,000원 1장
  • 5,000원 1장
  • 1,000원 2장

이런 식으로 '가장 적은 수'의 지폐를 거슬러 주는 것입니다.

방금 같은 경우에는 총 5장을 거슬러 준 거죠.

우리는 calculateChange라는 함수를 작성하려고 하는데요.

이 함수는 지불한 금액을 나타내는 payment와 물건의 가격을 나타내는 cost를 파라미터로 받습니다.

주어진 코드에 이어서 깔끔하게 프로그램을 작성해 보세요.

함수 모두 작성하고 프로그램을 실행하면 아래와 같은 결괏값이 콘솔에 출력되어야 합니다.

50000원 지폐: 1장
10000원 지폐: 1장
5000원 지폐: 1장
1000원 지폐: 2장

50000원 지폐: 2장
10000원 지폐: 2장
5000원 지폐: 0장
1000원 지폐: 2장

 


 

🔍 내가 푼 방식

function calculateChange(payment, cost) {
  // 코드를 작성해 주세요.
  let change = payment - cost;
  let fiftyThousand = (change - (change % 50000)) / 50000;
  if(fiftyThousand != ''){
    console.log(`50000원 지폐: ${fiftyThousand}장`);
  }else{
    console.log(`50000원 지폐: 0장`);
  }

  let change2 = change - 50000 * fiftyThousand;
  let tenThousand = (change2 - (change2 % 10000)) / 10000;
  if(tenThousand != ''){
    console.log(`10000원 지폐: ${tenThousand}장`);
  }else{
    console.log(`10000원 지폐: 0장`);
  }
  
  let change3 = change2 - 10000 * tenThousand;
  let fiveThousand = (change3 - (change3 % 5000)) / 5000;
  if(fiveThousand != ''){
    console.log(`5000원 지폐: ${fiveThousand}장`);
  }else{
    console.log(`5000원 지폐: 0장`);
  }
  
  let change4 = change3 - 5000 * fiveThousand;
  let oneThousand = (change4 - (change4 % 1000)) / 1000;
  if(oneThousand != ''){
    console.log(`1000원 지폐: ${oneThousand}장`);
  }else{
    console.log(`1000원 지폐: 0장`);
  }
  
}

 


 

🔍정답 해설

 

예시를 통해 아이디어를 얻어 봅시다. 33,000원 하는 물건을 사는데 100,000원을 받았다고 가정할게요.

그러면 67,000원을 거슬러 줘야 하는데, 어떻게 해야 최소 지폐 개수로 거슬러 줄 수 있을까요?

조금만 생각을 해보면 금방 알아낼 수 있을 텐데요. 가장 큰 지폐부터 넣어 보면 됩니다.

그러니까 처음에는 50,000원 지폐 몇 장을 거슬러 줄 수 있는지 보는 거죠.

50,000원 지폐로 거슬러 주는 것이 다른 작은 지폐로 거슬러 주는 것보다 무조건 좋기 때문에, 50,000원 지폐부터 보는 것입니다. 67,000원에는 50,000원이 한 번만 들어가기 때문에, 67,000원에서 50,000원을 빼서 17,000원이 남습니다.

그다음으로 큰 10,000원 지폐를 봅시다. 17,000원에 10,000원이 몇 번 들어가나요? 한 번 들어가죠?

그러면 17,000원에서 10,000원을 빼서 7,000원이 남습니다.

그다음으로 큰 5,000원 지폐를 봅시다. 7,000원에 5,000원이 몇 번 들어가나요? 한 번 들어가죠?

그러면 7,000원에서 5,000원을 빼서 2,000원이 남습니다.

마지막으로 1,000 지폐를 봅시다. 2,000원에 1,000원이 몇 번 들어가나요? 두 번 들어갑니다.

 

결론적으로,

  • 50,000원 1장
  • 10,000원 1장
  • 5,000원 1장
  • 1,000원 2장

이렇게 되는 것입니다.

 

거스름돈 총액

우리가 거슬러 줘야 하는 총액은 얼마인가요? 받은 돈에서 물건 가격을 빼면 되겠죠?

change = payment - cost;  // 거스름돈 총액

 

몇 장을 거슬러 줘야 할까?

67,000원을 거슬러 줘야 하면, 50,000원 지폐는 몇 장 주면 될까요? 67,000원에 50,000원이 몇 번 들어가는지 확인하면 되죠?

천천히 생각해보면,

거스름돈에서, 50000으로 나눠떨어지지 않는 나머지를 뺀 다음, 다시 50000을 나눠주면

거스름돈을 지폐 금액만큼 나눠준 개수를 얻을 수 있습니다.

(change - (change % 50000)) / 50000;  // 50000원 지폐 개수

 

혹은 Math객체의 floor 메소드를 이용하면 좀 더 간단하게 구할 수 있는데요.

floor 메소드는 주어진 숫자와 같거나 작은 정수 중에서 가장 큰 수를 반환하기 때문에, 버림 나눗셈과 같은 결과를 얻을 수 있습니다.

Math.floor(change / 50000); // 500000원 지폐 개수

 

거슬러 주고 얼마가 남았을까?

67,000원에서 50,000원으로 최대한 거슬러 주고 남은 금액은 17,000원입니다.

다음 지폐 개수를 계산할 때 새롭게 계산할 수도 있겠지만,

거슬러 주고 남은 값을 바로 계산해서 change에 할당해주면,

좀 더 수월하게 다음 지폐 개수를 계산할 수 있겠죠?

change = change - 50000 * fiftyCount;  // 50,000원 지폐로 거슬러 주고 남은 금액

 

🔍 모범답안

function calculateChange(payment, cost) {
  // 코드를 작성해 주세요.
  let change = payment - cost; // 거스름돈 총액

  const fiftyCount = (change - (change % 50000)) / 50000;
  change = change - 50000 * fiftyCount;

  const tenCount = (change - (change % 10000)) / 10000;
  change = change - 10000 * tenCount;

  const fiveCount = (change - (change % 5000)) / 5000;
  change = change - 5000 * fiveCount;

  const oneCount = (change - (change % 1000)) / 1000;
  change = change - 1000 * oneCount;

  console.log(`50000원 지폐: ${fiftyCount}장`);
  console.log(`10000원 지폐: ${tenCount}장`);
  console.log(`5000원 지폐: ${fiveCount}장`);
  console.log(`1000원 지폐: ${oneCount}장`);
}

// 테스트 코드
calculateChange(100000, 33000);
console.log('');
calculateChange(500000, 378000);

 

floor 메소드를 활용한다면,

function calculateChange(payment, cost) {
  // 코드를 작성해 주세요.
  let change = payment - cost; // 거스름돈 총액

  const fiftyCount = Math.floor(change / 50000);
  change = change - 50000 * fiftyCount;

  const tenCount = Math.floor(change / 10000);
  change = change - 10000 * tenCount;

  const fiveCount = Math.floor(change / 5000);
  change = change - 5000 * fiveCount;

  const oneCount = Math.floor(change / 1000);
  change = change - 1000 * oneCount;

  console.log(`50000원 지폐: ${fiftyCount}장`);
  console.log(`10000원 지폐: ${tenCount}장`);
  console.log(`5000원 지폐: ${fiveCount}장`);
  console.log(`1000원 지폐: ${oneCount}장`);
}

// 테스트 코드
calculateChange(100000, 33000);
console.log('');
calculateChange(500000, 378000);

 

🔍 응용답안

자, 그런데 코드를 다시 보면 지폐 개수를 셀 때 지폐 단위를 제외하면, 똑같이 반복된 부분들이 보이는데요.

심지어 지폐 단위 숫자도 똑같이 세 번, floor메소드를 쓰더라도 두 번은 반복되고 있습니다.

코드를 작성할 때 실수로 어느 한 곳에서 오타를 낼 수도 있고,

혹은 다 작성했는데 전체적으로 코드의 동작을 수정해야 할 수도 있기 때문에,

이렇게 똑같이 반복적으로 똑같이 동작해야 하는 코드들은 실제로 매번 반복해서 작성하는 것보다는 함수나 반복문을 통해 최대한 반복을 줄일 방법을 찾는 것이 좋습니다.

그래서 상황에 따라 변해야 하는 부분(지폐 단위)은 파라미터를 활용하고,

똑같이 반복되는 패턴을 추려서 동작 부분을 채운 함수를 작성해보면 다음과 같이 작성할 수 있습니다.

 

function calculateChange(payment, cost) {
  // 코드를 작성해 주세요.
  let change = payment - cost; // 거스름돈 총액

  function billCounting(amount) {
    const count = (change - (change % amount)) / amount;
    change = change - amount * count;
    return count;
  }

  const fiftyCount = billCounting(50000);
  const tenCount = billCounting(10000);
  const fiveCount = billCounting(5000);
  const oneCount = billCounting(1000);

  console.log(`50000원 지폐: ${fiftyCount}장`);
  console.log(`10000원 지폐: ${tenCount}장`);
  console.log(`5000원 지폐: ${fiveCount}장`);
  console.log(`1000원 지폐: ${oneCount}장`);
}

calculateChange(100000, 33000);
console.log('');
calculateChange(500000, 378000);

 

 

floor 메소드를 활용하는 게 좀 더 좋을 것 같다는 판단으로 코드를 수정해야 될 상황이라고 가정해 봅시다.

모범 답안과 같은 상황에서는 코드를 4줄을 고쳤어야 했는데,

이렇게 함수로 작성해두면, 함수 내부의 동작 부분에서 딱 한 줄만 고치면 됩니다.

function calculateChange(payment, cost) {
  // 코드를 작성해 주세요.
  let change = payment - cost; // 거스름돈 총액

  function billCounting(amount) {
    const count = Math.floor(change / amount);
    change = change - amount * count;
    return count;
  }

  const fiftyCount = billCounting(50000);
  const tenCount = billCounting(10000);
  const fiveCount = billCounting(5000);
  const oneCount = billCounting(1000);

  console.log(`50000원 지폐: ${fiftyCount}장`);
  console.log(`10000원 지폐: ${tenCount}장`);
  console.log(`5000원 지폐: ${fiveCount}장`);
  console.log(`1000원 지폐: ${oneCount}장`);
}

calculateChange(100000, 33000);
console.log('');
calculateChange(500000, 378000);

상대적으로 코드를 유지 보수하기가 더 편리한 코드가 된다 .

 

 

 

출처 - 코드잇