Home > Back-end >  Checking if a number can be written as a product of some fibonacci numbers
Checking if a number can be written as a product of some fibonacci numbers

Time:10-23

I have tried to solve the problem above but I got stuck. I guess that it all comes to factorization by non-prime numbers. The number could be really big - about 10^15.

What I attempted to do is to factor the x and all the Fibonacci numbers up to about 155th(this is the one that is over 10^30, and that means that I can not include its factors in my x's factors), then just like in normal factorization, I loop from the highest Fibonacci number to the lowest and check if my x has all the factors of the i-th Fibonacci number. If it does then I divide x by it. When I get to the i=1(I looped through all the Fibonacci factors table), I just check if my x is equal to 1. If it is, then my answer is YES, otherwise it is NO.

This solution does not work, because sometimes it divides x in way which rules out further division, so I tried to split it into two loops - the first one can divide the x by only Fibonacci numbers which have at least one number which does not belong to the Fibonacci sequence, and the second one can divide by every number.

I took factored Fibonacci numbers from this website: http://www.maths.surrey.ac.uk/hosted-sites/R.Knott/Fibonacci/fibtable.html

Here is an example which destroys the 1st idea:

x=2^10 × 3^5 × 5^2 × 7 × 11 × 17 × 23 × 47 × 89 × 1103

I divide it by: 48th number, 12th, 11th, 10th and after that I can't get rid of the 17 so my answer is no, but it should be yes dividing by: 48th, 11th, 10th, 9th, 10th, 6th, 5th, 3*4th.

My 2nd idea is a little bit weird so that is why I wrote it. Is my solution correct? Or maybe there is another which can determine if the number can be written as a product of Fibonacci numbers? (Note that x can be really big)

CodePudding user response:

Without relying on any special properties of Fibonnacci numbers, you could categorise this as a coin change problem, where the available coins are the Fibonacci numbers, and the target must be achieved via multiplication instead of addition.

A solution is then to use a recursive algorithm combined with memoization to avoid the same subproblem to be solved repeatedly (principle of dynamic programming).

Here is a demo implementation in JavaScript, which runs the algorithm for the problem you mentioned in the question:

// Preprocessing: collect all Fibonacci numbers with 15 digits or less:
let fib = [];
let a = 1, b = 2;
while (b < 1e16) {
    fib.push(b);
    [a, b] = [b, a b];
}
fib.reverse(); // Put greatest Fib numbers first

let memo = new Map(); // For memoization
function solve(n, start=0) {
    if (n === 1) return true;
    let result = memo.get(n);
    if (result === undefined) { // Not in map:
        let i;
        for (i = start; i < fib.length; i  ) {
            if (n % fib[i] == 0) {
                // Try solving problem after division by this factor:
                if (solve(n / fib[i], i)) break;
            }
        }
        result = i < fib.length;
        memo.set(n, result);
    }
    return result;
}

// Example input from question:
n = 2**10 * 3**5 * 5**2 * 7 * 11 * 17 * 23 * 47 * 89 * 1103
console.log(n, solve(n)); // 864126051784934400 true
<iframe name="sif1" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>

CodePudding user response:

Your first idea is almost correct: a tiny modification makes it work. By Carmichael's theorem, every Fibonacci number except 1, 8, and 144 has a prime divisor that does not divide any smaller Fibonacci number. Since 8 and 144 can both be written as the product of Fibonacci numbers themselves, we can ignore them when trying to find divisors.

// Given: integer N
F <- [2, 3, 5, 8, 13...] // All Fibonacci numbers x, 1 < x <= N
F.reverse() // put in decreasing order

for x in F:
    if x == 8 or x == 144: continue
    while N % x == 0:
        N = N / x

return (N == 1)

Ignoring 8 and 144, this works because if f is the largest Fibonacci number dividing N, then f has a prime factor p that no earlier Fibonacci number has, so we have to divide p out of N as many times as possible if it is to be written as a product of Fibonacci numbers.

In fact, up to the isomorphism of replacing (8 with 2^3) and (144 with 2^4 * 3^2 or 8 * 2 * 3^2), this factorization has to be unique by that argument.

  • Related