Best program for Permutation nPr of large numbers - c++

I am new to programming and was stuck at the permutation part. I have code which works for combination of large numbers which is stored in matrix but i am not able to find what should i change in that to get the result.
I tried the recursive method for permutations but could not achieve fast results.
This is the code which i got for combination what should be the change in condition which i should do here to get permutations?
void combination()
{
int i,j;
for(i=0;i<100;i++)
{
nCr[i][0]=1;
nCr[i][i]=1;
}
for(i=1;i<100;i++)
for(j=1;j<100;j++)
if (i!=j)
{
nCr[i][j] = (nCr[i-1][j] + nCr[i-1][j-1]);
}
}

A recurrence rule for permutations can be easily derived from the definition:
nPk = n*(n-1)*(n-2)* ... * (n-k+1) = n * (n-1)P(k-1)
Converted to code:
for(i=0;i<100;i++)
{
nPr[i][0]=1;
}
for(i=1;i<100;i++)
for(j=1;j<100;j++)
if (i!=j)
{
nPr[i][j] = i * nPr[i-1][j-1];
}
Note that the number of permutations grows fast and overflows the storage available for int: 13P11 for example is already out of range with signed 32bit integers.

well you can use the following pseudo-code for computing permutation and combination given that mod is always a very large prime number.
for permutation nPr
func permutation(r,n,mod):
q=factorial(n) // you should precompute them and saved in an array for a better execution time
r=(factorial(r))%mod
return (q*math.pow(r,mod-2))%mod
for combination nCr
func combination(r,n,mod):
q=factorial(n)
r=(factorial(r)*factorial(n-r))%mod
return (q*math.pow(r,mod-2))%mod
your should precompute factorials , for a decent execution time.
fact[100000]
fact[0]=fact[1]=1
func factorial_compute():
for x from 2 to 100000:
fact[x]=(x*fact[x-1])%mod
hence your factorial function will be
func factorial(x):
return(fact[x])
for reference on mathematics for this : http://mathworld.wolfram.com/ModularInverse.html

Actually, I know where the problem raised
At the point where we multiply , there is the actual problem ,when numbers get multiplied and get bigger and bigger.
this code is tested and is giving the correct result.
#include <bits/stdc++.h>
using namespace std;
#define mod 72057594037927936 // 2^56 (17 digits)
// #define mod 18446744073709551616 // 2^64 (20 digits) Not supported
long long int prod_uint64(long long int x, long long int y)
{
return x * y % mod;
}
int main()
{
long long int n=14, s = 1;
while (n != 1)
{
s = prod_uint64(s , n) ;
n--;
}
}

Related

c++ Recursion addition, 4*x

I have been trying to understand how to work on a function that returns the sum of a number like this: 1+2+3+4...4n by using recursion
I tried different cases without success and I am wondering if there is any mathematical way to solve it and translate it into code. I know that if I were this function:
int MyFunction(int x)
{
if (x==0)
return 0;
else{
return x+MyFunction(x-1);
}
}
and I used x=3 it would return 1+2+3 which is equal to 6 but in my case, I want to do something similar but up to 4 times the number. For example if x=1 it will return 1+2+3+4 since 4(1)=4. Then what returns is the addition of those numbers which is equal to 10
I tried thinking about simply converting the x to 4*x
int MyFunction(int x)
{
if (x==0)
return 0;
else{
return 4*x+MyFunction(x-1);
}
}
of course this didn't work, I also tried thinking that since everything was the same but by a factor of 4 thus MyFunction(4(x-1)) but obviously I am not thinking of this correctly. I wanted suggestions at least to understand the math behind it and how to relate it to code
nonrecursive solution
The sum of the members of a finite arithmetic progression is called an arithmetic series. For example, consider the sum:
1 + 2 + 3 + ... 4n-1 + 4n
This sum can be found quickly by taking the number of terms being added (here 4n), multiplying by the sum of the first and last number in the progression (here 1 + 4n = 4n+1), and dividing by 2.
The formula you are looking for is:
sum = 2n(4n+1)
A possible implementation can be:
int MyFunction(int n)
{
assert(n>0);
return 2*n*(4*n+1);
}
note: we do not checked a possible overflow
recursive solution
int recursive_sum(int k)
{
return (k>0) ? k+recursive_sum(k-1) : 0;
}
int recursive_MyFunction(int n)
{
assert(n>0);
return recursive_sum(4*n);
}
Check that both approaches give the same result
#include <cassert>
int MyFunction(int n) { ... as before ...}
int recursive_MyFunction(int n) { ... as before ...}
int main()
{
int n = 10; // whatever you want
assert(recursive_MyFunction(n)==MyFunction(n));
}

How is this code working for finding the number of divisors of a number?

http://www.spoj.com/problems/NDIV/
This is the problem statement. Since i'm new to programming, this particular problem ripped me off, I found this particular code on the internet which when I tried submitting got AC. I want to know how this code worked, as I have submitted it from online source which itself is bad idea for beginners.
#include <bits/stdc++.h>
using namespace std;
int check[32000];
int prime[10000];
void shieve()
{
for(int i=3;i<=180;i+=2)
{
if(!check[i])
{
for(int j=i*i;j<=32000;j+=i)
check[j]=1;
}
}
prime[0] = 2;
int j=1;
for(int i=3;i<=32000;i+=2)
{
if(!check[i]){
prime[j++]=i;
}
}
}
int main()
{
shieve();
int a,b,n,temp,total=1,res=0;
scanf("%d%d%d",&a,&b,&n);
int count=0,i,j,k;
for(i=a;i<=b;i++)
{
temp=i;
total=1;
k=0;
for(j=prime[k];j*j<=temp;j=prime[++k])
{
count=0;
while(temp%j==0)
{
count++;
temp/=j;
}
total *=count+1;
}
if(temp!=1)
total*=2;
if(total==n)
res++;
}
printf("%d\n",res);
return 0;
}
It looks like the code works on the sieve of eratosthenes, but a few things i'm unable to understand.
Why the limit of array "check" is 32000?
Again why the limit for array prime is 10000?
Inside main, whatever is happening inside the for loop of j.
Too many confusions regarding this approach, can someone explain the whole algorithm how it's working.
The hard limit on the arrays is set probably because the problem demands so? If not then just bad code.
Inside the inner loop, you are calculating the largest power of a prime that divides the number. Why? See point 3.
The number of factors of a number n can be calculated as follows:
Let n = (p1)^(n1) * (p2)^(n2) ... where p1, p2 are primes and n1, n2 ... are their exponents. Then the number of factors of n = (n1 + 1)*(n2 + 1)...
Hence the line total *= count + 1 which is basically total = total * (count + 1) (where count is the largest exponent of the prime number that divides the original number) calculates the number of prime factors of the number.
And yes, the code implements sieve of Eratosthenes for storing primes in a table.
(Edit Just saw the problem - you need at least 10^4 boolean values to store the primes (you don't actually need to store the values, just a flag indicating whether the values are prime or not). The condition given is 0 <= b - a <= 10^4 , So start your loop from a to b and check for the bool values stored in the array to know if they are prime or not.)

How make this even count code faster?

The following code is meant to find total numbers between l and r whose product of digits is even (for multiple test cases t). This code runs perfectly but is extremely slow for r greater than 100000. Can anyone suggest a better alternative?
#include <iostream>
#include <algorithm>
using namespace std;
long long int nd(long long int x, int n) //return the digit at a particular index staring with zero as index for unit place
{
while (n--) {
x /= 10;
}
return (x % 10);
}
int ng(long long int number) //returns total number of digits in an integer
{
int digits = 0;
if (number < 0) digits = 1;
while (number) {
number /= 10;
digits++;
}
return digits;
}
int main()
{
int t;
cin>>t;
long long int l[t], r[t], c;
for(long long int j=0;j<t;j++)
{
cin>>l[j]>>r[j];
}
for(long long int k=0;k<t;k++)
{
long long int sum=0;
long long int t=0;
for(long long int i=l[k];i<=r[k];i++)
{
while(t<ng(i))
{
c=nd(i,t);
if((c%2)==0)
{
++sum;
break;
}
++t;
}
t=0;
}
cout<<sum<<endl;
}
cin.ignore();
cin.get();
return 0;
}
The basic idea is to loop through each digit of a number and see if it's even. If it is, the whole product will be even and there's no need to check the remaining digits.
The problem with your code is that you run trough the number multiple times looking for a digit with index i. You should simply run through the number's digits once checking for evenness along the way.
Here's a self-explanatory Go code implementing the algorithm:
package main
func iseven(num int) bool {
for num > 0 {
digit := num % 10
if digit&1 == 0 { # same as digit%2 == 0, only simpler
return true
}
num /= 10
}
return false
}
func main() {
sum := 0
for n := 1; n < 1000000; n++ {
if iseven(n) {
sum++
}
}
println(sum)
}
Performance on my machine:
λ time go run main.go
980469
go run main.go 0.05s user 0.01s system 81% cpu 0.073 total
Update
If you need to work with ginormous numbers, then a more efficient approach can be used.
Let's call the numbers that have the product of their digits odd dodd numbers. So, 135 is a dodd number, 134 is not. Similarly, numbers that have the product of their digits even are called deven. So 134 is a deven number.
As has been mentioned earlier, only numbers that consist of odd digits are dodd. So instead of enumerating numbers, we can just count the numbers comprised of digits 1, 3, 5, 7, and 9. For integer N > 1, there are exactly 10^N - 10^(N-1) numbers that have N digits. And of those numbers, 5 ^ N are dodd, and therefore 10^N - 10^(N-1) - 5^N are deven.
The approach is to count how many dodd numbers there are in between the left and right bounds and then subtract that count from the total count of numbers between left and right. You could also count just deven numbers, but that is a bit trickier.
Effectively, you're going to loop through digits with this approach, instead of through numbers. My implementation in Python is able to compute the number of deven numbers between 1 and int("1" * 100000) (a number with 10000 digits) in under one second.
All numbers starting with, e.g., 10…, 12…, 14…, …, 2…, 30…, already are known to have an even product of digits. I would therefore start from the left (more significant digits) and count in blocks. There are only a few numbers whose product of digits is odd (such as 1111111111), only here you have to dig deeper.
Here is some pseudocode:
int count(String prefix, int digits) {
int result = 0;
if (digits == 0)
return 0;
for (int d = 0; d < 10; d++) {
if (d%2 == 0)
result += 10**(digits-1);
else
result += count(prefix . toString(d), digits-1);
}
return result;
}
This would be called like count("2", 8) to get the count for the interval from 200000000 to 299999999.
Here is a Haskell implementation for a whole block (i.e., all d-digit numbers):
blockcount :: Integer -> Integer
blockcount 0 = 0
blockcount d = 5 * 10^(d-1) + 5 * blockcount (d-1)
E.g., blockcount 1000 is calculated to be 9999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999066736381496781121009910455276182830382908553628291975378285660204033089024224365545559672902118897640405010069675757375784512478645967605158479182796069243765589333861674849726004924014098168488899509203734886881759487485204066209194821728874584896189301621145573518880530185771339040777982337089557201543830551112852533471993671631547352570738170137834797206804710506392882149336331258934560194469281863679400155173958045898786770370130497805485390095785391331638755207047965173135382342073083952579934063610958262104177881634921954443371555726074612482872145203218443653596285122318233100144607930734560575991288026325298250137373309252703237464196070623766166018953072125441394746303558349609375 in much less than a second.
You’d still have to add code that breaks your range into suitable blocks.
An optimisation based on the following would work:
Multiplying two numbers together gets you oddness / evenness according to the rule
even * even = even
odd * even = even * odd = even
odd * odd = odd
Therefore you only need to track the last digit of your number numbers.
I'm too old to code this but I bet it would be blisteringly quick as you only need to consider numbers between 0 and 9.
The only thing you need to check is if one of digits in the number is even. If it is, it will have 2 as a factor, and hence be even.
You also don't seem to remember where you are up to in digits - every time you increment t in your for loop, and then call nd(i,t), you count down from that t to zero in nd. This is quadratic in number of digits in the worst case. Better would be to simply break up the number into its component digits at the beginning.
I can't figure out what your code is doing, but the basic
principles are simple:
value % 10 is the low order digit
value /= 10 removes the low order digit
if any digit is even, then the product will be even.
This should lead to a very simple loop for each value. (You may
have to special case 0.)
Further optimizations are possible: all even numbers will have
a product of digits which is even, so you can iterate with
a step of 2, and then add in the number of evens (one half of
the range) afterwards. This should double the speed.
One further optimization: if the low order digit is even, the number itself is even, so you don't have to extract the low order digit to test it.
Another thing you could do is change
while(t<ng(i))
to
int d = ng(i);
while (t < d)
So ng is only called once per loop.
Also ng is just log(number)+1 (log base 10 that is)
I don't know is that will be quicker though.
First, please fix your indentation
Your code uses too many division and loops which cause a lot of delays
long long int nd(long long int x, int n) //return the digit at a particular index staring with zero as index for unit place
{
while (n--) {
x /= 10;
}
return (x % 10);
}
This can be fixed easily by a table lookup
long long int nd(long long int x, int n) //return the digit at a particular index staring with zero as index for unit place
{
long long int pow10[] = {1, 10, 100, 1000, 10000, 100000, 1000000, 10000000,
100000000, 1000000000, 10000000000, 100000000000,
1000000000000, 10000000000000, 100000000000000,
1000000000000000, 10000000000000000,
100000000000000000, 1000000000000000000};
return ((x / pow10[n]) % 10);
}
Likewise, the ng function to get total number of digits in an integer can be changed to a fast log10, no need to repeatedly divides and count. Ofcourse it'll need a small change to adapt 64 bit numbers
int ng(long long int number) //returns total number of digits in an integer
{
int digits = 0;
if (number < 0) digits = 1;
while (number) {
number /= 10;
digits++;
}
return digits;
}

Coding Competitions: How to store large numbers and find its all combination modulus P

I have started doing competitive programming and most of the time i find that the input size of numbers is like
1 <= n <= 10^(500).
So i understand that it would be like 500 digits which can not be stored on simple int memory. I know c and c++.
I think i should use an array. But then i get confused on how would i find
if ( (nCr % P) == 0 ) //for all (0<=r<=n)//
I think that i would store it in an array and then find nCr. Which would require coding multiplication and division on digits but what about modulus.
Is there any other way?
Thanks.
I think you don't want to code the multiplication and division yourself, but use something like the GNU MP Bignum library http://gmplib.org/
Regarding large number libraries, I have used ttmath, which provides arbitrary length integers, floats, etc, and some really good operations, all with relatively little bulk.
However, if you are only trying to figure out what (n^e) mod m is, you can do this for very large values of e even without extremely large number calculation. Below is a function I added to my local ttmath lib to do just that:
/*!
mod power this = (this ^ pow) % m
binary algorithm (r-to-l)
return values:
0 - ok
1 - carry
2 - incorrect argument (0^0)
*/
uint PowMod(UInt<value_size> pow, UInt<value_size> mod)
{
if(pow.IsZero() && IsZero())
// we don't define zero^zero
return 2;
UInt<value_size> remainder;
UInt<value_size> x = 1;
uint c = 0;
while (pow != 0)
{
remainder = (pow & 1 == 1);
pow /= 2;
if (remainder != 0)
{
c += x.Mul(*this);
x = x % mod;
}
c += Mul(*this);
*this = *this % mod;
}
*this = x;
return (c==0)? 0 : 1;
}
I don't believe you ever need to store a number larger than n^2 for this algorithm. It should be easy to modify such that it removes the ttmath related aspects, if you don't want to use those headers.
You can find the details of the mathematics online by looking up modular exponentiation, if you care about it.
If we have to calcuate nCr mod p(where p is a prime), we can calculate factorial mod p and then use modular inverse to find nCr mod p. If we have to find nCr mod m(where m is not prime), we can factorize m into primes and then use Chinese Remainder Theorem(CRT) to find nCr mod m.
#include<iostream>
using namespace std;
#include<vector>
/* This function calculates (a^b)%MOD */
long long pow(int a, int b, int MOD)
{
long long x=1,y=a;
while(b > 0)
{
if(b%2 == 1)
{
x=(x*y);
if(x>MOD) x%=MOD;
}
y = (y*y);
if(y>MOD) y%=MOD;
b /= 2;
}
return x;
}
/* Modular Multiplicative Inverse
Using Euler's Theorem
a^(phi(m)) = 1 (mod m)
a^(-1) = a^(m-2) (mod m) */
long long InverseEuler(int n, int MOD)
{
return pow(n,MOD-2,MOD);
}
long long C(int n, int r, int MOD)
{
vector<long long> f(n + 1,1);
for (int i=2; i<=n;i++)
f[i]= (f[i-1]*i) % MOD;
return (f[n]*((InverseEuler(f[r], MOD) * InverseEuler(f[n-r], MOD)) % MOD)) % MOD;
}
int main()
{
int n,r,p;
while (~scanf("%d%d%d",&n,&r,&p))
{
printf("%lld\n",C(n,r,p));
}
}
Here, I've used long long int to stote the number.
In many. many cases in these coding competitions, the idea is that you don't actually calculate these big numbers, but figure out how to answer the question without calculating it. For example:
What are the last ten digits of 1,000,000! (factorial)?
It's a number with over five million digits. However, I can answer that question without a computer, not even using pen and paper. Or take the question: What is (2014^2014) modulo 153? Here's a simple way to calculate this in C:
int modulo = 1;
for (int i = 0; i < 2014; ++i) modulo = (modulo * 2014) % 153;
Again, you avoided doing a calculation with a 6,000 digit number. (You can actually do this considerably faster, but I'm not trying to enter a competition).

Array Division - What is the best way to divide two numbers stored in an array?

I have two arrays (dividend, divisor):
dividend[] = {1,2,0,9,8,7,5,6,6};
divisor[] = {9,8};
I need the result (dividend/divisor) as:
quotient[] = {1,2,3,4,5,6,7};
I did this using array subtraction:
subtract divisor from dividend until dividend becomes 0 or less than divisor, each time incrementing quotient by 1,
but it takes a huge time. Is there a better way to do this?
Do long division.
Have a temporary storage of size equal to the divisor plus one, and initialized to zero:
accumulator[] = {0,0,0};
Now run a loop:
Shift each digit of the quotient one space to the left.
Shift each digit of the accumulator one space to the right.
Take the next digit of the dividend, starting from the most-significant end, and store it to the least-significant place of the accumulator.
Figure out accumulator / divisor and set the least-significant place of the quotient to the result. Set the accumulator to the remainder.
Used to use this same algorithm a lot in assembly language for CPUs what didn't have division instructions.
Other than that, have you considered using BigInt class (or the equivalent thing in your language) which will already does this for you?
You can use long division http://en.wikipedia.org/wiki/Long_division
Is there a better way to do this?
You can use long division.
You can use Long division algorithm or the more general Polynomial Long Division.
Why not convert them to integers and then use regular division?
in pseudocode:
int dividend_number
foreach i in dividend
dividend_number *= 10
dividend_number += i
int divisor_number
foreach i in divisor
divisor_number *= 10
divisor_number += i
int answer = dividend_number / divisor_number;
There you go!
A is the divident.
B is the divisor.
C is the integer quotinent
R is the rest.
Each "huge" number is a vector retaining a big number. In huge[0] we retain the number of digits the number has and thren the number is memorized backwards.
Let's say we had the number 1234, then the corespoding vector would be:
v[0]=4; //number of digits
v[1]=4;
v[2]=3;
v[3]=2;
v[4]=1;
....
SHL(H,1) does: H=H*10;
SGN(A,B) Compares the A and B numbers
SUBSTRACT(A,B) does: A=A-B;
DIVIDHUGE: makes the division using the mentioned procedures...
void Shl(Huge H, int Count)
/* H <- H*10ACount */
{
memmove(&H[Count+1],&H[1],sizeof(int)*H[0]);
memset(&H[1],0,sizeof(int)*Count);
H[0]+=Count;
}
int Sgn(Huge H1, Huge H2) {
while (H1[0] && !H1[H1[0]]) H1[0]--;
while (H2[0] && !H2[H2[0]]) H2[0]--;
if (H1[0] < H2[0]) {
return -1;
} else if (H1[0] > H2[0]) {
return +1;
}
for (int i = H1[0]; i > 0; --i) {
if (H1[i] < H2[i]) {
return -1;
} else if (H1[i] > H2[i]) {
return +1;
}
}
return 0;
}
void Subtract(Huge A, Huge B)
/* A <- A-B */
{ int i, T=0;
for (i=B[0]+1;i<=A[0];) B[i++]=0;
for (i=1;i<=A[0];i++)
A[i]+= (T=(A[i]-=B[i]+T)<0) ? 10 : 0;
while (!A[A[0]]) A[0]--;
}
void DivideHuge(Huge A, Huge B, Huge C, Huge R)
/* A/B = C rest R */
{ int i;
R[0]=0;C[0]=A[0];
for (i=A[0];i;i--)
{ Shl(R,1);R[1]=A[i];
C[i]=0;
while (Sgn(B,R)!=1)
{ C[i]++;
Subtract(R,B);
}
}
while (!C[C[0]] && C[0]>1) C[0]--;
}