품생품사(品生品死)

소프트웨어 품질에 살고 품질에 죽는 그런 평범한 일상 블로그

TESTING/PROGREMING

[자바스크립트 코딩 - Chap.2] 실습 거스름돈 구하기 문제 풀어보기

품생품사(品生品死) 2020. 12. 5. 00:30
반응형

자바스크립트 예제 : 거스름돈 구하기

파이썬으로도 구현했었던 문제입니다.

이번에는 자바스크립트로 프로그래밍을 해보려 합니다.

 

한번 도전해 보시죵.

 

문제

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

예를 들어 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장

 

힌트

1. 의미 있는 변수 이름을 사용해 주세요!

예를 들어서 5만원, 1만원, 5천원, 1천원을 셀 때는

  • fiftyThousand
  • tenThousand
  • fiveThousand
  • oneThousand

또는

  • fiftyCount
  • tenCount
  • fiveCount
  • oneCount

이런 식으로 알아보기 쉬운 변수 이름을 사용하는 것이 좋습니다.

 

이게 왜 중요할까요?

 

향후 복잡한 프로그램을 짜게 되면 변수를 여기저기서 사용해야 하는데요.

그 이름이 a, b, c, d처럼 의미 없이 설정되어 있으면, 변수를 활용하기도 어렵고 프로그램의 가독성도 떨어집니다.

특히 다른 개발자와 협업을 할 때 그 문제는 더 심각해집니다.

 

2. 예를 통해 생각해 보는 것이 가장 좋습니다.

물건 가격이 33,000원인데 100,000원을 받았다면, 차액에 해당하는 67,000원을 거슬러 주어야겠죠?

 

67,000원을 거슬러 주려면 50,000원짜리 지폐 1장이 필요합니다.

1장이 필요하다는 것은 (67000 - (67000 % 50000)) / 50000을 계산함으로써 구할 수 있습니다.

그러면 67000 % 50000인 17000원이 남겠죠?

 

3. 5만원 지폐 개수를 계산하는 코드만 보여드리겠습니다.

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

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

  console.log(`50000원 지폐: ${fiftyCount}장`);
}

// 테스트 코드
calculateChange(100000, 33000)
console.log('');
calculateChange(500000, 378000)
50000원 지폐: 1장

50000원 지폐: 2장

 

모범 답안

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)

해설

예시를 통해 아이디어를 얻어 봅시다.

 

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원 지폐로 거슬러 주고 남은 금액

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)

이렇게 하니 모범 답안보다 상대적으로 코드를 유지 보수하기가 더 편리하죠?

 

 

Related References

 

코딩이 처음이라면, 코드잇

월 3만원대로 Python, JavaScript, HTML/CSS, Java 등 1,600개 이상 프로그래밍 강의를 무제한 수강하세요

www.codeit.kr:443

This is coding_000
JAVA 프로그래밍

요약 : sparta coding club, 스파르타 코딩, 코드잇, 노마드 코더, 프로그래밍, 직장인 코딩, 내일 배움 카드 코딩, 밀크티 코딩, 초등 코딩, 아이스크림 코딩, 코딩 소프트웨어, 자바 스크립트 국비 지원, 자바 스크립트 교육

728x90
반응형