프론트엔드 개발/Algorithm

프로그래머스 lv2. 다음 큰 숫자

하이고니 2023. 1. 26. 15:51

와...................................................

// 1 0000 => 1 00000  (16 => 32) *2 // 0

// 1 0001 => 1 0010   (17 => 18) +1 // 1
// 1 0010 => 1 0100   (18 => 20) +2 // 2
// 1 0011 => 1 0101   (19 => 21) +2 // 3
// 1 0100 => 1 1000   (20 => 24) +4 // 4
// 1 0101 => 1 0110   (21 => 22) +1 // 5
// 1 0110 => 1 1001   (22 => 25) +3 // 6
// 1 0111 => 1 1011   (23 => 27) +4 // 7

// 1 1000 => 1 10000  (24 => 48) *2 // 8

// 1 1001 => 1 1010   (25 => 26) +1 // 9
// 1 1010 => 1 1100   (26 => 28) +2 // 10
// 1 1011 => 1 1101   (27 => 29) +2 // 11

// 1 1100 => 1 11000  (28 => 56) *2 // 12

// 1 1101 => 1 1110   (29 => 30) +1 // 13
// 1 1110 => 1 11100  (30 => 60) *2 // 14
// 1 1111 => 1 11110  (31 => 62) *2 // 15

// 1 00000 => 1 000000 (32 => 64) *2 // 0

// 1 00001 => 1 00010 (33 => 34) +1
// 1 00010 => 1 00100 (34 => 36) +2
// 1 00011 => 1 00101 (35 => 37) +2
// 1 00100 => 1 01000 (36 => 40) +4
// 1 00101 => 1 00110 (37 => 38) +1
// 1 00110 => 1 01001 (38 => 41) +3

// 16으로 나눠서
// 나머지 0, 8, 12, 14, 15 => *2
// 나머지 1,5,9 => +1
// 나머지 2,3,10,11 => +2
// 나머지 6 => +3
// 나머지 4,7 => +4

ㅇㅣ렇게 해서 16 단위로 규칙 찾은 줄 알고 기뻐하면서 코드를 짰는데 처참히 무너지고,

이거 안되겠다 싶어서 그냥 구글링했다.. 그런데..

 

function solution(n) {
  const oneNum = n.toString(2).split("1").length;
  while (true) {
    n++;
    if (n.toString(2).split("1").length === oneNum) return n;
  }
}

1. 2진수로 바꿔서 '1'을 기준으로 끊어서 그 길이를 구한다 => 1의 개수

2. while 문 안에서 n을 1 증가시키고 n의 1의 개수가 oneNum과 같다면 그때의 n을 리턴한다....

 

왜 이렇게 간단하게 생각하지 못했을까?

무조건 규칙을 찾으려고 하는 나의 습관이 내  발목을 ㅅ씨게 잡았다..

내 발목.. 아야 아야.. 아프다..

 

일단 문제를 딱 보고 반복문으로 끝낼 수 있을 것 같으면 그냥 끝내버려야 한다.

 

문제 안에서 중요한 포인트는 1의 개수가 같다는 거고

조건문에 무조건 그걸 쓸 생각을 해야한다.

 

 

 

알고리즘 문제를 대할 때의 자세

 

1. 문제에서 '이거 조건문에 넣어서 풀면 돼~' 라고 말하는 것 같다면 그건 진짜 그렇게 하라는 거다.

2. 보자마자 규칙 찾으려고 나열식으로 덤벼들면 안된다.