1보다 큰 자연수 중 1과 자기 자신만을 약수로 가지는 수
따라서 2를 제외한 짝수는 소수가 될 수 없으며,
홀수 중에서도 제곱근으로 나누어 떨어지는 것 또한 제외된다.
🔥 에라토스테네스의 체 공부하기!!
문제
1 이상의 자연수를 입력받아 소수(prime number)인지 여부를 리턴해야 합니다.
입력
인자 1 : num
number 타입의 수
출력
boolean 타입을 리턴해야 합니다.
입출력 예시let output = isPrime(2); console.log(output); // --> true output = isPrime(6); console.log(output); // --> false output = isPrime(17); console.log(output); // --> true
function isPrime(num) {
if (num === 2) return true; // 짝수 중 2만 유일하게 예외니까
if (num === 1 || !(num % 2)) return false;
let squareRoot = Math.sqrt(num)
for (let i = 3; i <= squareRoot; i += 2) {
if (!(num % i)) return false;
}
return true;
}
문제
2 이상의 자연수를 입력받아 2부터 해당 수까지의 소수들을 리턴해야 합니다.
입력
인자 : num
number 타입의 정수 (num >= 2)
출력
string 타입을 리턴해야 합니다.
2-3-5-7의 형식으로 리턴해야 합니다.
주의 사항
이중 반복문(double for loop)을 사용해야 합니다.
입출력 예시let output = listPrimes(2); console.log(output); // --> '2' output = listPrimes(6); console.log(output); // --> '2-3-5' output = listPrimes(18); console.log(output); // --> '2-3-5-7-11-13-17'
function listPrimes(num) {
let result = '2'
// 짝수 중 유일하게 소수인 2
// num은 최소 '2'를 포함한 결과값을 리턴
for (let i = 3; i <= num; i += 2) {
// num까지의 수 중 홀수만 i로 선별
let sqrt = Math.sqrt(i)
let isPrime = true; // 소수 판별의 조건 기본 설정
for (let j = 3; j <= sqrt; j += 2) {
// 홀수 i 중 소수 j 판별
if(!(i % j)) {
isPrime = false; // 제곱근으로 나누어 떨어지면 소수가 아니다.
break; // 안쪽 for문 해제.
// continue도 가능하지만 j문을 한번 더 도는 낭비가 발생
}
}
if(isPrime) result = `${result}-${i}`;
// 안쪽 for문을 거쳐 떨어지는 홀수 i가 소수인지 판별하기 위해 꼭 필요한 조건문
// 제곱근으로 나눠지지 않는 경우만 담는다.
}
return result;
}
TIL
- break vs continue
break더 반복하지 말고, 바로 반복문을 끝내라
continue현재는 건너 뛰고, 다음 반복으로 넘어가라
문제
다음의 조건을 만족하면서 현재의 비밀번호('curPwd')를 새 비밀번호(newPwd)로 변경하는 데 필요한 최소 동작의 수를 리턴해야 합니다.
- 한 번에 한 개의 숫자만 변경가능하다.
- 4자리의 소수(prime)인 비밀번호로만 변경가능하다.
정리하면, 비밀번호가 계속 소수를 유지하도록 숫자 한 개씩을 바꿔갈 때
현재 비밀번호에서 새 비밀번호로 바꾸는 데 최소 몇 개의 숫자를 변경해야 하는지를 리턴해야 합니다.
입력
인자 1 : curPwd
number 타입의 1,000 이상 9,999 이하의 자연수
인자 2 : newPwd
number 타입의 1,000 이상 9,999 이하의 자연수
출력
number 타입을 리턴해야 합니다.
주의사항
4자리인 소수는 1,000 이상의 소수를 말합니다.(0011, 0997 등은 제외)
입출력 예시let output = primePassword(1033, 1033); console.log(output); // --> 0 output = primePassword(3733, 8779); console.log(output); // --> 3 (3733 -> 3739 -> 3779 -> 8779)
현재 비밀번호에서 새 비밀번호로 변경하는 데 필요한 최소 동작의 수
-> BFS와 Q 자료구조를 통해 접근한다.
// 유효성 검사와 비밀번호 구현 파트를 나누고 BFS 접근 방식으로 푼다.
let Q = 비밀번호 리스트
let isUsed = 사용한 비밀번호
while 문을 통해 큐 리스트가 빌 떄까지 반복하는데
if (현재 비밀번호 === 원하는 새 비밀번호) 탈출!
for (let i~) {
if (조건과 유효성 검사 통과한다면)
Q 리스트에 추가한다.
}
// 소수 판별 함수 -> 유효성 검사
const isPrime = (num) => {
if (!(num % 2)) return false;
let sqrt = Math.sqrt(num)
for (let i = 3; i <= sqrt; i += 2) {
if (!(num % i)) return false;
}
return true;
}
// 비밀번호를 만드는 함수
const primePassword = (curPwd, newPwd) => {
let Q = [[curPwd, 0]]; // 큐에 현재 비밀번호와 변경한 횟수를 함께 넣어준다.
let isUsed = [curPwd];
while (Q.length) {
let [now, step] = Q.shift();
if (now === newPwd) return step;
for (let i = 0; i < 4; i++) {
let digits = String(now).split('').map( el => Number(el))
// 이 위치여야 i값에 따라 초기화가 된다.
for (let d = 0; d <= 9; d++) {
if (digits[i] !== d) {
digits[i] = d;
let next = Number(digits.join(''))
if (next === newPwd) return step + 1;
// 원하던 값을 찾으면 뒤에 남은 반복 연산을 두고 리턴하라!
if (next > 1000 && isPrime(next) && !isUsed.includes(next)) {
Q.push([next, step + 1])
isUsed.push(next)
}
}
}
}
}
};