한자리 숫자가 적힌 종이 조각이 흩어져있습니다. 흩어진 종이 조각을 붙여 소수를 몇 개 만들 수 있는지 알아내려 합니다.
각 종이 조각에 적힌 숫자가 적힌 문자열 numbers가 주어졌을 때, 종이 조각으로 만들 수 있는 소수가 몇 개인지 return 하도록 solution 함수를 완성해주세요.
numbers | return |
---|---|
"17" | 3 |
"011" | 2 |
순열(Permutation)
()을 만들어내야 한다. 따라서, 이 문제에서는 순열을 구하는 함수를 구현하는 것이 제일 key point가 되겠다.r == 1
일 때는 파라미터로 들어온 배열의 원소 하나하나에 대해서 배열로 만들어서 리턴해준다.[1, 2, 3] => [[1], [2], [3]]
r >= 2
일 때는 파라미터로 들어온 배열의 원소 하나하나에 대해서 fixed
수로 정해놓고, 나머지 원소들을 rest
배열에 모아놓은 다음, 그 rest
를 가지고 다시 Permutation(rest, r-1)
을 돌려 결과를 얻어낸다.fixed
를 합쳐서 임시 결과로써 저장한다.temp_result = [fixed, ...permutation]
Set
을 사용했다.Array.prototype.forEach()
와 Array.prototype.slice()
의 조합
forEach
를 사용할 때는 콜백함수의 파라미터로 거의 currentvalue
, index
까지만 썼었었는데 이 문제에서는 array(원본배열)
까지 활용하는 문제였다. 순열을 구하는 함수 내부에서 forEach()
의 파라미터 array(원본배열)
으로 slice()
메소드를 사용한다.
스프레드 연산자
Array.prototype.concat()
메소드를 사용하지 않고도 보다 간편하고 깔끔하게 두 배열을 병합시킬 때 사용한다. 순열을 구하는 함수 내부에서 유용하게 사용한다.
// 소수 판별함수
function isPrime(n) {
if(n < 2)
return false;
for(let i=2; i<=Math.sqrt(n); i++) {
if(n % i === 0)
return false;
}
return true;
}
// nPr만큼의 순열을 구하는 함수
function permutation(arr, r) {
let temp_result = [];
// Base case
if(r == 1)
return arr.map(n => [n]);
// r이 2 이상일 떄
arr.forEach((fixed, i, src) => {
let rest = [...src.slice(0, i), ...src.slice(i+1)];
let lowerLevel = permutation(rest, r-1);
let attached = lowerLevel.map(elem => [fixed, ...elem]);
temp_result.push(...attached);
});
return temp_result;
}
function solution(numbers) {
let result = [];
let numarr = numbers.split("");
let set = new Set();
for(let i=1; i<=numbers.length; i++) {
let perm = [...permutation(numarr, i)];
// console.log(perm);
perm.forEach(p => {
let testnum = ~~(p.join(""))
if(isPrime(testnum))
set.add(testnum);
})
}
console.log(set);
return set.size;
}
itertools
의 permutations
를 사용하여 순열을 손쉽게 만든다. (하지만 그래도 데이터 처리는 필요함)permutations
함수에 원하는 리스트와 길이를 넘겨주고 반환받은 값을 list()
함수를 이용하여 리스트로 바꿔준다.ex. ("1", )
)이므로, join 메서드를 통해 문자열 하나로 합쳐주고, 이를 int()
함수를 통해 숫자로 바꿔준다.perm
이라는 리스트에 저장하고, perm
을 순회하면서 set
에 넣어주어 중복된 수를 제거해준다.is_prime
함수에 넣어 소수인지 판별되면 answer을 1씩 증가시키면 되는 로직이다.import math
from itertools import permutations
def is_prime(number):
if(number == 0 or number == 1):
return False
else:
for i in range(2, int(math.sqrt(number)) + 1):
if(number % i == 0):
return False
return True
def solution(numbers):
numSet = set()
nums = list(numbers)
# 길이 1부터 numbers의 길이까지 순서대로 순열 돌린다
for i in range (1, len(numbers) + 1):
perm = [int("".join(tup)) for tup in list(permutations(nums, i))]
# 만들어진 순열을 set에 넣어 중복을 제거한다.
for n in perm:
numSet.add(n)
# 만들어진 set에 대해 하나하나 소수인지 판별한다.
answer = 0
for n in numSet:
if(is_prime(n)):
answer += 1
return answer