zhaopinboai.com

Efficiently Checking Fibonacci Numbers with JavaScript

Written on

Fibonacci sequence illustration

As Christmas approaches, so does the end of DevAdvent 2022. With limited time today, I'm focusing on an intriguing challenge involving Fibonacci numbers in JavaScript. My goal is to find an efficient way to determine if a number is part of the Fibonacci series without recalculating the series each time.

Fibonacci Numbers

Let's begin by clarifying what the Fibonacci series is: it’s a sequence where each number is the sum of the two preceding ones, with the first two numbers defined as 0 and 1.

The initial numbers in the series are: 0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233.

The Obvious Solution

The simplest method for checking if a number belongs to the series is to generate the series up to that number. Here’s an example function:

const isFibonacci = (n) => {

let a = 0;

let b = 1;

if (n === a || n === b) {

return true;

}

let c = a + b;

while (c <= n) {

if (c === n) return true;

a = b;

b = c;

c = a + b;

}

return false;

};

However, this approach becomes inefficient as the number increases, resulting in longer calculation times. While it works, it isn't practical for real-world applications.

A Better Solution

To enhance efficiency, we can explore the properties of the Fibonacci series. According to Wikipedia, French mathematician Jacques Philippe Marie Binet developed a formula that can compute the nth Fibonacci number:

F(n) = frac{(phi^n - (1 - phi)^n)}{sqrt{5}}

where F(n) is the nth Fibonacci number and ? (phi) represents the golden ratio, approximately 1.61803398875.

Here’s a JavaScript function that uses Binet’s formula to compute the nth Fibonacci number:

const fibonacci = (n) => {

const phi = (1 + Math.sqrt(5)) / 2;

return Math.round(

(Math.pow(phi, n + 1) - Math.pow(1 - phi, n + 1)) / Math.sqrt(5)

);

};

Alternatively, you can use this version of the function:

const fibonacci = (n) => {

const x = n - 1;

const sqr = 5 ** 0.5;

const a = (1 + sqr) ** x;

const b = (1 - sqr) ** x;

const c = 2 ** x * sqr;

return Math.round((a - b) / c);

};

This function receives a single argument n, which represents the index of the Fibonacci number to compute, returning the corresponding Fibonacci number. For example, to compute the 8th Fibonacci number, you would call the function as follows:

console.log(fibonacci(8)); // Output: 13

From Binet’s formula, we can derive a method to determine if a number belongs to the Fibonacci sequence:

If quad 5N^2 + 4 quad text{or} quad 5N^2 - 4 quad text{is a perfect square, then the number is in the Fibonacci sequence.}

Using this definition, I can create the function isFibonacci(n):

const isFibonacci = (n) => {

const x1 = 5 * n ** 2 + 4;

const x2 = 5 * n ** 2 - 4;

return Number.isInteger(Math.sqrt(x1)) || Number.isInteger(Math.sqrt(x2));

};

This function checks if a given number n is a Fibonacci number, returning true if it is, and false otherwise. For example, to check if 13 is a Fibonacci number, you can call it like this:

console.log(isFibonacci(13)); // Output: true

A more concise version of the same function can be written as follows:

const isFibonacci = (n) =>

Number.isInteger((5 * n ** 2 + 4) ** 0.5) ||

Number.isInteger((5 * n ** 2 - 4) ** 0.5);

How to Find the Position of a Number in the Fibonacci Series?

To summarize, we've created a JavaScript function to calculate the nth Fibonacci number (fibonacci(n)) and another to verify if a number belongs to the Fibonacci series (isFibonacci(n)). Now we need to develop a function to determine the position of a Fibonacci number within the sequence.

The simplest method, though resource-intensive, is as follows:

const fibonacciPosition = (n) => {

let position = 0;

let current = 0;

let next = 1;

while (current < n) {

position++;

let temp = current;

current = next;

next = temp + current;

}

if (current === n) {

return position + 1;

} else {

return -1;

}

};

Using Binet’s formula again, we can create a more efficient function:

const fibonacciPosition = (n) => {

const phi = (1 + Math.sqrt(5)) / 2;

const position = Math.log(n * 5 ** 0.5 + 0.5) / Math.log(phi);

return Math.floor(position) + 1;

};

However, the initial numbers in the series require special handling as they are part of the Fibonacci series definition. Therefore, we can add conditions at the beginning:

const fibonacciPosition = (n) => {

if (n === 0) return 1;

if (n === 1) return 2;

const phi = (1 + Math.sqrt(5)) / 2;

const position = Math.log(n * 5 ** 0.5 + 0.5) / Math.log(phi);

return Math.floor(position) + 1;

};

Lastly, we should check whether the number is a Fibonacci number before performing calculations:

const fibonacciPosition = (n) => {

if (!isFibonacci(n)) return -1;

if (n === 0) return 1;

if (n === 1) return 2;

const phi = (1 + Math.sqrt(5)) / 2;

const position = Math.log(n * 5 ** 0.5 + 0.5) / Math.log(phi);

return Math.floor(position) + 1;

};

With this, we have wrapped up the topic.

Before I conclude, I’d like to note that in the functions, I added 1 to the position (in both fibonacciPosition(n) and fibonacci(n)) to assign the first position an index of 1. However, if we intend to work with arrays where the first position has an index of 0, it would be simpler to omit this adjustment.

Thank you for reading! Stay tuned for more insights.

Don’t miss my next article — sign up for my Medium email list.

Join Medium with my referral link — Samuele Read every story from Samuele (and thousands of other writers on Medium). Not a Medium member? Join here and a piece of…

el3um4s.medium.com

Originally published at https://blog.stranianelli.com on December 21, 2022.

More content at **PlainEnglish.io*. Sign up for our free weekly newsletter. Follow us on Twitter, LinkedIn, YouTube, and Discord.*

Interested in scaling your software startup? Check out **Circuit*.*

Share the page:

Twitter Facebook Reddit LinkIn

-----------------------

Recent Post:

Navigating Life After the Pandemic: Embracing Change and Growth

Explore the challenges and opportunities for growth as we transition back to life after the pandemic.

How I Became One of the Top 1% of Female Earners

Discover the mindset and strategies that helped me join the top 1% of female earners in America.

New Journey: My 1,828 Days of Sobriety and Why I Won't Look Back

A transformative journey of sobriety after 1,828 days without alcohol, revealing the unexpected joys of life without drinking.

Unlock Your Mind: Five Transformative Books to Read Today

Discover five powerful books that can enhance your mindset, creativity, and personal growth for a more vibrant life.

Unlocking the Power of Functional Programming in JavaScript

Discover the essentials and advantages of functional programming in JavaScript to enhance your development skills.

Title: A Humble Admission Transformed Their Awkward Date

A simple act of humility changed the course of a couple's first date, sparking connection and chemistry.

The Fascinating Era of Dinosaurs: A Deep Dive into the Jurassic Period

Explore the Jurassic Period, the age of dinosaurs, and their evolution, alongside the rise of flowering plants.

Avoid These 4 Types of People for a Happier 2024

Discover four types of individuals to steer clear of in 2024 for a more peaceful and fulfilling year.