티스토리 뷰

반응형

오늘의 백준 문제는 4673번이다. 

이런식의 문제를 푸는 로직에서 종종 막혔던 것 같아 정리해보고자 한다. 

두가지 풀이법을 보았는데 1번 풀이는 처음부터 접근하면서 푸는 풀이법이라 이해하는데 있어서 수월했고,

2번 풀이는 1번보다 직관적이고 깔끔한 풀이법인 것 같다. 

 

이번에는 console.log()를 단계별로 출력해보며 누구나 100%이해할 수 있는 풀이법을 적고자 한다. 

 

 

Answer 1.

* 정수 n은 1부터 10000까지의 숫자이나, 필자는 콘솔로 출력하기에는 숫자가 너무 많아 임시로 n 의 범위를 10까지로 하고 풀어보았다 .

백준 문제 답안 제출할 때는 i <= 10; 은 i <= 10000; 으로, Array(11)는 Array(10001)로 바꿔주면 된다. 

 

solution();

function d(n) {
  let sum = 0;
  const strNum = String(num);
  for (let i = 0; i < strNum.length; i++) {
    sum += +strNum[i];
  }
  return n + sum;
}

function solution() {
  const arr = Array(11).fill(0);
  for (let i = 1; i <= 10; i++) {
    const ans = d(i);
    //console.log(ans);
    if (ans <= 10) {
      arr[ans]++;
    }
  }

  for (let i = 0; i <= 10; i++) {
    if (arr[i] === 0) {
      console.log(i);
    }
  }
}

 

 

1-1. function d(n) 함수 만들기 

먼저 문제 순서에 맞게 d(n)의 함수를 만든다. 숫자를 문자로 만들어 각 숫자 자릿수를 더한 sum 을 구하고 num 과 sum 을 더 한 값을 리턴한다. 

 

d(10); // return 1 (1 + 0)

function d(n) {
  let sum = 0;
  const strNum = String(n);
  for (let i = 0; i < strNum.length; i++) {
    sum += +strNum[i];
    
  }
  return n + sum;
}

d(10);으로 함수를 실행시켜보면 각 자리 수를 더한 값(1 + 0) 인 1이 출력된다. 

 

 

 

1-2. 11개의 배열 만들기 - console.log(arr);

셀프넘버를 출력하기 위한 solution()를 만들었다. 

그 안에 우선 11개의 index가 각각 0으로 채워진 배열 arr를 만든다. 

 

 const arr = Array(11).fill(0);
 // console.log(arr);

[  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ]

 

 

 

1-3. d(i) 출력하기 - console.log(`d(${i}): `, ans); 

for문으로 i의 범위를 1-10까지 정하고, ans이라는 상수변수를 만들어 d(i)를 출력한다.

 

for (let i = 1; i <= 10; i++) {
    const ans = d(i);
    // console.log(`d(${i}):  `, ans);
  }

 console.log(`d(${i}): `, ans); //

d(1):   2
d(2):   4
d(3):   6
d(4):   8
d(5):   10
d(6):   12
d(7):   14
d(8):   16
d(9):   18
d(10):   11

 

 

 

1-4. 출력된 d(i) 의 값들을 새로 생성한 배열 arr의 index로 넣기 - console.log(`arr :`, arr); 

 

1-3에서 나온 d(i)의 결과 값인 2, 4, 6, 8, 10, 12, 14, 16, 18, 11 이 arr[i]의 i 에 대입이되는데 이 때 i 의 범위를 10까지만 했기 때문에 d(6) ~ d(10)의 값인 12, 13, 16, 18, 11은 출력되지 않는다. 

 

따라서 arr index 11개의 배열에서  arr[2] , arr[4], arr[6], arr[8], arr[10] 에만 1씩 증가하게 된다. 

 

 const arr = Array(11).fill(0);
 
  for (let i = 1; i <= 10; i++) {
    const ans = d(i);
    if (ans <= 10) {
      arr[ans]++;
    }
  }
  // console.log(`arr :`, arr);

 

console.log(`arr :`, arr); 

// arr : [  0, 0, 1, 0, 1,  0, 1, 0, 1, 0, 1 ]

 

자, 그럼 여기서 문제를 다시 살펴보자. 

d(n)함수에서 출력된 값들은 n의 생성자가 된다. 

생성자가 없는 숫자를 셀프넘버라고 하며, 셀프넘버를 한 줄 씩 출력하는게 정답인 문제이다. 

지금 나는 arr배열에 d(n)함수로 출력된 값들를 arr배열의 index로 넣어 1씩 증가시켰음으로 arr[i] 값이 0인 으로 들어있는 index들이 셀프넘버가 되는 로직이다.

 

이해가 어렵다면 아래의 표를 참고하자.

d(i) 해당안됨 셀프넘버 d(1) = 2 셀프넘버 d(2) = 4 셀프넘버 d(3) = 6 셀프넘버 d(4) = 8 셀프넘버 d(5) =10
index 0 1 2 3 4 5 6 7 8 9 10
arr 0 0 1 0 1 0 1 0 1 0 1

 

 

 

1-5. arr 배열의 값이 0인 index 출력하기 - console.log(i);

 

1-4의 표를 참고하면 1,3,5,7,9가 답이 된다. 그럼 조건문을 통해 arr[i] 의 값이 0일 때 i를 console.log()를 통해 출력하면 된다. 

(문제의 범위는 1에서 10000까지였으므로 모든 범위는 10에서 10000으로 고쳐줘야 정답처리가 됨)

 

for (let i = 1; i <= 10; i++) {
    if (arr[i] === 0) {
      console.log(i);
    }
  }

console.log(i); 

1
3
5
7
9

 

 

Answer 2.

1번 문제풀이와 크게 다를 것은 없지만, 배열을 앞서 만들고 d(n)에 출력된 값들을 새로 만든 배열에 푸시한 후

indexOf() 메서드를 통해 답을 구하는 방식이다.  

 

solution();

function solution() {
  let arr = [];
  let ans = [];
  for (let i = 1; i <= 10; i++) {
    let sum = 0;
    let strNum = String(i);
    for (let j = 0; j < strNum.length; j++) {
      sum += +strNum[j];
    }
    let newNum = i + sum;
    arr.push(newNum);
    console.log("arr: ", newNum);
  }

  for (let i = 1; i <= 10; i++) {
    if (arr.indexOf(i) === -1) {
      console.log(i);
    }
  }
}

 

 

2-1. d(n)의 값을 담을 배열을 생성하고 d(n)을 만드는 로직을 for문을 통해 구현한다.

-console.log("newNum: ", newNum);

 

1-1과 같은 방법이지만 d(n)함수를 따로 만들지 않고 바로 출력해 newNum이라는 변수에 담았다. 

newNum은 n에 1부터 10까지 대입해 나온 d(n)의 출력값들이 된다. 

 

let sum = 0;
let strNum = String(i);
for (let j = 0; j < strNum.length; j++) {
  sum += +strNum[j];
}
let newNum = i + sum;
//console.log(newNum);
console.log("newNum: ", newNum);

newNum:  2
newNum:  4
newNum:  6
newNum:  8
newNum:  10
newNum:  12
newNum:  14
newNum:  16
newNum:  18
newNum:  11

 

 

2-2. newNum을 새로 만든 배열 arr에 넣어준다.  - console.log("arr: ", arr);

 

반복문을 통해 newNum을 새로 만든 배열 arr에 넣어(push())준다. 

 

let arr = [];
  for (let i = 1; i <= 10; i++) {
    let sum = 0;
    let strNum = String(i);
    for (let j = 0; j < strNum.length; j++) {
      sum += +strNum[j];
    }
    let newNum = i + sum;
    arr.push(newNum);
  }
  //  console.log("arr: ", arr);
console.log("arr: ", arr); //
 
[ 2,  4,  6,  8, 10, 12, 14, 16, 18, 11 ]
 
 
 
 
 

2-3. indexOf()를 사용해 배열에 없는 숫자를 출력한다. - console.log(i);


 indexOf()란?
 

const test = [2, 4, 5 , 7]; 라는 배열이 있다고 할 때 

 
test.indexOf(2);
 
// expected output: 0이 출력된다.  (2가 들어있는 index 는 0이다.)
 
tes.indexOf(1);
 
// expected output: -1 이 출력된다. (1이 들어있는 index는 없음으로 -1이 출력된다. )

 


 

이러한 indexOf()의 기능을 이용하면

d(n)의 모든 값들을 담은 arr배열에서 반복문을 만들어  arr.indexOf(1)부터 indexOf(10)까지 출력했을 때해당되는 값이 없으면 indexOf(숫자)의 숫자를 출력하게 하는 조건문을 넣어 출력하면 답이 된다. 

 

  for (let i = 1; i <= 10; i++) {
    if (arr.indexOf(i) === -1) {
      console.log(i);
    }
  }
 
console.log(i); //
 
1
3
5
7
9

 


 

첫번 째 방법도 좋지만, 확실히 쓰다보니까 두번째 방법이 설명할게 더 없어 괜찮은 풀이방식이라는 생각이 든다. 

특히 indexOf()나 배열에 새로 만들어 담는 것은 문제가 몇번 있었던 것 같아서 개념잡기에 좋은 문제라는 생각이 든다. 

 

 

 

 

Reference : Youtube 라메개발자 , velog (dragoocho.log)

 

반응형