알고리즘에선 경우의 수 문제가 많다. 그 중에 단골로 등장하는 문제가 바로 줄세우기(혹은 뽑아서 줄세우기)인데, 순열 조합이라고 부르기도 한다.
순열의 경우의 수를 구하는 것은 수학적인 개념을 적용하면 되지만, 그 case들을 나열하는 것이면 얘기가 달라진다. 재귀함수를 이용하여 원하는 데이터로 나열해야 하기 때문. 재귀함수를 사용하는 것 자체가 비효율적인 부분이 있어서 최적화 하는데에 항상 스트레스.
여태까지 순열 조합에 시달리며 재귀함수를 이것저것 짜봤는데, 역시나 재귀함수 자체는 결과를 위한 최적화된 코드는 짤 수 없다. 매 함수 컨텍스트 마다 원하는 모양을 만들기 위해 불필요하게 반복되는 코드가 존재할 수밖에 없기 때문이다. 그럼에도 재귀함수를 쓸수 밖에 없는 이유는 재귀함수밖에 구현하지 못하기 때문?
(예를들어 순열을 만들기 위해 기준을 잡고 순서를 바꾸는 방식이든, 맨앞으로 넘기는 방식이든, 잘랐다가 다시 붙히는 방식이든 배열을 fasly 값으로 바꿔주는 방식이든 고정된 수를 잡고 나머지 순서를 바꾸는 단계에서 한 번 이상 필요없는 코드를 반복하는 것을 피할 수 없다. 어쩌면 내 머리의 한계일지도..?)
function solution(numbers) {
let result = [];
let numbersArr = numbers.split('').sort((a,b)=>a-b)
const getPermutations = (arr,str) => {
for (let i = 0 ; i<arr.length; i++){
let temp = arr.slice();
let tempStr = str;
if(temp[i] !== null){
tempStr += temp[i];
result.push(Number(tempStr))
temp[i] = null;
getPermutations(temp,tempStr)
}
}
}
getPermutations(numbersArr, '')
let max = Math.sqrt(result[result.length-1])
for(let i = 2; i<=max; i++){
for(let j = 0; j<result.length; j++){
if(result[j] !== null){
result[j] === 1 ? result[j] = null : null;
result[j] % i === 0 && result[j] / i !== 1 ? result[j] = null : null;
}
}
}
return result.filter((el,i)=> el && i === result.indexOf(el)).length;
}
const getPermutations = (arr,str) => {
for (let i = 0 ; i<arr.length; i++){
let temp = arr.slice();
let tempStr = str;
if(temp[i] !== null){
tempStr += temp[i];
console.log(Number(tempStr))//조합될때마다 출력
temp[i] = null;
getPermutations(temp,tempStr)
}
}
}
getPermutations([0,1,2], '')
//console : '0' '1' '12' '2' '21' '1' '10 ... Number()에 의해 앞에 0은 제거된다.
function solution(n){
let result = 0;
for(let i = 2; i<=n; i++){
let count = 0;
for(let j = 2; j<=i; j++){
if(i % j === 0) count++
}
count === 1 ? result ++ : null;
}
return result;
}
function solution(numbers) {
let result = [];
let numbersArr = numbers.split('').sort((a,b)=>a-b)
const getPermutations = (arr,str) => {
for (let i = 0 ; i<arr.length; i++){
let temp = arr.slice();
let tempStr = str;
if(temp[i] !== null){
tempStr += temp[i];
result.push(Number(tempStr))
temp[i] = null;
getPermutations(temp,tempStr)
}
}
}
getPermutations(numbersArr, '')
let max = Math.sqrt(result[result.length-1])
for(let i = 2; i<=max; i++){
for(let j = 0; j<result.length; j++){
if(result[j] !== null){
result[j] === 1 ? result[j] = null : null;
result[j] % i === 0 && result[j] / i !== 1 ? result[j] = null : null;
}
}
}
return result.filter((el,i)=> el && i === result.indexOf(el)).length;
//0이 포함되었을때 중복될 값도 제거해줘야한다.
}
function solution(numbers) {
let numbersArr = numbers.split('').sort((a,b)=>b-a)
const filterArr = new Array(Number(numbersArr.join(''))+1);
filterArr.fill(1)
const getPermutations = (arr,str) => {
for (let i = 0 ; i<arr.length; i++){
let temp = arr.slice();
let tempStr = str;
if(temp[i] !== null){
tempStr += temp[i];
filterArr[Number(tempStr)] = 2;
temp[i] = null;
getPermutations(temp,tempStr)
}
}
}
getPermutations(numbersArr, '')
let max = Math.sqrt(numbersArr.join(''))
filterArr.fill(0,0,2)
for(let i= 2; i<=max; i++){
if(filterArr[i]){
for(let j = i * 2; j<filterArr.length; j+=i){
filterArr[j]= 0;
}
}
}
return filterArr.filter(el=>el && el === 2).length;
}
위가 2번, 아래가 3번이다.