Algorithm
2023. 6. 15.
[프로그래머스] 소수 찾기 (Javascript)
문제 설명
한자리 숫자가 적힌 종이 조각이 흩어져있습니다. 흩어진 종이 조각을 붙여 소수를 몇 개 만들 수 있는지 알아내려 합니다.
각 종이 조각에 적힌 숫자가 적힌 문자열 numbers가 주어졌을 때, 종이 조각으로 만들 수 있는 소수가 몇 개인지 return 하도록 solution 함수를 완성해주세요.
제한사항
- numbers는 길이 1 이상 7 이하인 문자열입니다.
- numbers는 0~9까지 숫자만으로 이루어져 있습니다.
- "013"은 0, 1, 3 숫자가 적힌 종이 조각이 흩어져있다는 의미입니다.
문제 풀이
이 문제를 풀기 위해선
- 완전 탐색(순열)과
- 소수 판별 방법
에 대해 이해해야 합니다.
순열
순열에 대한 기본적인 설명은 이 링크에서 확인할 수 있습니다.
가능한 모든 숫자 조합을 완전 탐색하기 위해 순열 알고리즘을 사용했습니다. 이 때, 순열을 시작하게 될 값과 숫자 조합의 자릿수도 완전탐색에 반영하기 위해 각각 반복문을 지정해줬습니다.
순열을 이용한 완전 탐색의 코드는 아래와 같습니다.
let nums = [];
// 조합 가능한 숫자를 찾는 로직
const permutation = (output, rests, length) => {
if (output.length === length) {
if (!nums.includes(output * 1)) nums.push(output * 1);
return;
}
rests.forEach((v, i) => {
const nextOutput = `${output}${v}`;
const nextRests = rests.filter((_, restIdx) => restIdx !== i);
permutation(nextOutput, nextRests, length);
});
};
// arr의 모든 값들을 시작값으로 지정하기 위해 반복문 수행
for (let i = 0; i < arr.length; i++) {
const firstSelect = arr[i];
const firstRests = arr.filter((_, restIdx) => restIdx !== i);
// 1부터 최대 자릿수까지 순회
for (let j = 1; j <= arr.length; j++) {
permutation(firstSelect, firstRests, j);
}
}
소수 찾기
가능한 모든 숫자들의 조합들을 찾아주었다면, 이제 해당 숫자들이 소수인지 판별해줘야 합니다. 소수 판별 방식에는 여러가지 방법들이 있지만, 저는 Math.sqrt(숫자)까지 순회하며 소수인지 판별하는 로직을 이용했습니다.
소수인지 아닌지 판별하는 코드는 아래와 같습니다.
// 소수 판별 핸들러
const checkPrimeNumber = (number) => {
if (number < 2) return false;
for (let i = 2; i <= Math.sqrt(number); i++) {
const remainder = number % i;
if (remainder === 0) return false;
}
return true;
};
// 소수만 남기고 제거
nums = nums.filter((v) => checkPrimeNumber(v * 1));
마지막으로 남은 소수들의 수를 구하여 리턴해주면 코드는 완성입니다.
전체 코드
const solution = (numbers) => {
const arr = numbers.split("");
let nums = [];
// 조합 가능한 숫자를 찾는 로직
const permutation = (output, rests, length) => {
if (output.length === length) {
if (!nums.includes(output * 1)) nums.push(output * 1);
return;
}
rests.forEach((v, i) => {
const nextOutput = `${output}${v}`;
const nextRests = rests.filter((_, restIdx) => restIdx !== i);
permutation(nextOutput, nextRests, length);
});
};
// arr의 모든 값들을 시작값으로 지정하기 위해 반복문 수행
for (let i = 0; i < arr.length; i++) {
const firstSelect = arr[i];
const firstRests = arr.filter((_, restIdx) => restIdx !== i);
// 1부터 최대 자릿수까지 순회
for (let j = 1; j <= arr.length; j++) {
permutation(firstSelect, firstRests, j);
}
}
// 소수 판별 핸들러
const checkPrimeNumber = (number) => {
if (number < 2) return false;
for (let i = 2; i <= Math.sqrt(number); i++) {
const remainder = number % i;
if (remainder === 0) return false;
}
return true;
};
nums = nums.filter((v) => checkPrimeNumber(v * 1));
return nums.length;
};
마무리하며
덕분에 수열에 대해 배우고 이를 응용하는 연습을 할 수 있었던 좋은 문제인 것 같습니다.
'Algorithm' 카테고리의 다른 글
[Programmers, Lv.2] 땅따먹기 (feat. 동적계획법, 자바스크립트) (0) | 2023.06.22 |
---|---|
[이론] 순열 (1) | 2023.06.15 |
[프로그래머스] 큰 수 만들기 (0) | 2023.06.14 |
[프로그래머스] 전력망을 둘로 나누기 (2) | 2023.06.13 |
[이론] BFS와 DFS (javascript) (0) | 2023.06.13 |