14일차
14일차부터는 같은 시간에 많은 문제를 풀기가 어렵다. 코딩 기초트레이닝도 정답률이 80%이하고, 좀 더 수학적이고 사고적인 생각을 요구하는 문제들이 나온다. 그렇기에 한 문제 한 문제에 70%이상의 집중력으로 문제를 풀어야한다.

오늘까지의 코딩 기초트레이닝 결과다. 남은 문제는 23문제가 남았고, 81%를 달성했다. 이 문제는 다음 주까지 마무리 짓는 것을 목표로 잡아야겠다.
오늘의 문제
배열의 길이를 2의 거듭제곱으로 만들기
문제 설명
정수 배열 arr이 매개변수로 주어집니다. arr의 길이가 2의 정수 거듭제곱이 되도록 arr 뒤에 정수 0을 추가하려고 합니다. arr에 최소한의 개수로 0을 추가한 배열을 return 하는 solution 함수를 작성해 주세요.
입출력 예
| arr | result |
|---|
| [1, 2, 3, 4, 5, 6] | [1, 2, 3, 4, 5, 6, 0, 0] |
| [58, 172, 746, 89] | [58, 172, 746, 89] |
매 문제마다 쉽지 않다는 생각이 계속든다. 그 중에서도 오늘의 문제로 정하는 기준은 나에게 얼마나 이로운 문제였나이다. 이 문제가 나에게 준 이로운 점은 2가지다.
수학적인 사고와 코드로 표현하기
접근방법
- arr의 길이를 확인.
- arr의 길이가 이미 2의 거듭제곱이라면 추가할 0의 개수는 0.
- arr의 길이가 2의 거듭제곱이 아닌 경우, 추가해야 하는 0의 개수 구하기.
- arr에 추가해야하는 개수만큼 0을 추가하기.
항상 코딩을 할 때는 접근방법을 잘 기록하는 것이 중요하다. 접근을 잘하면 잘 할수록 문제를 올바른 방향으로 풀 수 있으니까 항상 문제를 푸는 것보다도 접근을 잘하려 하는 자세가 중요하다.
풀이
const checkPow = num => {
return num & (num - 1) === 0
}
function solution(arr) {
var answer = [];
let length = arr.length;
let nextPow = Math.pow(2, Math.ceil(Math.log2(length)))
let plusZero = nextPow - length;
if(checkPow(length)) {
answer = arr;
} else {
for(let i = 0; i < plusZero; i++) {
arr.push(0)
}
answer = arr;
}
return answer;
}
접근방법을 중심으로 문제를 풀면 위와 같다. 하나하나 설명을 하면 우선 가장 처음 checkPow 함수다.
checkPow 함수는 arr의 길이가 2의 거듭제곱인지 파악하는 함수다. 여기서 비트연산자를 사용했다. 두 수의 비트를 비교하는 연산자 &는 둘 다 1인 경우에만 1을 반환한다. 비트연산자를 사용한 이유는 2의 거듭제곱 숫자는 이진 표현에서 가장 오른쪽 비트를 제외하고 모든 비트가 0인 숫자이기 때문이다.
예를 들어, 8을 비트로 나타내면 1000이다. 이를 바탕으로 checkPow함수에 넣어 풀어보면 8 & 7 이 되고, 비트로는 1000 & 0111이며 이는 둘 다 1인 경우가 없기 때문에 0으로 결국 true를 반환하고 8인 2의 거듭제곱이라는 뜻이다.
다음으로 변수 nextPow다. nextPow는 현재 arr의 길이가 2의 거듭제곱이 아닌 경우, arr의 길이보다 큰 가장 가까운 2의 거듭제곱 수이다.
예를 들어 길이가 6인 경우는 Math.log2()를 통해 루트(log26)가 된다. 이 수를 반올림하고 2의 거듭제곱을 하면 가장 가까운 8이 나온다.
풀이결과
나머지는 간단하다. arr의 길이가 우선 2의 거듭제곱인지 체크 맞으면 그대로 반환. 아닐 경우 arr의 길이에서 가장 가까운 2의 거듭제곱을 찾아 arr길이를 빼주며, 남은 수만큼 0를 더 해준다.
정리하기
접근방법은 너무 어렵지는 않았다. 그러나 수학적으로 생각하는 것과 이를 어떻게 표현하는지가 중요한 문제였다. 이 두 가지를 다 갖고 있던 좋은 문제였다.
거듭제곱 문제가 나올 경우, 비트연산자를 사용하거나 이진 로그를 사용하는 걸 배운 문제기 때문에 잊지 않을 것 같다. 다음에 비슷한 문제가 나올 경우에는 망설이지 않고 사용해보도록 해야겠다.