Checking if a number can be written as a product of some fibonacci numbers - algorithm

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)

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

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

Finding the combination of N numbers that their sum give number R

How it would be possible to find/guess the combination of N numbers such as 5 or 7 or whatever that gives a final number R?
For example, determine N = 5 and R = 15
The one possible result/guess that the 5 numbers in which their summation give 15 would be {1,2,3,4,5}
To get n floating point numbers that total a target r:
Fill an array of size n with random numbers in (0,1).
Find the total of the array. Call this T.
Multiply every element in the array by r/T.
-edit (thanks #ruakh) -
To account for floating point error, total the array again, calculate the delta from target, and update the array to correct for it however you like. This will be a very small number. It's probably fine to update the first element of the array, but if you want you could spread it across the full array.
This can be solved by backtracking, this is really slow, because it looks for all combinations, but if you only want one combination use K-1 0' and N, this sum = N
n = 15
k = 2
array = [0] * k
def comb (len, sum):
if len == k - 1:
array[len] = sum
print(array)
return
for i in range(0, n + 1):
if sum - i >= 0:
array[len] = i
comb(len + 1, sum - i)
comb(0, n)
Python code
import random
N = 5
R = 7
result = random.sample(range(0, int(R)), N-1)
result.append(R - sum(result))

count of even numbers having more exponent of 2

Suppose I have given a number n. I want to find out all then even numbers which are less than n, and also have a greater exponent of 2 in its prime factorization than that of the exponent of 2 in the prime factorization of n.
if n=18 answer is 4 i.e, 4,8,12,16.
Using a for loop from i=2 to less than n and checking for every i will show time limit exceeded in the code.
My approach is to count no of times i will continue to divide by 2. But constraints of n=10^18. So, i think its a O (1) operation . Can anyone help me to find any formula or algorithm to find the answer as fast as possible?
First assume n is an odd number. Obviously every even number less than n also has a greater exponent of 2 in its factorization, so the answer will be equal to (n−1) / 2.
Now suppose n is equal to 2 times some odd number p. There are (p−1) / 2 even numbers that are smaller than p, so it follows that there are also (p−1) / 2 numbers smaller than n that are divisible by at least 22.
In general, given any number n that is equal to 2k times some odd number q, there will be (q−1) / 2 numbers that are smaller than n and have a larger exponent of 2 (> 2k) in their factorization.
So a function like this should work:
def count_smaller_numbers_with_greater_power_of_2_as_a_factor(n):
assert n > 0
while n % 2 == 0:
n >>= 1
return (n-1) // 2
Example 1 (n = 18)
Since n is even, keep dividing it by 2 until you get an odd number. This only takes one step (because n / 2 = 9)
Count the number of even numbers that are less than 9. This is equal to (9−1) / 2 = 4
Example 2 (n = 1018)
In this case, n = 218 × 518. So if we keep halving n until we get an odd number, the result will be 518.
The number of even numbers that are less than 518 is equal to (518−1) / 2 = 1907348632812
Your division is limited by constant number 64 (for 10^18~2^64), and O(64)=O(1) in complexity theory.
Number of two's in value factorization is equal to the number of trailing zero bits in binary representation of this value, so you can use bit operations (like & 1 and right shift shr, >>) to accelerate code a bit or apply some bit tricks
First, suppose n = 2^k * something. Find out k:
long k = 0;
while(n % 2 == 0) { n >>= 1; k++; }
n <<= k;
Now that you know who is k, multiply 2^k by 2 to get the first power of 2 greater than 2^k:
long next_power = 1 << (k + 1); // same as 2^(k + 1)
And lastly, check if n is odd. If it isn't, print all the multiples of next_power:
if(k == 0){ //equivalent to testing n % 2 == 0
for(long i = next_power; i < n; i += next_power) cout<<i<<endl;
}
EXAMPLE: n = 18
k will be 1, because 18 = 2^1 * 9 and the while will finish there.
next_power will be 4 (= 1 << (k + 1) = 2 ^ (k + 1)).
for(long i = next_power; i < n; i += next_power) cout<<i<<endl; will print 4, 8, 12 and 16.
This is very easy to do with a gcd trick i found:
You can find the count by //4. So 10^18 has
In [298]: pow(10,18)//4
Out[298]: 250000000000000000
You can find the count of 18 by //4 which is 4
Fan any numbers that meet your criteria. You can check by using my
algorithm here, and taking the len of the array and conpare with the
number div//4 to see that that is the answer your looking for: an exact
match. You'll notice that it's every four numbers that don't have an
exponent of 2. So the count of numbers can be found with //4.
import math
def lars_last_modulus_powers_of_two(hm):
return math.gcd(hm, 1<<hm.bit_length())
def findevennumberswithexponentgreaterthan2lessthannum(hm):
if hm %2 != 0:
return "only for use of even numbers"
vv = []
for x in range(hm,1,-2):
if lars_last_modulus_powers_of_two(x) != 2:
vv.append(x)
return vv
Result:
In [3132]: findevennumberswithexponentgreaterthan2lessthannum(18)
Out[3132]: [16, 12, 8, 4]
This is the fastest way to do it as you skip the mod down the path to get the answer. Instantly get the number you need with lars_last_modulus_powers_of_two(num) which is one operation per number.
Here is some example to show the answer is right:
In [302]: len(findevennumberswithexponentgreaterthan2lessthannum(100))
Out[302]: 25
In [303]: 100//4
Out[303]: 25
In [304]: len(findevennumberswithexponentgreaterthan2lessthannum(1000))
Out[304]: 250
In [305]: 1000//4
Out[305]: 250
In [306]: len(findevennumberswithexponentgreaterthan2lessthannum(23424))
Out[306]: 5856
In [307]: 23424//4
Out[307]: 5856

Count "cool" divisors of given number N

I'm trying to solve pretty complex problem with divisors and number theory.
Namely for a given number m we can say that k is cool divisor if k<m k|m (k divides m evenly), and for a given number n the number k^n (k to the power of n) is not divisor of m. Let s(x) - number of cool divisors of x.
Now for given a and b we should find D = s(a) + s(a+1) + s(a+2) + s(a+3) + ... + s(a+b).
Limits for all values:
(1 <= a <= 10^6), (1 <= b <= 10^7), (2<=n<=10)
Example
Let's say a=32, b=1, n=3;
x = 32, n = 3 divisors of 32 are {1,2,4,8,16,32}. However only {4,8,16} fill the conditions so s(32) = 3
x = 33, n = 3 divisors of 33 are {1,3,11,33}. Only the numbers {3,11} fill the conditions so s(33)=2;
D = s(32) + s(33) = 3 + 2 = 5
What I have tried
We should answer all those questions for 100 test cases in 3 seconds time limit.
I have two ideas, the first one: I iterate in the interval [a, a+b] and for each value i in the range I check how many cool divisors are there for that value, we can check this in O(sqrt(N)) if the function for getting number of power of N is considered as O(1) so the total function for this is O(B*sqrt(B)).
The second one, I'm now sure if it will work and how fast it will be. First I do a precomputation, I have a for loop that iterates from 1 to N, where N = 10^7
and now in the range [2, N] for each number whose divisor is i, where i is in the range [2,N] and I check if i to the power of n is not divisor of j then we update that the number j has one more cool divisor. With this I think that the complexity will be O(NlogN) and for the answers O(B).
Your first idea works but you can improve it.
Instead of checking all numbers from 1 to sqrt(N) whether they are cool divisors, you can factorize N=*p0^q0*p1^q1*p2^q2...pk^qk*. Then the number of cool divisors should then be (q0+1)(q1+1)...(qk+1) - (q0/n+1)(q1/n+1)...(qk/n+1).
So you can first preprocess and find out all the prime numbers using some existing algo like Sieve of Eratosthenes and for each number N between [a,a+b] you do a factorization. The complexity should be roughly O(BlogB).
Your second idea works as well.
For each number i between [2,a+b], you can just check the multiples of i between [a,a+b] and see whether i is a cool divisor of those multiples. The complexity should be O(BlogB) as well. Some tricks can be played in this idea to speed up the program is that, once you don't need to use divide/mod operations from time to time to check whether i is a cool divisor. You can compute the first number m between [a, a+b] that i^n|m. This m should be m=ceiling(a/(i^n))(i^n). And then you know i^n|m+p*i does not hold for p between [1,i^(n-1) - 1] and holds for p=i^n-1. Basically, you know i is not a cool divisor every i^(n-1) multiples, and you do not need to use divide/mod to figure it out, which will speed the program up.

How to explain this algorithm for calculating the power of a number?

I am currently reading Skiena's "The Algorithm Design Manual".
He describes an algorithm for calculating the power of a number i.e. calculate a^n.
He begins by saying that the simplest algorithm is simply a*a*a ... *a, so we have a total of n-1 calculations.
He then goes on to say that there is an optimisation for that, and asks us to recognise that:
n = n/2 + n/2
and we can also say that
a^n = ((a^n/2)^2) (a to the n equals a to the n over 2, squared)
Which I understand so far. From these equations, he deduces an algorithm which performs only O(lg n) multiplications.
function power(a, n)
if (n = 0)
return(1)
x = power(a,n/2)
if (n is even)
return(x^2)
else
return(a*x^2)
It appears that x must be the current value computed so far. But still after reading this several times, I don't understand how from those equations he designed this algorithm, or even how it works. Can anyone explain?
The concept is simple. For example, compute the value of 38
You can use the obvious way which is 38 = 3 x 3 x 3 x 3 x 3 x 3 x 3 x 3 which takes 7 multiplication operations. Or there is a better way.
Let say that
If we know the value 34, we can compute 38 only in one multiplication operation, but we don't know the value of 34
If we know the value of 32, we can compute 34 in one multiplication operation.
And finally, we know that 32 can be easily compute by 3 x 3.
Going backward, it only takes 3 multiplication to compute 38 instead of 7
Here is the clearly view of the process:
32 = 3 x 3 = 9
34 = 32 x 32 = 9 x 9 = 81
38 = 34 x 34 = 81 x 81 = 6,561
Then, there is another problem, what if the power is odd number. For example: 39, how to deal with it? You can either do this
39 = 3 x 38 or
39 = 3 x 34 x 34
Lets call the algorithm that continuously multiple the number as Method A, and algorithm that continuously divide the power by two as Method B. How good is method A comparing to method B? For a small number such as 38, there is not much significant improvement, even those, we minimize the number of multiplication, but we also slightly increase the number of division operation.
So for 38
Multiplication Division
Method A: 7 0
Method B: 3 3
However, for the larger power, for example: 34,294,967,296
Multiplication Division
Method A: 4,294,967,295 0
Method B: 32 32
The difference is huge.
First of all, let's fix your algorithm:
function power( a, n )
if (n = 0)
return(1)
x = power(a,n/2)
if (n is even)
return(x*x)
else
return(a*x*x)
Say you want to calculate power(2,8), that is, 2^8 (^ is not XOR here, of course).
1) (a=2, n=8). 2^8 = (2^4)^2, so we have to calculate x=2^4, and then x*x to yield the final result. We have to call power() again to get x. power(2,4).
2) (a=2, n=4). 2^4 = (2^2)^2, so we have to calculate x=2^2, and then x*x to yield the final result. We have to call power() again to get x. power(2,2).
3) (a=2, n=2). 2^2 = (2^1)^2, so we have to calculate x=2^1, and then x*x to yield the final result. We have to call power() again to get x. power(2,1).
4) (a=2, n=1). 2^1 = (2^0)^2, so we have to calculate x=2^0, and then a*x*x to yield the final result. We have to call power() again to get x. power(2,0).
5) (a=2, n=0). 2^0 = 1 because n is 0, so we have the value of x that is returned to step #4.
4) (a=2, n=1, x=1). The final result for this step is a*x*x = 2*1*1=2, which is the value to be assigned to x in step #3.
3) (a=2, n=2, x=2). The final result for this step is x*x = 2*2 = 4. This is the result to be assigned to x in step #2.
2) (a=2, n=4, x=4). The final result for this step is x*x = 4*4 = 16. This is the result to be assigned to x in step #1.
1) (a=2, n=8, x=16). The final result for this step is x*x = 16*16 = 256. This is the result to be returned by power(2,8).
x = power(a, n/2)
will give you a^n/2. If even this whole statement is squared giving (a^n/2)^2. Now if n is odd, during n/2 a power of a^1 is lost so to get it back it is multiplied with a. This is according to the equation given.
This function is recursive, meaning that when called, it is going to call itself over and over again until some final condition is met. In this case, there are three final conditions that will stop the function from calling itself and return the result.
If I were you I would try to apply the algorithm manually on a couple of different values in order to understand.
The function power(...) appears to be written the way it is to handle the effects of integer division. Recall that under integer division rules, the fractional part is discarded. This will only affect odd integers since an even integer divided by two produces no remainder.
Thus whenever n is an even integer, the value computed for n/2 is exactly equal to n/2 and the top branch of the if can be taken: this is exactly what the equations stipulate.
Whenever n is an odd integer, the value computed for n/2 is actually equal to floor(n/2). In other words, the statement:
x = power(a,n/2)
Has actually computed the result
x = power(a,(n-1)/2)
Meaning that you have permanently lost one 1 from your exponent, and simply returning x^2 will be short one power of a. Hence the bottom branch, which adds back in the power of a.
If you imagine that instead of integer division, the computer was capable of perfectly lossless real number division, then you could rewrite the function as:
function power( a, n )
if (n = 0)
return(1)
x = power(a,n/2)
return x^2
You can easily satisfy yourself that this is a simple recursive implementation of the second equation you provided in the question.
This formula a^n = ((a^n/2)^2), which you understand dictates recursive algorithm.
To get a^n you need first to calculate a^(n/2),
To get a^(n/2), you need to calculate a^((n/2)/2),
... and so on, until (n/2/2/...2) reaches 0, which is the termination condition of the recursion.
So, the recursive algorithm follows that formula exactly :
to get power(a,n) you first recursively calculate power(a,n/2) and then return the result adjusting for n being odd/even number.
There is also wikipedia article about this implementation.

Finding the first number larger than N that is a relative prime to M

Basically, the title says everything. The numbers are not too big (the maximum for N is ~2/3 * max(long) and max M is max(long)), so I think even a simple solution that I currently have is sufficient. M is always bigger than N.
What I currently have:
Most simple, just start from N + 1, perform plain Euclidean GCD, and if it returns 1 we are done, if not increment and try again.
I would like to know what is the worst case scenario with this solution. Performance is not a big issue, but still I feel like there must be a better way.
Thanks.
About the worst case, I made a small test:
Random r = new Random();
while (true)
{
long num = (long) r.Next();
num *= r.Next();
f((long)(num * 0.61), num);
}
...
public static int max;
public static int f(long N, long M)
{
int iter = 0;
while (GCD(N++, M) != 1)
{
iter++;
}
if (iter > max)
{
max = iter;
Console.WriteLine(max);
}
return 0;
}
It is running for ~30 minutes and the worst case so far is 29 iterations. So I believe that there is a more precise answer then O(N).
I don't know the worst scenario, but using the fact that M < 264, I can bound it above by 292 iterations and below by 53 (removing the restriction that the ratio N/M be approximately fixed).
Let p1, …, pk be the primes greater than or equal to 5 by which M is divisible. Let N' ≥ N be the least integer such that N' = 1 mod 6 or N' = 5 mod 6. For each i = 1, …, k, the prime pi divides at most ceil(49/pi) of the integers N', N' + 6, N' + 12, …, N' + 288. An upper bound on ∑i=1,…,k ceil(49/pi) is ∑i=3,…,16 ceil(49/qi) = 48, where q is the primes in order starting with q1 = 2. (This follows because ∏i=3,…,17 ≥ 264 implies that M is the product of at most 14 distinct primes other than 2 and 3.) We conclude that at least one of the integers mentioned is relatively prime to M.
For the lower bound, let M = 614889782588491410 (product of the first fifteen primes) and let N = 1. After 1, the first integer relatively prime to the first fifteen primes is the sixteenth prime, 53.
I expect both bounds could be improved without too much work, though it's not clear to me for what purpose. For the upper bound, handle separately the case where 2 and 3 are both divisors of M, as then M can be the product of at most thirteen other primes. For the lower bound, one could try to find a good M by running the sieve of Eratosthenes to compute, for a range of integers, the list of primes dividing those integers. Then sweep a window across the range; if the product of the distinct primes in the window is too large, advance the trailing end of the window; otherwise, advance the leading end.
Sure it's not O(n), By knowing that prime number gaps is logen we can simply say your algorithm has at most logen iterations,(because after passing at most logen number you will see new prime number which is prime respect to your given number n) for more detail about this gap, you can see prime numbers gap.
So for your bounded case it is smaller than logen = loge264 <= 44 and it will be smaller than 44 iterations.

Resources