Skip to main content
5 of 5
edited tags; edited tags
200_success
  • 144.1k
  • 22
  • 188
  • 473

Testing Fibonacci conjecture

The sequence of Fibonacci numbers is defined as F1 = 1, Fn = Fn−2 + Fn−1. It has been conjectured that for any Fibonacci number F, F2 + 41 is composite.

... [T]ask is to either prove the conjecture to be true or find a counter-example that demonstrates it is false.

(source)

Here is my working code for this problem - although I don't know the conjecture is either true or false in general.

I tested it for first 107 natural numbers, also for first 1000 Fibonacci numbers - and it seems conjecture is true. but I takes a lot of time (80-90 seconds) to spit out a result.

As you see in last three functions, I have 3 method to test conjecture.

  • First one (fibonacci_conjecture) generates a sequence of Fib2+41s and returns result of primality test.

  • Second one is similar to first, but it first checks if numbers in a given range are Fibonacci numbers or not.

  • Third one seems more optimal. As we know from definition, for a given Fibonacci number f, 5f2+4 or 5f2-4 is perfect square. If we add 41 to both of them we'll have 5f2+45 or 5f2+37. The first one is always divisible by 5, so there's no need to check these values.

How can this code be written in an optimal way, for faster results? Or, which techniques should I follow (either within the code or within the math)?

import math

def is_perfect_square(x):
    return int(math.sqrt(x)) == math.sqrt(x)

def is_fibo(x):
    c = 5*x*x
    return is_perfect_square(c+4) or is_perfect_square(c-4)

def is_prime(x):
    c = int(math.sqrt(x))+2
    if (x%2==0 and x!=2) or is_perfect_square(x): return False
    else:
        for i in range(2, c):
            if x%i==0: return False
    return True

def minus_four(fib):
    if is_fibo(fib) and fib>0: return is_perfect_square(5*fib*fib-4)

def fibo(x):
    if x<2: return 1
    else: return fibo(x-1)+fibo(x-2)
    
def fibonacci_conjecture(end):
    return (True not in map(is_prime, [fibo(i)*fibo(i)+41 for i in range(end+1)]))
                                                                                                          
def second_way(end):
    return (True not in map(is_prime, [i**2+41 for i in range(end+1) if is_fibo(i)]))
                                                                                                    
def third_way(end):
    return (True not in map(is_prime, [fibo(i)*fibo(i)+41 for i in range(end+1) if minus_four(i)]))

There is also a brute-force like implementation. that checks if 5x2+37 is prime, then checks if that number is a Fibonacci number.

from fibonacci_conjecture import * # functions above
import time
from sys import argv

script, start, end = argv

_list = []

start_time = time.time()
for i in range(int(start), int(end)):
    if is_prime(5*i*i+37) and is_fibo(5*i*i+37): _list.append(i)
print _list
print time.time() - start_time
                                                                      

Results calling the last one from Terminal:

$ python timings.py 0 1000
[]
0.0163550376892
$ python timings.py 1000 2000
[]
0.0392298698425
$ python timings.py 2000 12000
[]
1.66012907028
$ python timings.py 12000 42000
[]
35.4742548466
$ python timings.py 42000 43000
[]
2.01177597046
$ python timings.py 43000 48000
[]
11.1937119961