모든 자연수 x에 대해서 현재 값이 x이면 x가 짝수일 때는 2로 나누고, x가 홀수일 때는 3 * x + 1로 바꾸는 계산을 계속해서 반복하면 언젠가는 반드시 x가 1이 되는지 묻는 문제를 콜라츠 문제라고 부릅니다.
그리고 위 과정에서 거쳐간 모든 수를 기록한 수열을 콜라츠 수열이라고 부릅니다.
계산 결과 1,000 보다 작거나 같은 수에 대해서는 전부 언젠가 1에 도달한다는 것이 알려져 있습니다.
임의의 1,000 보다 작거나 같은 양의 정수 n이 주어질 때 초기값이 n인 콜라츠 수열을 return 하는 solution 함수를 완성해 주세요.
제한사항
// 짝수
const even = (n) => {
return n / 2;
}
// 홀수
const odd = (n) => {
return 3 * n + 1;
}
function solution(n) {
let result = [];
result.push(n)
while (n > 1) {
n % 2 === 0 ? n = even(n) : n = odd(n);
result.push(n)
}
return result;
}
재귀를 이용해서 풀고 싶었지만?... 고민하면서 코드 쓰다가 걍 풀어져버림. 어...? 하고 일단 제출 ㅎ
function solution(n, arr = []) {
arr.push(n)
if (n === 1) return arr
if (n % 2 === 0) return solution(n / 2, arr)
return solution(3 * n + 1, arr)
}
재귀 풀이 발견!!
이 코드는 무한 루프에 빠지지 않으며 동작한다! 재귀 호출 시 n이 1이 되면 종료하기 때문이다.
위에서 내가 푼 코드는... while 조건문에 =
을 붙일 경우 런타임 레어가 난다. 왜냐면 n이 1이 되었을 때도 계속해서 루프가 실행되기 때문이다. even 함수가 계속해서 n = n / 2를 수행하게 된다. (해보고 알았습니다)
function* collatz(num) {
let value = num;
yield value;
while (value !== 1) {
value = value % 2 ? 3 * value + 1 : value / 2;
yield value;
}
}
function solution(n) {
return [...collatz(n)];
}
대체 yield
키워드가 머임...? 당황스러운 코드라서 찾아보고 왔다.
제너레이터 함수를 사용한 답안이라고 한다. (함수 실행을 일시 중지했다가 나중에 재개할 수 있는 특별한 함수)
collatz
함수는 제너레이터 함수이다. 이는 입력받은 숫자 num에 대해 콜라츠 추측 과정을 반복하고 각 단계의 값을 yield
를 통해 반환한다. 제너레이터 함수 동작 방식
yield value
는 현재 value를 반환하고, 함수 실행을 일시 중지한다. 함수 실행을 일시 중지했다가 나중에 재개할 수 있게 하는 자바스크립트의 고급 기능
ㅇㅅㅇ... 정말 이런 개념을 처음 알았다. 신기하다.
function*
으로 선언한다.yield
키워드를 사용하면 함수를 일시 중지할 수 있다.**yield
키워드
제너레이터 함수의 장점