숫자가 적힌 종이 쪼가리가 주어진다. 이 종이쪼가리를 이어붙여서 숫자를 만들 수 있는 만큼 만들고 그 이어붙인 숫자들이 소수이면 answer에 추가한다. 예를들어, 17
이 주어지면 1,7이라는 숫자가 적힌 종이조각이 주어진것이다.
이때 만들수 있는 경우의 수는 1,7,17,71
이다. 이중에 소수를 찾아서 return하면 된다.
뽑아낼 수 있는 모든 경우를 뽑아내는 것에서 부분집합이 떠올랐다. 그러나 부분집합은 순서를 고려하지 않는다. 즉, 1,7,17만을 뽑아 내는 것이다. 7이 앞으로가고 1이 뒤로가서 71을 뽑아내지는 않는다.
숫자의 갯수와 순서까지 신경써서 모든 경우의 수를 뽑아내는 것을 brute-force라고 하나? 여튼 부분집합, 소수 판별법 까지 구현했지만 숫자를 뒤집어서까지 경우의 수를 뽑아내는 기능은 구현하지 못해서 정답을 봤는데 역시나가 역시나다. 그냥 좋다.
function isPrime(n) {
for (let i = 2; i < Math.sqrt(n); i++) {
if (n % i === 0) return false;
}
return n > 1;
}
function solution(numbers) {
let answer = 0;
let n = numbers.split("");
let nums = new Set();
combi(n, "");
function combi(arr, strNum) {
// 문자형태의 숫자가 만들어 졌다면
if (strNum.length > 0) {
if (nums.has(Number(strNum)) === false) {
nums.add(Number(strNum));
if (isPrime(strNum)) {
answer++;
}
}
}
if (arr.length > 0) {
for (let i = 0; i < arr.length; i++) {
// arr안에 있는 숫자를 뜯어내서 조합하기 위새 새로운 arr , cut을 만들었음
let cut = arr.slice(0); // 새로운 array에 담음 ==> ['1','7']
// 차례대로 뜯어내서 하나씩 조합
cut.splice(i, 1); // i가 0일때 결과적으로 ['7']만 남음. ['1','7'] 중에서 '1'을 떼어가므로
combi(cut, strNum + arr[i]); // combi(['7'],''+'1')
}
}
}
return answer;
}
보기 쉽게 그림으로 정리해 보았다.
보면, ['1','7']이 주어졌다고 했을 때, 맨처음 level에서는 왼쪽가지에서는 1로 시작되는 숫자의 조합이 나타나고 오른쪽 가지는 7로 시작되는 조합이 나타날것이다. 그런식으로 뻗어가면서 앞뒤로 붙여나가고 그럴 것이다.
다시 배웠다. 재밌다. 좋다. 신기하다!