[프로그래머스] 레벨2 (level2) 소수 만들기
2020년 05월 21일, 11:29
소수 만들기
문제 설명
주어진 숫자 중 3개의 수를 더했을 때 소수가 되는 경우의 개수를 구하려고 합니다. 숫자들이 들어있는 배열 nums가 매개변수로 주어질 때, nums에 있는 숫자들 중 서로 다른 3개를 골라 더했을 때 소수가 되는 경우의 개수를 return 하도록 solution 함수를 완성해주세요.
제한사항
- nums에 들어있는 숫자의 개수는 3개 이상 50개 이하입니다.
- nums의 각 원소는 1 이상 1,000 이하의 자연수이며, 중복된 숫자가 들어있지 않습니다.
입출력 예
nums result [1,2,3,4] 1 [1,2,7,6,4] 4
처음 생각
처음에는 문제를 보자마자 아 조합문제니까 재귀를 이용해서 풀어야겠다!하고 시작했다.
답은 맞았는데 1점 밖에 안주는걸 보고 응?하고 다른 사람의 풀이를 봤는데,
for문으로만 푸신 분들이 많았다.. 그래서 꼭 재귀가 답은 아니구나 라는 생각이 다시한번 들었다.
만약, 뽑아야 하는 수가 더 많았으면 재귀를 활용해서 할 수 밖에 없겠지만, 3가지 숫자이기 때문에 for문을 중첩으로해서 충분히 가능한 문제였다.
문제풀이
3가지 숫자를 골라서 더해야 하기 때문에 for문을 3개 사용하면 된다. 2번째 포문은 1번째 포문보다 +1에서 시작하고, 3번째 포문은 2번째 포문보다 +1에서 시작하게 만들어서 모든 숫자를 보면 된다. 그리고 total값이 소수일 때만 answer++한다. (여기서 answer값은 0으로 초기화 => 0인 경우가 존재.)
function solution(nums) {
var answer = 0;
// answer = permutation(nums,0,1);
for (let i = 0; i < nums.length; i++) {
for (let j = i + 1; j < nums.length; j++) {
for (let k = j + 1; k < nums.length; k++) {
let total = nums[i] + nums[j] + nums[k];
if (checkPrime(total)) {
answer++;
}
}
}
}
return answer;
}
function checkPrime(num) {
for (let i = 2; i <= Math.sqrt(num); i++) {
if (num % i === 0) return false;
}
return true;
}
추가, 재귀로 순열을 짜서 품.
function solution(nums) {
var answer = 0;
answer = permutation(nums, 0, 1);
return answer;
}
function permutation(nums, total, dep) {
return nums.reduce((acc, val, idx) => {
let newArr = [...nums];
if (idx === 0) newArr.splice(idx, 1);
else newArr.splice(0, idx + 1);
total += val;
dep++;
if (dep === 3) {
if (checkPrime(total)) return ++acc;
else return acc;
}
let result = permutation(nums, total, dep);
acc += result;
total -= val;
return acc;
}, 0);
}
function checkPrime(num) {
for (let i = 2; i <= Math.sqrt(num); i++) {
if (num % i === 0) return false;
}
return true;
}