[Level2] 12. 55 ~ 59
2단계 시작! 하루에 최소 3문제, 오늘은 숫자 부시기
55. N개의 최소공배수
const gcd = (a, b) => {
if (a < b) [a, b] = [b, a];
while (b > 0) {
let temp = b;
b = a % b;
a = temp;
}
return a;
};
const lcm = (a, b) => {
return (a * b) / gcd(a, b);
};
function solution(arr) {
let answer = 1;
for (let i = 0; i < arr.length; i++) {
answer = lcm(answer, arr[i]);
}
return answer;
}
30번 문제에서 풀었던 최대공약수, 최소공배수를 그대로 활용하는 문제였다.
유클리드 호제법은 암기를 해두는게 좋을 것 같다.
헷갈리니 다시 짚고 넘어가자
유클리드 호제법
- 2개의 자연수의 최대공약수를 구하는 알고리즘
- 두 개의 자연수 a, b에서 (a>b) a를 b로 나눈 나머지를 r이라 할 때, GCD(a,b) === GCD(b,r)
- r이 0이면 그 때의 b가 최대공약수이다.
- ex) GCD(24,16) === GCD(16, 8) === GCD(8,0) 최대공약수 = 8
- 최소공배수 : LCM = (a * b) / 최대공약수 === (a * b) / GCD(a, b)
best 풀이
function nlcm(num) {
return num.reduce((a,b) => a*b / gcd(a,b))
}
function gcd(a, b) {
return a % b ? gcd(b, a%b) : b
}
// 아래는 테스트로 출력해 보기 위한 코드입니다.
console.log(nlcm([2,6,8,14]));
원리는 동일한데 그걸 코드로 엄청 깔끔하게 잘 정리한 것 같다.
이런 센스는 도대체 어떻게 해야 얻을 수 있는거지…???!!!
56. 최솟값 만들기
function solution(A, B) {
A.sort((a, b) => a - b);
B.sort((a, b) => b - a);
return A.reduce((acc, value, index) => acc + value * B[index], 0);
}
2단계 문제를 대할 떼 사실 엄청 쫄아있었는데 이건 너무 간단했다.
이게 왜 2단계에 있지?
쫄지 말자!! 할 수 있따!!!
best 풀이와 동일함으로 best는 패스!
57. 최댓값과 최솟값
function solution(s) {
let temp = s.split(" ");
temp.sort((x, y) => x - y);
return `${temp[0] / 1} ${temp[temp.length - 1] / 1}`;
}
이주전에 한번 도전했다가 포기했던 문제인데 이제는 풀린다!!
점점 실력이 쌓이는게 느껴진다. 더더 열심히하자 🤩👊
best 풀이
function solution(s) {
const arr = s.split(' ');
return Math.min(...arr)+' '+Math.max(...arr);
}
sort 정렬대신 Math.min, Math.max를 사용했다.
효율적인 측면에서는 그래도 내 코드가 n이면 이건 2n이니 난 내 코드가 더 좋다고 본다..!!
function solution(s) {
return s.split(' ').sort((a, b) => a - b)[0] + ' ' + s.split(' ').sort((a, b) => a - b)[s.split(' ').length - 1];
}
워후… 한줄이긴 한데 너무 불필요하게 메소드들을 반복사용한다. (내 코드 짱…!)
58. 숫자의 표현 🤔
function solution(n) {
let answer = 0;
for (let i =0; i<=n; i++){
if (n%i === 0 &&& i % 2 === 1) answer++
}
return answer;
}
모르겠어서 다른 분의 풀이를 참고하였다.ㅠ
주어진 자연수를 연속된 자연수의 합으로 표현하는 방법의 수와 주어진 수의 홀수의 약수 갯수는 같다
라는 공식을 활용한 풀이법이다.
- 15의 약수는 1, 3, 5, 15 이고, 이중 홀수는 4개이다.
- 약수 1 : 연속하는 1개의 자연수의 합으로 표현 가능 > 15 = 15
- 약수 3 : 연속하는 3개의 자연수의 합으로 표현 가능, 15를 3으로 나눈 값인 5로 표현할 수 있다. > 5 + 5 + 5 = 15 => 3 + 4 + 5 = 15
- 약수 5 : 연속하는 5개의 자연수의 합으로 표현 가능, 15를 5로 나눈 값인 3으로 표현할 수 있다. > 3 + 3 + 3 + 3 + 3 => 1 + 2 + 3 + 4 + 5 = 15
- 약수 15 : 연속하는 15개의 자연수의 합으로 표현 가능 > 모든 홀수(2n+1)는 n과 n+1로 표현 가능 > 7 + 8 = 15
function solution(n) {
let answer = 0;
for (let i = 1; i <= n; i++) {
let total = 0;
for (let j = i; j <= n; j++) {
if (total === n) answer++;
if (total > n) break;
total += j;
}
}
return answer;
}
이 코드는 위에 코드보다 성능은 현저히 떨어지지만 수학적 공식 없이 문제 본질만을 생각해서 쓸 수 있는 코드이다.
이 코드까지는 어떻게 짜겠는데 정말 저런 위의 코드같은 건 내가 할 수 있을까….싶다.😭
코테 하면서 알게 되는 수학의 중요성….😭😭
59. 다음 큰 숫자
function solution(n) {
let cnt = n
.toString(2)
.split("")
.filter((i) => i === "1").length;
while (n++) {
if (
n
.toString(2)
.split("")
.filter((i) => i === "1").length === cnt
)
return n;
}
}
처음에 문제보고 살짝 쫄았는데 잘했어…!!
대견하다..!!
best 풀이
function nextBigNumber(n) {
var size = n.toString(2).match(/1/g).length
while(n++) {
if(size === n.toString(2).match(/1/g).length) return n
}
}
1의 갯수를 세는 걸 정규식으로 해결했다. split()과 filter()를 거치던 내 코드보다 훨씬 좋다…
앞으로는 문자열에서 특정 문자를 찾을 때는 정규식을 활용하자.