[프로그래머스 2레벨] 피보나치 수

이민선(Jasmine)·2023년 2월 3일
0
post-thumbnail

문제

피보나치 수
피보나치 수는 F(0) = 0, F(1) = 1일 때, 1 이상의 n에 대하여 F(n) = F(n-1) + F(n-2) 가 적용되는 수 입니다.

예를들어

F(2) = F(0) + F(1) = 0 + 1 = 1
F(3) = F(1) + F(2) = 1 + 1 = 2
F(4) = F(2) + F(3) = 1 + 2 = 3
F(5) = F(3) + F(4) = 2 + 3 = 5
와 같이 이어집니다.

2 이상의 n이 입력되었을 때, n번째 피보나치 수를 1234567으로 나눈 나머지를 리턴하는 함수, solution을 완성해 주세요.

제한 사항
n은 2 이상 100,000 이하인 자연수입니다.
입출력 예
n	return
3	2
5	5
입출력 예 설명
피보나치수는 0번째부터 0, 1, 1, 2, 3, 5, ... 와 같이 이어집니다.

문제에서 n번째 피보나치 수를 1234567으로 나눈 나머지를 리턴하라길래
처음에 코드를 짤 때는

function solution(n) {
    let arr = [0, 1];
    for (let i = 2; i <= n ;i++)
        arr.push((arr.slice(-2)[0] + arr.slice(-2)[1]);
    return arr[n] % 1234567;
}

이렇게 짰고
수많은 테스트케이스가 실패로 떴다.
읭? 나 피보나치 수열 잘 구현해낸 것 같은딩?

이유는 오버플로우였다.
그게 뭔데??

언어가 표현할 수 있는 자료형의 범위를 넘어서는 것!
n이 너무 커서 해당 범위를 넘어갈 경우에 오류가 나는 것이다.
자바스크립트에서 표현가능한 정수의 최대 크기는 Number.MAX_SAFE_INTEGER를 console로 찍어보면 알 수 있다.

난 의지의 한국인이기 때문에 Number.MAX_SAFE_INTEGER를 넘어서는 피보나치 수를 찾아내었다. 79다. (ㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋ)
피보나치 수 계산해주는 사이트:
https://ko.numberempire.com/fibonaccinumbers.php

78일 때는 Number.MAX_SAFE_INTEGER 미만이므로 solution함수에서 반환하는 값과 일치하지만,

79일 때는 Number.MAX_SAFE_INTEGER를 초과하기 때문에 solution 함수에서 반환하는 값과 불일치한다.

function solution(n) {
  let arr = [0, 1];
  for (let i = 2; i <= n; i++) arr.push(arr.slice(-2)[0] + arr.slice(-2)[1]);
  return arr[n];
}
console.log(Number.MAX_SAFE_INTEGER); // 9007199254740991
console.log(solution(78)); // 8944394323791464
console.log(solution(78) > Number.MAX_SAFE_INTEGER); // false
console.log(solution(78) === 8944394323791464); // true

console.log(Number.MAX_SAFE_INTEGER); // 9007199254740991
console.log(solution(79)); // 14472334024676220
console.log(solution(79) > Number.MAX_SAFE_INTEGER); // true
console.log(solution(78) === 14472334024676221); //false

따라서 오버플로우가 나지 않도록 arr에 push하기 전에 1234567로 미리미리 나눠주면 문제의 범위에서는 자바스크립트가 Number.MAX_SAFE_INTEGER 미만의 수를 표현하게 되므로 더 이상 에러가 나지 않는다.

참고: https://ivorycirrus.github.io/archivers/js-big-int

나의 코드

function solution(n) {
    let arr = [0, 1];
    for (let i = 2; i <= n ;i++)
        arr.push((arr.slice(-2)[0] + arr.slice(-2)[1]) % 1234567);
    return arr[n];
}

미리미리 나눠주어 자바스크립트에게 친절해지자!

profile
기록에 진심인 개발자 🌿

0개의 댓글