OCaml fatorial is 0 - ocaml

I want to have a code that calculates the Narayana numbers. https://en.wikipedia.org/wiki/Narayana_number
However, it starts to present '0' for numbers over 20.
What might be failing?
let rec factorial n =
if n <= 1 then 1
else factorial (n-1) * n;;

factorial 21 overflows and returns an incorrect result.
The max_int value of on my 64bit setup is 4611686018427387903, which is just between 20! and 21!.
The to get around this you can avoid actually calculating the value of n! (or k!) ub binomial_coeff. Instead calculate more complex values. For instance, instead of n!/k!, you can use (k+1)*(k+2)*...*n.

You missed a piece of code, that is factorial (n) as numerator:
let binomial_coeff (n:int) (k:int) =
if k = 0 || k = n then 1
else factorial (n) / (factorial (k) * factorial (n-k));;

Related

Product of three primes divisible by sum of those primes

I found this problem in a cp contest which is over now so it can be answered.
Three primes (p1,p2,p3) (not necessarily distinct) are called special if (p1+p2+p3) divides p1*p2*p3. We have to find the number of these special pairs if the primes can't exceed 10^6
I tried brute force method but it timed out. Can there be any other method?
If you are timing out, then you need to do some smart searching to replace brute force. There are just short of 80,000 primes below a million so it is not surprising you timed out.
So, you need to start looking more carefully.
For example, any triple (2, p, p+2) where p+2 is also prime will meet the criteria:
2 + 3 + 5 = 10; 2 * 3 * 5 = 30; 30 / 10 = 3.
2 + 5 + 7 = 14; 2 * 5 * 7 = 70. 70 / 14 = 5.
...
2 + p + p+2 = 2(p+2); 2 * p * (p+2) = 2p(p+2); 2p(p+2) / 2(p+2) = p.
...
Are there other triples that start with 2? Are there triples that start with 3? What forms do p2 and p3 take if p1= 3? Run your program for triples up to 500 or so and look for patterns in the results. Then extrapolate those results to 10^6.
I assume you are using a Sieve to generate your initial list of primes.
I've experimented with this problem since you posted it. I've not solved it, but wanted to pass along what insight I have before I move onto something else:
Generating Primes is Not the Issue
With a proper sieve algorithm, we can generate all primes under 10**6 in a fraction of a second. (Less than 1/3 of a second on my Mac mini.) Spending time optimizing prime generation beyond this is time wasted.
The Brute Force Method
If we try to generate all permutations of three primes in Python, e.g.:
for prime_1 in primes:
for prime_2 in primes:
if prime_2 < prime_1:
continue
for prime_3 in primes:
if prime_3 < prime_2:
continue
pass
Or better yet, push the problem down to the C level via Python's itertools:
from itertools import combinations_with_replacement
for prime_1, prime_2, prime_3 in combinations_with_replacement(primes, 3):
pass
Then, our timings, doing no actual work except generating prime triples, looks like:
sec.
10**2 0.04
10**3 0.13
10**4 37.37
10**5 ?
You can see how much time increases with each order of magnitude. Here's my example of a brute force solution:
from itertools import combinations_with_replacement
def sieve_primes(n): # assumes n > 1
sieve = [False, False, True] + [True, False] * ((n - 1) // 2)
p = 3
while p * p <= n:
if sieve[p]:
for i in range(p * p, n + 1, p):
sieve[i] = False
p += 2
return [number for number, isPrime in enumerate(sieve) if isPrime]
primes = sieve_primes(10 ** 3)
print("Finished Sieve:", len(primes), "primes")
special = 0
for prime_1, prime_2, prime_3 in combinations_with_replacement(primes, 3):
if (prime_1 * prime_2 * prime_3) % (prime_1 + prime_2 + prime_3) == 0:
special += 1
print(special)
Avoid Generating Triples, but Still Brute Force
Here's an approach that avoids generating triples. We take the smallest and largest primes we generated, cube them, and loop over them with a custom factoring function. This custom factoring function only returns a value for those numbers that are made up of exactly three prime factors. For any number made up of more or less, it returns None. This should be faster than normal factoring as the function can give up early.
Numbers that factor into exactly three primes are easy to test for specialness. We're going to pretend our custom factoring function takes no time at all and simply measure how long it takes us to loop over all the numbers in question:
smallest_factor, largest_factor = primes[0], primes[-1]
for number in range(smallest_factor**3, largest_factor**3):
pass
Again, some timings:
sec.
10**2 0.14
10**3 122.39
10**4 ?
Doesn't look promising. In fact, worse than our original brute force method. And our custom factoring function in reality adds a lot of time. Here's my example of this solution (copy sieve_primes() from the previous example):
def factor_number(n, count):
size = 0
factors = []
for prime in primes:
while size < count and n % prime == 0:
factors.append(prime)
n //= prime
size += 1
if n == 1 or size == count:
break
if n > 1 or size < count:
return None
return factors
primes = sieve_primes(10 ** 3)
print("Finished Sieve:", len(primes), "primes")
special = 0
smallest_factor, largest_factor = primes[0], primes[-1]
for number in range(smallest_factor**3, largest_factor**3):
factors = factor_number(number, 3)
if factors:
if number % sum(factors) == 0:
special += 1
print(special)

Fastest way to find dividers of a number in C++

I am trying to do an exercise in which you should find number of dividers of factorial of nth number:
https://www.e-olymp.com/en/problems/124
So here is my code:
int fact(int n){
return (n==1 || n==0) ? 1 : n*fact(n-1);
}
long long int a,b=1,c=0;
cin>>a;
long long int y=fact(a);
while(b!=y){
if(y%b==0){
c++;
}
b++;
}
cout<<c+1<<endl;
But this code takes too much time and I need something quicker. Don't give code, algorithm will be enough.
In this task 1 <= N <= 45. Obviously, N is too large to calculate it directly.
You should implement another approach. Just iterate from the 1 to N and do the prime factorization for every i, 1 < i <= N. Then you can easily find the prime factorization of N!, just merge factorization of every i, 1 < i <= N. After that calculate the total number of divisors using previously calculated factorization.
Example for 6!:
2 = 2
3 = 3
4 = 2 ^ 2
5 = 5
6 = 3 * 2
So:
6! = 2 ^ 4 * 3 ^ 2 * 5
And the number of divisors:
(4 + 1) * (2 + 1) * (1 + 1) = 30
Use a bit of mathematics.
If you know the prime factors of a number, it is trivial to calculate the number of divisors.
And it's easy to find the prime factors of a factorial. Without calculating the factorial itself.

Find minimum prime numbers which sum to a given value

I want to find the minimum set of prime numbers which would sum to a given value e.g. 9 = 7 + 2 (not 3+3+3).
I have already generated a array of prime numbers using sieve of eratosthens
I am traversing the array in descending order to get the array largest prime number smaller than or equal to given number. This works great if the number is odd.
But fails for even numbers e.g 122 = 113 + 7 + 2 but 122 = 109 +13.
From Golbach's Conjecture we know that any even number can be represented as two sum of two prime numbers. So if a number is even we can directly return 2 as output.
But I am trying to figure out a way other than brute force to find minimum prime numbers.
Although your question didn't say so, I assume you are looking for the set of primes that has the smallest cardinality.
If n is even, then consider the primes p in order, 2, 3, 5, …; eventually n - p will be prime, so n is the sum of two primes. This process typically converges very quickly, with the smaller of the two primes seldom larger than 1000 (and usually much smaller than that).
If n is odd, and n - 2 is prime, then n is the sum of the primes 2 and n - 2.
If n is odd, and n - 2 is not prime, then n - 3 is even and can be written as the sum of two primes, as described above.
Thus you can always find two or three primes that sum to any target n greater than 3.
Try this out!
Not an ideal code but if you want to have a working solution :P
primes = [2,3,5,7]
D = 29
i = -1
sum_ = 0
count = 0
while sum_ != D :
sum_ = sum_ + primes[i]
count += 1
if (sum_ == D) :
break
elif D - sum_ == primes[i-1] :
count += 1
break
elif D - sum_ < ex[i-1] and (D-sum_ not in primes) :
sum_ = sum_ - primes[i]
count = count - 1
i = i - 1
print(count)

Dynamic Programming solution for a Recursion solution

Given an input n , find the sum of all the possible combinations of numbers 1 ... n.
For example, if n=3 , then all the possible combinations are
(1),(2),(3),(1,2),(1,3),(2,3),(1,2,3)
and their sum is
1 + 2 + 3 + (1+2) + (1+3) + (2+3) + (1+2+3) =24
I am able to solve this problem using recursion. How can I solve this problem using Dynamic Programming ?
#include<iostream>
using namespace std;
int sum=0,n;
int f(int pos,int s)
{
if(pos>n)
{
return 0;
}
else
{
for(int i=pos+1;i<=n;++i)
{
sum+=s+i;
f(i,s+i);
}
}
}
int main()
{
cin>>n;
sum=0;
f(0,0);
cout<<sum<<'\n';
}
}
EDIT
Though this problem can be solved in constant time using this series.
But I want to know how this can be done using Dynamic Programming as I am very weak at it.
You do not need to use dynamic programming; you can use simple arithmetic if you want.
The number of cases is 2 ^ n, since each number is either on or off for a given sum.
Each number from 1 to n is used in exactly half of the sums, so each number comes 2 ^ (n-1) times.
1 + 2 + ... + n = (n - 1) * n / 2.
So the sum is (n - 1) * n / 2 * 2 ^ (n-1).
For n = 3, it is (4*3/2) * 4 = 24.
EDIT: if you really want to use dynamic programming, here's one way.
Dynamic programming makes use of saving the results of sub-problems to make the super problem faster to solve. In this question, the sub-problem would be the sum of all combinations from 1 ... n-1.
So create a mapping from n -> (number of combinations, sum of combinations).
Initialize with 1 -> (2,1). Because there are two combinations {0,1} and the sum is 1. Including 0 just makes the math a bit easier.
Then your iteration step is to use the mapping.
Let's say (n-1) -> (k,s), meaning there are k sets that sum to s for 1 ... n-1.
Then the number of sets for n is k * 2 (each combination either has n or does not).
And the sum of all combinations is s + (s + k * n), since you have the previous sum (where n is missing) plus the sum of all the combinations with n (which should be k * n more than s because there are k new combinations with n in each).
So add n -> (2*k,2*s + k*n).
And your final answer is the s in n -> (k,s).
let dp[n] be the result, Therefore:
dp[1] = 1
dp[n] = 2 * dp[n-1] + 2^(n-1) * n
First, it is obvious that dp[1] = 1
Second, dp[n] is the sum which contains n and sum which didn't contains n
E.G: dp[3] = {(1) (2) (1,2)} + {(3), (1,3), (2,3), (1,2,3)}
We can find dp[n-1] appear twice and the number of n appear 2^(n-1) times
I think maybe it is what you want.

Number of calls for nth Fibonacci number

Consider the following code snippet:
int fib(int N)
{
if(N<2) return 1;
return (fib(N-1) + fib(N-2));
}
Given that fib is called from main with N as 10,35,67,... (say), how many total calls
are made to fib?
Is there any relation for this problem?
PS: This is a theoretical question and not supposed to be executed.
EDIT:
I am aware of other methods for the faster computation of Fibonacci series.
I want a solution for computing number of times fib is invoked for fib(40),fib(50) ,.. without the aid of compiler and in exam condition where you are supposed to answer 40 question similar to this one in a stipulated of time ( about 30 mints).
Thanks,
Let f(n) be the number of calls made to calculate fib(n).
If n < 2 then f(n) = 1.
Otherwise, f(n) = 1 + f(n - 1) + f(n - 2).
So, f is at least O(fib(n)). In fact, f(n) is 2 * fib(n) - 1. We show this by induction:
Base cases (n < 2, that is, n = 0 or n = 1):
f(n) = 1 = 2 * 1 - 1 = 2 * fib(n) - 1.
Induction step (n >= 2):
f(n + 1) = f(n) + f(n - 1) + 1
f(n + 1) = 2 * fib(n) - 1 + 2 * fib(n - 1) - 1 + 1
f(n + 1) = 2 * fib(n + 1) - 1
There exist efficient ways to calculate any Fibonacci term. Thus the same holds for f(n).
Is there any relation for this problem
?
There is a close-form equation for the nth fibonacci number: http://en.wikipedia.org/wiki/Fibonacci_number#Closed_form_expression
In the pseudocode you posted, the number of calls satisfies the recurrence relation
x(n) = x(n-1) + x(n-2) +1 # for n>=2
x(1) = 1
x(0) = 1
This is almost same as the Fibonacci recurrence relation. Proof by induction can show that the number of calls to fib made by fib(n) is equal to 2*fib(n)-1, for n>=0.
Of course, the calculation can be sped up by using the closed form expression, or by adding code to memorize previously computed values.
As mentioned above, you need to solve the following recurring equation:
K(n)=K(n-1)+K(n-2)+1
Let's write it for n-1: K(n-1)=K(n-2)+K(n-3)+1
Now, subtract the second one from the first one:
K(n)-K(n-1) = K(n-1) - K(n-3),
or
K(n) - 2*K(n-1) + K(n-3) = 0.
The respective characteristic equation will be:
x^3 - 2*x^2 + 1 = 0.
It has the following roots: 1, (1+sqrt(5))/2, (1-sqrt(5))/2
Thus for any real A,B,C the following function
K(n) = A*(1)^n + B*((1+sqrt(5))/2)^n + C*((1-sqrt(5))/2)^n
will be a solution for your equation.
To find A,B,C you need to define several initial values K(0), K(1), K(2) and solve the system of equations.
phi is a constant
position = ceil(log((n - 0.5)*sqrt(5))/log(phi));
n is the fibonacci number...
position will give you the which fibonacci number is n
for example given 13 , position will be 7 - 0 1 1 2 3 5 8 13
using this position just calculate the fibonacci number at position-1 or any position you want relative to given fibonacci number.
Previous Fibo Num = floor((pow(phi,position-1)/sqrt(5))+0.5);
floor((pow(phi, position)/sqrt(5))+0.5) - is the standard formula for calculating Nth fibonacci num (Note - This is not an approximation)
I have just reverse this formula to calculate the position and use the position - 1 to calculate the previous fibonacci number.
Ref - http://itpian.com/Coding/20951-Given-the-Nth-fib-no-and-find-the--N-1-th-fib-number-without-calculating-from-the-beginning---------.aspx
This is a classic problem for solving with Recurrence Relations.
Specifically, the fibonacci problem has the following parameters:
f(0) = 1
f(1) = 1
f(n) = f(n-1) + f(n-2)
Once you master solving recurrences, you'll have no problem reaching the solution (which, incidently, is exactly the same as fib(n)).
Interesting question, I can't give you a formula, but I wrote a Ruby program to do it, it works on numbers I figured out on paper, and it should work for any.
#!/usr/bin/ruby
#find out how many times fib() would need to be called
def howmany(n)
a = [ ]
a.push n-1
a.push n-2
while a.select{|n| n > 2}.length > 0
a.map! do |n|
n > 2 ? [n-1,n-2] : n
end
a.flatten!
end
a.length
end
.
>> howmany(10)
=> 55
It's slow.. I'm figuring out 35 right now, I'll edit when it finishes.
Edit:
>> howmany(35)
=> 9227465