프로그래머스 level2. 완전탐색 소수찾기
문제 설명
한자리 숫자가 적힌 종이 조각이 흩어져있습니다. 흩어진 종이 조각을 붙여 소수를 몇 개 만들 수 있는지 알아내려 합니다.
각 종이 조각에 적힌 숫자가 적힌 문자열 numbers가 주어졌을 때, 종이 조각으로 만들 수 있는 소수가 몇 개인지 return 하도록 solution 함수를 완성해주세요.
제한 사항
- numbers는 길이 1 이상 7 이하인 문자열입니다.
- numbers는 0~9까지 숫자만으로 이루어져 있습니다.
- “013”은 0, 1, 3 숫자가 적힌 종이 조각이 흩어져있다는 의미입니다.
입출력 예
입출력 예 #1 [1, 7]으로는 소수 [7, 17, 71]를 만들 수 있습니다.
입출력 예 #2 [0, 1, 1]으로는 소수 [11, 101]를 만들 수 있습니다.
- 11과 011은 같은 숫자로 취급합니다.
분류
- 완전 탐색
- DFS
풀이
만들 수 있는 숫자의 모든 경우의 수를 탐색한다. 그 중 소수를 찾아 개수를 센다.
문자열으로 주어지는 numbers 의 조합을 구하고 그 중 소수의 개수를 찾아야 한다.
-
permute 하는 함수를 정의한다. 모든 경우의 수를 구한다. 한글자씩 잘라서 조합한다.
-
소수를 찾는 함수를 정의한다.
먼저 solution 함수의 경우. 주어진 numbers의 길이 인덱스를 활용하여 경우의 수를 구하는 permute함수를 생각할 수있다.
function solution(numbers) {
const result = new Set();
for (let n = 1; n <= numbers.length; n++) {
for (const e of permute(numbers, n)) {
result.add(e);
}
}
}
permute 함수의 경우.
- 만약 n이 1인 즉, 1개를 뽑는 경우라면 중복값을 제거 한 후 spread 연산자로 쪼개서 반환해준다.
- 여러 개를 고르는 경우에는 재귀적으로 함수를 호출하여 numbers.length 만큼의 수행을 반복하며 글자를 자르고 조합하는 작업을 반복한다.
numbers.slice(0, i) + numbers.slice(i + 1) 를 사용하여 조합해 준다.
permute 의 두번째 인자는 n-1이 되어야 하는데, 이는 재귀의 패턴으로 n개를 고르는 문제가 있을 시 하나를 빼서 맨 앞에 고정해놓고 나머지 n-1 을 골라 뒤에 붙이게 되므로 늘 n-1 로 작아지는 패턴을 가지고 있다. n=1이 되면 재귀가 멈춘다.
function permute(numbers, n) {
const result = new Set();
if (n === 1) {
return new Set([...numbers]);
}
for (let i = 0; i < numbers.length; i++) {
for (const e of permute(
numbers.slice(0, i) + numbers.slice(i + 1),
n - 1
)) {
result.add(numbers[i] + e);
}
}
return result;
}
마지막으로 소수를 구하는 isPrime 함수를 정의해보자.
- num이 1이면 소수가 아니다. num이 2면 소수다.
- 1,0 으로 나누면 모든 값이 1로 나눠지고 0은 0이 되니까 2부터 시작한다.
- num을 i 로 나눴을때 나누어 떨어지면 false, 나누어 떨어지지 않으면 true.
function isPrime(num) {
if (num === 1) return false;
if (num === 2) return true;
for (let i = 2; i <= Math.floor(Math.sqrt(num)); i++) {
if (num % i === 0) {
return false;
}
}
return true;
}
최종 코드
function solution(numbers) {
const result = new Set();
for (let n = 1; n <= numbers.length; n++) {
for (const e of permute(numbers, n)) {
result.add(e);
}
}
return [...result].filter((n) => n > 1 && isPrime(n)).length;
}