Post

우아한테크코스 자바스크립트 온보딩 3번 풀어보기

문제

🚀 기능 요구 사항

배달이가 좋아하는 369게임을 하고자 한다. 놀이법은 1부터 숫자를 하나씩 대면서, 3, 6, 9가 들어가는 숫자는 숫자를 말하는 대신 3, 6, 9의 개수만큼 손뼉을 쳐야 한다.

숫자 number가 매개변수로 주어질 때, 1부터 number까지 손뼉을 몇 번 쳐야 하는지 횟수를 return 하도록 solution 메서드를 완성하라.

제한사항

  • number는 1 이상 10,000 이하인 자연수이다.

실행 결과 예시

numberresult
134
3314

접근

문제가 비교적 단순하기 때문에 아래와 같은 사고 과정을 통해 구현 목록을 정리해볼 수 있었다.

먼저 입력인 number까지의 모든 숫자를 확인해야 하기 때문에 number 배열을 생성해야 한다. 이후 이 배열을 순회하며 3, 6, 9가 들어있는 숫자를 확인하고 그 갯수 만큼 손뼉을 쳐야하는 변수를 증가시킨다.

🧑🏻‍💻 구현 목록

구현

  • 각 자릿수의 숫자를 반환하는 함수를 구현한다.
  • 숫자가 3, 6, 9인지 확인하는 함수를 구현한다.
  • 1부터 number까지 손뼉을 쳐야 하는 횟수를 반환하는 함수를 구현한다.

예외

  • 입력된 숫자가 1이상 10000이하인 자연수가 아닌 경우 예외를 발생시킨다.

고민

지금까지의 풀이는 독립적이고 재사용 가능한 함수를 정의하여 문제를 해결하는 함수형 프로그래밍 방식에 가깝다. 하지만 구현 사항이 복잡하여 함수가 많아지면 함수 간의 관계를 이해하기 어려울 수 있다. 이러한 문제는 어떻게 해결해야할까? 이번 문제에서는 먼저 기존의 방식대로 문제를 풀이한 이후 객체 지향 프로그래밍 방식으로 다시 문제를 풀어보고 두 가지 방법을 비교해보려한다.

풀이

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
const GAME = Object.freeze({ NUMBERS: [3, 6, 9] });

function isGameNumber(number) {
  return GAME.NUMBERS.includes(number);
}

function splitNumber(number) {
  return number.toString().split("");
}

function calculateGameNumber(number) {
  return splitNumber(number).reduce(
    (result, splitedNumber) =>
      isGameNumber(Number(splitedNumber)) ? result + 1 : result,
    0
  );
}

function indexArray(number) {
  return Array.from(Array(number), (_, index) => index);
}

const ErrorMessage = Object.freeze({
  ERROR_INVALIDE_TYPE: "입력된 숫자의 타입이 올바르지 않습니다.",
  ERROR_NUBER_IS_NOT_INTEGER: "입력된 숫자가 정수가 아닙니다.",
  ERROR_NUMBER_NOT_IN_RANGE: "입력된 숫자가 유효 범위 안에 존재하지 않습니다.",
});

function validateNumber(number) {
  if (typeof number !== "number") {
    throw new Error(ErrorMessage.ERROR_INVALIDE_TYPE);
  }
  if (!Number.isInteger(number)) {
    throw new Error(ErrorMessage.ERROR_NUBER_IS_NOT_INTEGER);
  }
  if (!(0 < number && number <= 10000)) {
    throw new Error(ErrorMessage.ERROR_NUMBER_NOT_IN_RANGE);
  }
}

function game(number) {
  validateNumber(number);

  return indexArray(number).reduce(
    (result, current) => result + calculateGameNumber(current + 1),
    0
  );
}

function problem3(number) {
  try {
    return game(number);
  } catch (error) {
    return error.message;
  }
}

console.log(problem3(33));

module.exports = problem3;

This post is licensed under CC BY 4.0 by the author.