C++ combination function always resulting 0 - c++

can anybody tell me why my Combination function is always resulting 0 ?
I also tried to make it calculate the combination without the use of the permutation function but the factorial and still the result is 0;
#include <iostream>
#include <cmath>
using namespace std;
int factorial(int& n)
{
if (n <= 1)
{
return 1;
}
else
{
n = n-1;
return (n+1) * factorial(n);
}
}
int permutation(int& a, int& b)
{
int x = a-b;
return factorial(a) / factorial(x);
}
int Combination(int& a, int& b)
{
return permutation(a,b) / factorial(b);
}
int main()
{
int f, s;
cin >> f >> s;
cout << permutation(f,s) << endl;
cout << Combination(f,s);
return 0;
}

Your immediate problem is that that you pass a modifiable reference to your function. This means that you have Undefined Behaviour here:
return (n+1) * factorial(n);
// ^^^ ^^^
because factorial(n) modifies n, and is indeterminately sequenced with (n+1). A similar problem exists in Combination(), where b is modified twice in the same expression:
return permutation(a,b) / factorial(b);
// ^^^ ^^^
You will get correct results if you pass n, a and b by value, like this:
int factorial(int n)
Now, factorial() gets its own copy of n, and doesn't affect the n+1 you're multiplying it with.
While we're here, I should point out some other flaws in the code.
Avoid using namespace std; - it has traps for the unwary (and even for the wary!).
You can write factorial() without modifying n once you pass by value (rather than by reference):
int factorial(const int n)
{
if (n <= 1) {
return 1;
} else {
return n * factorial(n-1);
}
}
Consider using iterative code to compute factorial.
We should probably be using unsigned int, since the operations are meaningless for negative numbers. You might consider unsigned long or unsigned long long for greater range.
Computing one factorial and dividing by another is not only inefficient, it also risks unnecessary overflow (when a is as low as 13, with 32-bit int). Instead, we can multiply just down to the other number:
unsigned int permutation(const unsigned int a, const unsigned int b)
{
if (a < b) return 0;
unsigned int permutations = 1;
for (unsigned int i = a; i > a-b; --i) {
permutations *= i;
}
return permutations;
}
This works with much higher a, when b is small.
We didn't need the <cmath> header for anything.
Suggested fixed code:
unsigned int factorial(const unsigned int n)
{
unsigned int result = 1;
for (unsigned int i = 2; i <= n; ++i) {
result *= i;
}
return result;
}
unsigned int permutation(const unsigned int a, const unsigned int b)
{
if (a < b) return 0;
unsigned int result = 1;
for (unsigned int i = a; i > a-b; --i) {
result *= i;
}
return result;
}
unsigned int combination(const unsigned int a, const unsigned int b)
{
// C(a, b) == C(a, a - b), but it's faster to compute with small b
if (b > a - b) {
return combination(a, a - b);
}
return permutation(a,b) / factorial(b);
}

You dont calculate with the pointer value you calculate withe the pointer address.

Related

LCM and GCD not working

I made a program for codechef and its wrong apparantly (although all tests have been positive). The code is:
#include <iostream>
using namespace std;
int g (int a,int b){
return b == 0 ? a : g(b, a % b);
}
int l (int a, int b){
return (a*b)/(g(a,b));
}
int main() {
int n;
cin >> n;
int a[n],b[n];
for (int x = 0;x<n;x++){
cin >> a[x] >> b[x];
}
for (int x = 0;x<n;x++){
cout << g(a[x],b[x]) << " "<< l(a[x],b[x]) << endl;
}
return 0;
}
Codechef won't tell me what integers dont work, and im pretty sure my gcd function is legit.
Since gcd is properly defined as the largest non-negative common divisor, you can save yourself the annoying details of signed division, e.g.,
static unsigned gcd (unsigned a, unsigned b)
{
/* additional iteration if (a < b) : */
for (unsigned t = 0; (t = b) != 0; a = t)
b = a % b;
return a;
}
Likewise for lcm; but the problem here is that (a*b) may overflow. So if you have two large (signed) int values that are co-prime, say: 2147483647 and 2147483629, then gcd(a,b) == 1, and (a*b)/g overflows.
A reasonable assumption on most platforms is that unsigned long long is twice the width of unsigned - although strictly speaking, it doesn't have to be. This is also a good reason to use exact types like [u]int32_t and [u]int64_t.
One thing you can be sure of is that a/g or b/g will not cause any issues. So a possible implementation might be:
static unsigned long long lcm (unsigned a, unsigned b)
{
return ((unsigned long long) a) * (b / gcd(a, b)));
}
If your test values are 'positive' (which is what I think you mean), you can cast them prior to (unsigned) prior to call. Better yet - replace all your int variables with unsigned int (though the loop variables are fine), and save yourself the trouble to begin with.

int limit in permutation program (C++)

I wrote a simple C++ program that computes permutations/factorials in 2 different methods. The problem arises when I try to use the longer method (p1) with 20 and 2. Granted, "20!" is a HUGE number. Is there a limit with integers when calculating the factorial using the recursion method?
#include <iostream>
using namespace std;
int p1(int n, int r);
int p2(int n, int r);
int factorial(int x);
int main()
{
cout << p1(10, 8) << endl;
cout << p2(10, 8) << endl;
cout << p1(4, 3) << endl;
cout << p2(4, 3) << endl;
cout << p1(20, 2) << endl; // THE NUMBER PRINTS INCORRECTLY HERE
cout << p2(20, 2) << endl;
system("PAUSE");
return EXIT_SUCCESS;
}
int p1(int n, int r) // long version, recursively calls factorial
{
return (factorial(n) / factorial(n - r));
}
int factorial(int x)
{
if (x == 0)
return 1;
else if (x > 0)
return (x * factorial(x - 1));
}
int p2(int n, int r) // shortcut, does arithmetic in for loop
{
int answer = n;
for (int i = 1; i < r; i++)
{
answer *= n - 1;
n--;
}
return answer;
}
20! is 2.4*10^18
You can check out a reference of limits.h to see what the limits are.
consider that 2^32 is 4.2*10^9. long int is usually a 32-bit value.
consider that 2^64 is 1.8*10^19, so a 64-bit integer will get you through 20! but no more. unsigned long long int should do it for you then.
unsigned long long int p1(int n, int r)
{
return (factorial(n) / factorial(n - r));
}
unsigned long long int factorial(unsigned long long int x)
{
if (x == 0)
return 1;
else if (x > 0)
return (x * factorial(x - 1));
}
unsigned long long int p2(int n, int r)
{
unsigned long long int answer = n;
for (int i = 1; i < r; i++)
{
answer *= n - 1;
n--;
}
return answer;
}
If you are allowed in this assignment, consider using float or double, unless you need absolute precision, or just need to get to 20 and be done. If you do need absolute precision and to perform a factorial above 20, you will have to devise a way to store a larger integer in a byte array like #z32a7ul states.
Also you can save an operation by doing answer *= --n; to pre-decrement n before you use it.
20! exceeds the integer range. Your shortcut function doesn't exceed simply because you don't calculate the whole faculty, but 20*19
If you really need it, you may create a class that holds a variable-length array of bytes, and define operators on it. In that case, only the available memory and your patiance will limit the size of numbers. I think Scheme (a LISP dialect) does something like that.

Find the number of ways the N balls could be placed in the M boxes

You have N different balls numbered from 1 to N, and M different boxes numbered from 1 to M.
Input:
First line of input contains the number of test cases T. After that, next T lines contain the value of N and M.
Output:
For each test case, print the answer. As it can be very large, you should print it modulo 10^9 + 7.
I tried the below code, but it gives an error:
#include<iostream>
#include<cmath>
#include<math.h>
using namespace std;
int main()
{
unsigned short int T;
unsigned long int N,M;
cin>>T;
for (int i = 0; i < T; i++)
{
cin>>N>>M;
long int res;
res= pow(M,N);
int c=0;
c=pow(10,9);
res=res%(c + 7);
cout<<res<<endl;
}
return 0;
}
You must be facing integer overflow problem, that's why you must have been getting wrong answer.
Do the following steps to fix this problem.
change the unsigned long to long long or unsigned long long. (Why? Think).
Use the logarithmic user-defined function to calculate the value of the res = pow(M,N) along with the modulo consideration side-by-side. This will boost up your program.
See my code snippet to check what changes to be made:
#include<iostream>
#define MOD 1000000007
int main() {
unsigned short int T;
unsigned long long N , M , result;
unsigned long long power(unsigned long long, unsigned long long); /*prototype of power*/
std::cin>>T;
for (int i = 0; i < T; i++) {
std::cin >> N >> M;
result = power(M , N);
std::cout << result << std::endl;
}
return 0;
}
unsigned long long power(unsigned long long M, unsigned long long N) {
if(N == 0) {
return 1;
}
unsigned long long result = power(M , N/2);
result = (result * result) % MOD;
if(N%2 == 1) {
result = (result * M) % MOD;
}
return result;
}

Counting number of digits in an integer through recursion

My code is following:
/counting number of digits in an integer
#include <iostream>
using namespace std;
int countNum(int n,int d){
if(n==0)
return d;
else
return (n/10,d++);
}
int main(){
int n;
int d;
cout<<"Enter number"<<endl;
cin>>n;
int x=countNum();
cout<<x;
return 0;
}
i cannot figure out the error,it says that
: too few arguments to function `int countNum(int, int)'
what is issue?
Because you declared the function to take two arguments:
int countNum(int n,int d){
and you are passing none in:
int x = countNum();
You probably meant to call it like this, instead:
int x = countNum(n, d);
Also this:
return (n/10,d++);
should probably be this:
return countNum(n/10,d++);
Also you are not initializing your n and d variables:
int n;
int d;
Finally you don't need the d argument at all. Here's a better version:
int countNum(int n){
return (n >= 10)
? 1 + countNum(n/10)
: 1;
}
and here's the working example.
int x=countNum(); the caller function should pass actual arguments to calling function. You have defined function countNum(int, int) which means it will receive two ints as arguments from the calling function, so the caller should pass them which are missing in your case. Thats the reason of error too few arguments.
Your code here:
int x=countNum();
countNum needs to be called with two integers. eg
int x=countNum(n, d);
Because you haven't passed parameters to the countNum function. Use it like int x=countNum(n,d);
Assuming this is not for an assignment, there are better ways to do this (just a couple of examples):
Convert to string
unsigned int count_digits(unsigned int n)
{
std::string sValue = std::to_string(n);
return sValue.length();
}
Loop
unsigned int count_digits(unsigned int n)
{
unsigned int cnt = 1;
if (n > 0)
{
for (n = n/10; n > 0; n /= 10, ++cnt);
}
return cnt;
}
Tail End Recursion
unsigned int count_digits(unsigned int n, unsigned int cnt = 1)
{
if (n < 10)
return cnt;
else
return count_digits(n / 10, cnt + 1);
}
Note: With tail-end recursion optimizations turned on, your compiler will transform this into a loop for you - preventing the unnecessary flooding of the call stack.
Change it to:
int x=countNum(n,0);
You don't need to pass d in, you can just pass 0 as the seed.
Also change countNum to this:
int countNum(int n,int d){
if(n==0)
return d;
else
return coutNum(n/10,d+1); // NOTE: This is the recursive bit!
}
#include <iostream>
using namespace std;
int countNum(int n,int d){
if(n<10)
return d;
else
return countNum(n/10, d+1);
}
int main(){
int n;
cout<<"Enter number"<<endl;
cin>>n;
int x=countNum(n, 1);
cout<<x;
return 0;
}
Your function is written incorrectly. For example it is not clear why it has two parameters or where it calls recursively itself.
I would write it the following way
int countNum( int n )
{
return 1 + ( ( n /= 10 ) ? countNum( n ) : 0 );
}
Or even it would be better to define it as
constexpr int countNum( int n )
{
return 1 + ( ( n / 10 ) ? countNum( n/10 ) : 0 );
}

Curious behaviour of inverse modulo

I wrote the following code to calculate n!modulo p...Given that n and p are close...but its running in a rather funny way, cant figure out the bug..There is some overflow somewhere..The constraints are 1 < P <= 2*10^9
1 <= N <= 2*10^9
though it runs fine for few cases...what could be the error.I have used
(a/b)mod p = ((a mod p)*(b^(p-2))mod p)mod p
as p is prime....and wilsons theorem that (p-1)! mod p = p-1
#include<bits/stdc++.h>
#define _ ios_base::sync_with_stdio(0);cin.tie(0);
using namespace std;
unsigned int pow(unsigned int a, unsigned n,unsigned int p) {
unsigned int ret = 1;
while(n) {
if((n&1)== 1) ret=(ret*a)%p;
a=a%p;
a=(a*a)%p;
n=n>>1;
}
return ret;
}
int main(){_
int t;
cin>>t;
while(t--){
unsigned int n,p;
long long int r;
cin>>n>>p;
r=p-1;
if(n>=p){
cout<<"0\n";
}
else{
for(unsigned int i=p-1;i>n;i--){
r=((long long)r*pow(i,p-2,p))%p;
}
cout<<r<<"\n";
}
}
return 0;
}
21! is 51090942171709440000, while 2^64 is only 1844674407370955161: so if unsigned long long is a 64-bit quantity (as is likely), it doesn't fit.