When addressed exponentiation in chapter 2, the author mentioned
"The number of multiplications required is clearly at most 2 log n(the base is 2), because at
most two multiplications (if n is odd) are required to halve the problem. Again,a recurrence formula can be written and solved."
The code as follow:
int pow( int x, unsigned int n)
{
/*1*/ if( n == 0 )
/*2*/ return 1;
/*1*/ if( n == 1 )
/*4*/ return x;
/*5*/ if( even( n ) )
/*6*/ return( pow( x*x, n/2 ) );
else
/*7*/ return( pow( x*x, n/2 ) * x );
}
Q:
As the author said,
2^16 need at most 8 multiplications
2^15 ... 7 ...
2^14 ... 7 ...
2^13 ... 7 ...
2^12 ... 7 ...
In fact, I perfrom the code:
2^16 .... 4 ...
2^15 .... 6 ...
2^14 ... 5 ...
2^13 ... 5 ...
2^12 ... 4 ...
So, is somewhere wrong?
There's no contradiction or mistake -- the book gives an upper bound, and you're looking at the exact number of multiplications.
The exact number of multiplications (for n>0) is floor(log_2(n)) + bitcount(n) - 1. That's just by inspecting the code -- the even cases (which perform one multiplication) correspond to 0 bits in the input, the odd cases (which perform an extra multiplication) correspond to 1 bits in the input, and the code stops when it reaches the highest bit.
The book says that 2*log_2(n) is an upper bound for the number of multiplications. That's consistent with the exact formula: floor(log_2(n)) <= log_2(n) and bitcount(n) - 1 <= log_2(n). So floor(log_2(n)) + bitcount(n) - 1 <= 2*log_2(n).
From the exact formula, you can see that the lower the bitcount of n, the worse the upper bound is. The very worst cases are when n is a power of 2: then exactly log_2(n) multiplications will be performed, and the upper bound is off by a factor of 2. The very best cases are when n is one less than a power of 2: then the upper bound will be off by only 1. That matches your empirical table of results.
Finding x^n will take at most 2 log n multiplications, since it is possible for n/2 to be odd at every iteration. For example:
pow(2, 15) --> pow(2 * 2, 7) * 2
--> pow(4 * 4, 3) * 4 * 2
--> pow(16 * 16, 1) * 16 * 4 * 2
This is six multiplications (two multiplications per function call); 2 * log(15) ~= 7.8. So the upper bound is satisfied. The best case is n a power of 2, which takes only log n multiplications.
To calculate the complexity, consider that this algorithm reduces n by half k times, until n is between 1 and 2; that is, we have:
1 ≤ n⁄2k < 2
So:
2k ≤ n < 2k+1
⇒ k ≤ log n < k+1
⇒ (log n) - 1 < k ≤ log n
Thus, the algorithm takes log n steps, and since the worst case is two multiplications per step, at most 2 log n multiplications are required.
Related
Problem Statement:
Given a positive integer n, find the least number of perfect square numbers (for example, 1, 4, 9, 16, ...) which sum to n.
Example 1:
Input: n = 12
Output: 3
Explanation: 12 = 4 + 4 + 4.
Example 2:
Input: n = 13
Output: 2
Explanation: 13 = 4 + 9.
Using the following knowledge about squares (given below) we can implement the following solution.
A natural number is...
... a square if and only if each prime factor occurs to an even power in the number's prime factorization.
... a sum of two squares if and only if each prime factor that's 3 modulo 4 occurs to an even power in the number's prime factorization.
... a sum of three squares if and only if it's not of the form 4a(8b+7) with integers a and b.
... a sum of four squares. Period. No condition. You never need more than four.
int numSquares(int n) {
while (n % 4 == 0)
n /= 4;
if (n % 8 == 7)
return 4;
for (int a=0; a*a<=n; ++a) {
int b = sqrt(n - a*a);
if (a*a + b*b == n)
return 1 + !!a;
}
return 3;
}
Question:
Can someone help me understand what exactly are we trying to achieve in following for loop?
I'm a little lost here.
for (int a=0; a*a<=n; ++a) {
int b = sqrt(n - a*a);
if (a*a + b*b == n)
return 1 + !!a;
}
The loop is trying to find two squares that sum to n.
Rather than trying every combination of numbers to see if we can square them and they add up to n, we just loop through the possibilities for one of the numbers -- this is a. We square that with a*a, and subtract that from n. We then get the integer part of the square root of this difference, and this is b. If a2+b2 adds up to n, this is the pair of squares that we're looking for.
We need to calculate the sum of the squares in case n - a*a wasn't a perfect square. In that case its square root will have a fraction in it, which will be lost when we convert it to an integer. In other words, testing a*a+b*b == n allows us to determine whether the square root was an integer.
I got a problem about finding the smallest N, where N! contains exactly k trailing zeros.
I've got an idea of finding it through binary search from here - Finding natural numbers having n Trailing Zeroes in Factorial .
Is it possible to calculate it without binary search, using any formula or some iterations?
You can use the formula that the number of times p divides n! is:
k = floor(n/p) + floor(n/p^2) + floor(n/p^3) + ...
Combining this with the fact that the number of trailing zeros is exactly equal to the number of times 5 evenly divides it (each zero corresponds to a 2 and 5 pair, but given 2 is less than 5, we'll always have more 2s than 5s, and thus be constrained by our 5s).
With some algebra, and applying the formula for an infinite geometric series, we can get a very (very!) close lower bound on n. We then just increment n by 5 as much as necessary get the actual result. In practice, this ends up being 1-2 increments for k in the lower thousands, so its fairly negligible.
Full code below:
def count_div5(n):
result = 0
pow5 = 5
while pow5 <= n:
result += n // pow5
pow5 *= 5
return result
def n_from_fact_zeros(k):
n = round(4*k)
n += -n % 5
while count_div5(n) < k:
n += 5
return n
I found the following code for computing nCr, but don't understand the logic behind it. Why does this code work?
long long combi(int n,int k)
{
long long ans=1;
k=k>n-k?n-k:k;
int j=1;
for(;j<=k;j++,n--)
{
if(n%j==0)
{
ans*=n/j;
}else
if(ans%j==0)
{
ans=ans/j*n;
}else
{
ans=(ans*n)/j;
}
}
return ans;
}
that's a clever code!
In general it aims to calculate the following formula:
ans = n! / (k!)(n-k)!
It is equal to:
ans = n(n-1)(n-2) ... (n-k)...1 / k(k-1)...1 * (n-k)(n-k-1) ... 1
And after obvious cancellation:
ans = n(n-1)(n-2)..(n-k+1) / k!
Now notice that nominator and denominator have the same number of elements (k element)
So the calculation of ans will be like the following:
ans = 1 // initially
ans *= n/1
ans *= (n-1)/2
ans *= (n-2)/3
.
.
.
ans *= (n-k+1)/k
take a look again at the code and you notice that:
ans is being multiplied by n at each iteration
n is reduced by 1 at each iteration (n--)
ans is divided by j at each iteration
This is exactly what is done by the posted code, Now let's see the meanings of different conditions in the loop, with nominator starting from n and denominator from 1 to k, so variable j is assigned to denominator right?
1) if(n%j==0)
at each step if n/j is (computable) So we calculate it first here than multiply to the whole ans, this practice keeps the result at its smallest possible value.
2) else if(ans%j==0)
at each step if we couldn't calculate n/j but actually can calculate ans/j so that's not bad to say :
ans /= j; //first we divide
ans *= n; //then we multiply
This is always keeping our overall output as small as possible, right?
3) last condition
at each step, if we couldn't compute neither n/j nor ans/j in this case we are not lucky enough to divide first then multiply (hence keeping the result small). But well we need to carry on even-though we are left with only one choice which is
ans *= n; // multiply first
ans /= j; // then divide
ET VOILA!
Example
consider the case 3C7
we know that the answer is 7!/ 3!*4!
hence : ans = 7*6*5 / 1*2*3
let's see what happen at each iteration:
//1
ans = 1
//2
n = 7
j = 1
ans = ans * n/j
first compute 7/1 = 7
then multiply to ans
ans = 1*7
ans = 7
//3
n = 6
j = 2
ans = ans* n/j
evaluate n/j = 6/2 (can be divided)
n/j = 3
ans = ans *(n/j)
= 7 * 3
= 21
// 4
n = 5
j = 3
ans = ans * n/j
evaluate n/j = 5/3 oppsss!! (first if)
evaluate ans/j = 21/3 = 7 YES (second if)
ans = (ans/j)*n
= 7*5
= 35
// end iterations
Note that in last iteration if we calculate straight forward we would say:
ans = ans*n/j
= 21 * 5 / 3
= 105 / 3
= 34
yes it does find right result but meanwhile the value flies up to 105 before getting back to 35. Now imagine calculating real large numbers?!
Conclusion
This code is computing carefully the binomial coefficients trying to keep the output as small as possible at each step of calculation, it does that by checking if it is possible to divide (int) then execute, hence it is capable of calculating some very big kCn that the straightforward coding cannot handle (OverFlow may occur)
To answer the question in part, consider the fact that the entries of n choose k constitute Pascal's triangle. As Pascal's triangle is symmetric, it is sufficient to move the argument k into the left half, which is done with the
k=k>n-k?n-k:k;
statement; see the definition of C's conditional operator.
Furthermore, the result ans is initialized in the beginning to contain 1, which is the first entry of every row in Pascal's triangle, which means that initially, ans is in fact n choose j.
The fact is that nCr for 1<=k<=n/2 is same as in n/2+1<=k<=n.so first change in k so that it values lies value in the left half.One more thing nCk means (n*(n-1).....(n-k))/(k*(k-1)*....*2*1) so the above code apply it iteratively.
yes.
[N choose K] reduces its factorials a lot because the dividend and divisor share many factors that cancel each other out to x/x=1 (for x>0)
the trick is to not calculate the large factorials, because these large factors require too much address space (too many bits)
the first trick is to reduce the fraction, before dividing.
the second trick is to do modulo within a conditional to chose one of 3 operations for the current iteration. this can be done differently, and integer modulo is chosen to be a fast operator, skipping some slower integer division approaches.
you iteratively traverse pascals triangle.
with each path that you take, you multiply something.
There are 3 possible branching paths for every iterative step:
each of the 3 steps multiplies the accumulator "ans" with a different value, representing the factor between 2 "positions" on pascals triangle.
you always end up doing N multiplications, where N is the number of iterations, and end up at the binomial coefficient's value.
N is the column # of pascals triangle that you want to know, and you accumulate an N, multiplied by something, while reducing the number of column s (and lines) of pascals triangle by N=N-1 for each iteration.
j=1;
ans=0;
//within each iteration;
ans=ans*n;
n=n-1;
ans=ans/j;
j=n+1;
the integer division is slow and can be skipped (or made faster by making the divisor smaller) at least once, and often many more times (because there are a lot of shared prime factors in pascals triangle), this is being done by the modulo conditionals.
pascals triangle is extremely symmetric (on summing up its domains), therefore this works.
the difference between (partial) sums of columns of pascals triangle shows the symmetry that is important for the multiplications and divisions here.
just watch some youtube videos on the symmetries and identities of pascals triangle.
Forgive me if I am being a bit silly, but I have only very recently started programming, and am maybe a little out of my depth doing Problem 160 on Project Euler. I have made some attempts at solving it but it seems that going through 1tn numbers will take too long on any personal computer, so I guess I should be looking into the mathematics to find some short-cuts.
Project Euler Problem 160:
For any N, let f(N) be the last five digits before the trailing zeroes
in N!. For example,
9! = 362880 so f(9)=36288 10! = 3628800 so f(10)=36288 20! =
2432902008176640000 so f(20)=17664
Find f(1,000,000,000,000)
New attempt:
#include <stdio.h>
main()
{
//I have used long long ints everywhere to avoid possible multiplication errors
long long f; //f is f(1,000,000,000,000)
f = 1;
for (long long i = 1; i <= 1000000000000; i = ++i){
long long p;
for (p = i; (p % 10) == 0; p = p / 10) //p is i without proceeding zeros
;
p = (p % 1000000); //p is last six nontrivial digits of i
for (f = f * p; (f % 10) == 0; f = f / 10)
;
f = (f % 1000000);
}
f = (f % 100000);
printf("f(1,000,000,000,000) = %d\n", f);
}
Old attempt:
#include <stdio.h>
main()
{
//This part of the programme removes the zeros in factorials by dividing by 10 for each factor of 5, and finds f(1,000,000,000,000) inductively
long long int f, m; //f is f(n), m is 10^k for each multiple of 5
short k; //Stores multiplicity of 5 for each multiple of 5
f = 1;
for (long long i = 1; i <= 100000000000; ++i){
if ((i % 5) == 0){
k = 1;
for ((m = i / 5); (m % 5) == 0; m = m / 5) //Computes multiplicity of 5 in factorisation of i
++k;
m = 1;
for (short j = 1; j <= k; ++j) //Computes 10^k
m = 10 * m;
f = (((f * i) / m) % 100000);
}
else f = ((f * i) % 100000);
}
printf("f(1,000,000,000,000) = %d\n", f);
}
The problem is:
For any N, let f(N) be the last five digits before the trailing zeroes in N!. Find f(1,000,000,000,000)
Let's rephrase the question:
For any N, let g(N) be the last five digits before the trailing zeroes in N. For any N, let f(N) be g(N!). Find f(1,000,000,000,000).
Now, before you write the code, prove this assertion mathematically:
For any N > 1, f(N) is equal to g(f(N-1) * g(N))
Note that I have not proved this myself; I might be making a mistake here. (UPDATE: It appears to be wrong! We'll have to give this more thought.) Prove it to your satisfaction. You might want to start by proving some intermediate results, like:
g(x * y) = g(g(x) * g(y))
And so on.
Once you have obtained a proof of this result, now you have a recurrence relation that you can use to find any f(N), and the numbers you have to deal with don't ever get much larger than N.
Prod(n->k)(k*a+c) mod a <=> c^k mod a
For example
prod[ 3, 1000003, 2000003,... , 999999000003 ] mod 1000000
equals
3^(1,000,000,000,000/1,000,000) mod 1000000
And number of trailing 0 in N! equals to number of 5 in factorisation of N!
I would compute the whole thing and then separate first nonzero digits from LSB ...
but for you I think is better this:
1.use bigger base
any number can be rewrite as sum of multiplies of powers of the same number (base)
like 1234560004587786542 can be rewrite to base b=1000 000 000 like this:
1*b^2 + 234560004*b^1 + 587786542*b^0
2.when you multiply then lower digit is dependent only on lowest digits of multiplied numbers
A*B = (a0*b^0+a1*b^1+...)*(b0*b^0+b1*b^1+...)
= (a0*b0*b^0)+ (...*b^1) + (...*b^2)+ ...
3.put it together
for (f=1,i=1;i<=N;i++)
{
j=i%base;
// here remove ending zeroes from j
f*=j;
// here remove ending zeroes from f
f%=base;
}
do not forget that variable f has to be big enough for base^2
and base has to be at least 2 digits bigger then 100000 to cover 5 digits and overflows to zero
base must be power of 10 to preserve decimal digits
[edit1] implementation
uint<2> f,i,j,n,base; // mine 64bit unsigned ints (i use 32bit compiler/app)
base="10000000000"; // base >= 100000^2 ... must be as string to avoid 32bit trunc
n="20"; // f(n) ... must be as string to avoid 32bit trunc
for (f=1,i=1;i<=n;i++)
{
j=i%base;
for (;(j)&&((j%10).iszero());j/=10);
f*=j;
for (;(f)&&((f%10).iszero());f/=10);
f%=base;
}
f%=100000;
int s=f.a[1]; // export low 32bit part of 64bit uint (s is the result)
It is too slow :(
f(1000000)=12544 [17769.414 ms]
f( 20)=17664 [ 0.122 ms]
f( 10)=36288 [ 0.045 ms]
for more speed or use any fast factorial implementation
[edit2] just few more 32bit n! factorials for testing
this statement is not valid :(
//You could attempt to exploit that
//f(n) = ( f(n%base) * (f(base)^floor(n/base)) )%base
//do not forget that this is true only if base fulfill the conditions above
luckily this one seems to be true :) but only if (a is much much bigger then b and a%base=0)
g((a+b)!)=g(g(a!)*g(b!))
// g mod base without last zeroes...
// this can speed up things a lot
f( 1)=00001
f( 10)=36288
f( 100)=16864
f( 1,000)=53472
f( 10,000)=79008
f( 100,000)=56096
f( 1,000,000)=12544
f( 10,000,000)=28125
f( 1,000,100)=42016
f( 1,000,100)=g(??????12544*??????16864)=g(??????42016)->42016
the more is a closer to b the less valid digits there are!!!
that is why f(1001000) will not work ...
I'm not an expert project Euler solver, but some general advice for all Euler problems.
1 - Start by solving the problem in the most obvious way first. This may lead to insights for later attempts
2 - Work the problem for a smaller range. Euler usually give an answer for the smaller range that you can use to check your algorithm
3 - Scale up the problem and work out how the problem will scale, time-wise, as the problem gets bigger
4 - If the solution is going to take longer than a few minutes, it's time to check the algorithm and come up with a better way
5 - Remember that Euler problems always have an answer and rely on a combination of clever programming and clever mathematics
6 - A problem that has been solved by many people cannot be wrong, it's you that's wrong!
I recently solved the phidigital number problem (Euler's site is down, can't look up the number, it's quite recent at time of posting) using exactly these steps. My initial brute-force algorithm was going to take 60 hours, I took a look at the patterns solving to 1,000,000 showed and got the insight to find a solution that took 1.25s.
It might be an idea to deal with numbers ending 2,4,5,6,8,0 separately. Numbers ending 1,3,7,9 can not contribute to a trailing zeros. Let
A(n) = 1 * 3 * 7 * 9 * 11 * 13 * 17 * 19 * ... * (n-1).
B(n) = 2 * 4 * 5 * 6 * 8 * 10 * 12 * 14 * 15 * 16 * 18 * 20 * ... * n.
The factorial of n is A(n)*B(n). We can find the last five digits of A(n) quite easily. First find A(100,000) MOD 100,000 we can make this easier by just doing multiplications mod 100,000. Note that A(200,000) MOD 100,000 is just A(100,000)*A(100,000) MOD 100,000 as 100,001 = 1 MOD 100,000 etc. So A(1,000,000,000,000) is just A(100,000)^10,000,000 MOD 100,000.
More care is needed with 2,4,5,6,8,0 you'll need to track when these add a trailing zero. Obviously whenever we multiply by numbers ending 2 or 5 we will end up with a zero. However there are cases when you can get two zeros 25*4 = 100.
I am stuck in a program while finding modulus of division.
Say for example I have:
((a*b*c)/(d*e)) % n
Now, I cannot simply calculate the expression and then modulo it to n as the multiplication and division are going in a loop and the value is large enough to not fit even in long long.
As clarified in comments, n can be considered prime.
I found that, for multiplication, I can easily calculate it as:
((a%n*b%n)%n*c%n)%n
but couldn't understand how to calculate the division part then.
The problem I am facing is say for a simple example:
((7*3*5)/(5*3)) % 11
The value of above expression would be 7
but if I calculate the multiplication, modulo, it would be like:
((7%11)*(3%11))%11 = 10
((10%11)*(5%11))%11 = 6
now I am left with 6/15 and I have no way to generate correct answer.
Could someone help me. Please make me understand the logic by above example.
Since 11 is prime, Z11 is a field. Since 15 % 11 is 4, 1/15 equals 3 (since 3 * 4 % 11 is 1). Therefore, 6/15 is 6 * 3 which is 7 mod 11.
In your comments below the question, you clarify that the modulus will always be a prime.
To efficiently generate a table of multiplicative inverses, you can raise 2 to successive powers to see which values it generates. Note that in a field Zp, where p is an odd prime, 2p-1 = 1. So, for Z11:
2^1 = 2
2^2 = 4
2^3 = 8
2^4 = 5
2^5 = 10
2^6 = 9
2^7 = 7
2^8 = 3
2^9 = 6
So the multiplicative inverse of 5 (which is 24) is 26 (which is 9).
So, you can generate the above table like this:
power_of_2[0] = 1;
for (int i = 1; i < n; ++i) {
power_of_2[i] = (2*power_of_2[i-1]) % n;
}
And the multiplicative inverse table can be computed like this:
mult_inverse[1] = 1;
for (int i = 1; i < n; ++i) {
mult_inverse[power_of_2[i]] = power_of_2[n-1-i];
}
In your example, since 15 = 4 mod 11, you actually end up with having to evaluate (6/4) mod 11.
In order to find an exact solution to this, rearrange it as 6 = ( (x * 4) mod 11), which makes clearer how the modulo division works.
If nothing else, if the modulus is always small, you can iterate from 0 to modulus-1 to get the solution.
Note that when the modulus is not prime, there may be multiple solutions to the reduced problem. For instance, there are two solutions to 4 = ( ( x * 2) mod 8): 2 and 6. This will happen for a reduced problem of form:
a = ( (x * b) mod c)
whenever b and c are NOT relatively prime (ie whenever they DO share a common divisor).
Similarly, when b and c are NOT relatively prime, there may be no solution to the reduced problem. For instance, 3 = ( (x * 2) mod 8) has no solution. This happens whenever the largest common divisor of b and c does not also divide a.
These latter two circumstances are consequences of the integers from 0 to n-1 not forming a group under multiplication (or equivalently, a field under + and *) when n is not prime, but rather forming simply the less useful structure of a ring.
I think the way the question is asked, it should be assumed that the numerator is divisible by the denominator. In that case the finite field solution for prime n and speculations about possible extensions and caveats for non-prime n is basically overkill. If you have all the numerator terms and denominator terms stored in arrays, you can iteratively test pairs of (numerator term, denominator term) and quickly find the greatest common divisor (gcd), and then divide the numerator term and denominator term by the gcd. (Finding the gcd is a classical problem and you can easily find a simple solution online.) In the worst case you will have to iterate over all possible pairs but at some point, if the denominator indeed divides the numerator, then you'll eventually be left with reduced numerator terms and all denominator terms will be 1. Then you're ready to apply multiplication (avoiding overflow) the way you described.
As n is prime, dividing an integer b is simply multiplying b's inverse. That is:
(a / b) mod n = (a * inv(b)) mod n
where
inv(b) = (b ^ (n - 2)) mod n
Calculating inv(b) can be done in O(log(n)) time using the Exponentiation by squaring algorithm. Here is the code:
int inv(int b, int n)
{
int r = 1, m = n - 2;
while (m)
{
if (m & 1) r = (long long)r * b % n;
b = (long long)b * b % n;
m >>= 1;
}
return r;
}
Why it works? According to Fermat's little theorem, if n is prime, b ^ (n - 1) mod n = 1 for any positive integer b. Therefore we have inv(b) * b mod n = 1.
Another solution for finding inv(b) is the Extended Euclidean algorithm, which needs a bit more code to implement.
I think you can distribute the division like
z = d*e/3
(a/z)*(b/z)*(c/z) % n
Remains only the integer division problem.
I think the problem you had was that you picked a problem that was too simple for an example. In that case the answer was 7 , but what if a*b*c was not evenly divisible by c*d ? You should probably look up how to do division with modulo first, it should be clear to you :)
Instead of dividing, think in terms of multiplicative inverses. For each number in a mod-n system, there ought to be an inverse, if certain conditions are met. For d and e, find those inverses, and then it's all just multiplying. Finding the inverses is not done by dividing! There's plenty of info out there...