How to implement N choose R? - c++

I just wrote this code :
#include <iostream>
using namespace std;
unsigned long long int choose(unsigned long long int k, unsigned long long int n)
{
if (k==n or k==0)
{
return 1;
}
else
{
return (choose(n-1,k-1)+choose(n-1,k));
}
}
int main(){
cout << choose(3, 6);
}
but I got Run-Time Error, I think my problem is in my variables, I did debugging but I couldn't find the answer, why I got run time error?

Since your variables are unsigned, substracting 1 from them when they're already 0 will make them roll over to the max value.
When n reaches 0 and you then call choose(n-1,k), this'll happen and that's the source of the issue (stackoverflow).

Related

Last Digit of the Sum of Fibonacci Numbers. Unable to get exact answer

#include<iostream>
#include<vector>
#include<cstdlib>
#include <cassert>
using namespace std;
long long int LastDigitofSumofFibonacci(int n){long long int first=0;
long long int second=1;
long long int fibOfn;
long long int sum=1;
vector<long long int> V;
V.push_back(first);
V.push_back(second);
if(n==0) return first;
else if(n==1) return second;
else{
for(int i=2;i<60;i++){
fibOfn=first+second;
first=second;
second=fibOfn;
sum=sum+fibOfn;
//cout<<"i "<<i<<" fibOfn "<<fibOfn<<" fibOfnlastdigit "<<fibOfnlastdigit<<" first "<<first<<" second "<<second<<" sum "<<sum;
//cout<<endl;
sum=sum%10;
V.push_back(sum);
}
}
//for(auto element:V)
//cout<<element<<" ";
//cout<<endl;
//cout<<(n)%60<<endl;
return V[(n)%60];
}
int main(){
int n;
cin>>n;
long long int Base=LastDigitofSumofFibonacci(n);
cout<<Base<<endl;
}
In this I am trying to calculate the the last digit of Fibonacci series. I know and also read from net that last digit follow pattern of 60(0-59). from that concept wise I think my code is OK. but still I am unable to get the correct answers for large digit number.
I cleaned up the code a bit and fixed the issue with second not being computed % 10.
Since only the last digit is relevant all variables can be just int, no need for long long int to store a single digit. It would actually save ram to use uint8_t as type for the cache, but 60 bytes or 240 bytes isn't going to make a difference here.
The result repeats every 60 steps, which is the basis for the algorithm. But why compute this every time the function gets called? So lets make a static array so the computation only happens once. Lets go one step further with constinit and compute it at compile time.
As last change I made the argument to LastDigitofSumofFibonacci unsigned int. Unless you want to extend the fibonacci series backwards into the negative and extend the algorithm. unsigned int generates better code for n % 60.
#include <iostream>
#include <array>
int LastDigitofSumofFibonacci(unsigned int n) {
// The last digit of `fib(n)` and their sum repeats every 60 steps.
// https://en.wikipedia.org/wiki/Pisano_period
// Compute the first 60 values as lookup table at compile time.
static constinit std::array<int, 60> cache = []() {
int first = 0, second = 1;
std::array<int, 60> a{0, 1};
for (int i = 2; i < 60; i++) {
int t = first + second;
first = second;
second = t % 10;
a[i] = (a[i - 1] + t) % 10;
}
return a;
}();
// and now just look up the answer at run time.
return cache[n % 60];
}
int main(){
int n;
std::cin >> n;
std::cout << LastDigitofSumofFibonacci(n) << std::endl;
}
Somehow the code got a lot shorter just from eliminating some overhead here and there.

Modified Fibbonaci C++ getting a large negative number

Ok so, I'm doing hackerrank's Fibonacci modified question. I am able to solve this question only when the iteration goes to 8 anything pass that and it starts returning a large negative number. I thought this was because of an integer overflow so I changed my types to unsigned long long yet the problems still persist. Any help is appreciated.
Link to original problem: https://www.hackerrank.com/challenges/fibonacci-modified/problem
#include <iostream>
#include <vector>
using namespace std;
int modFib(unsigned t1, unsigned t2, unsigned n) {
if (n == 1) {
return t1;
}
else if (n == 2) {
return t2;
} else {
return modFib(t1, t2, n-2) + (modFib(t1, t2, n-1) * modFib(t1, t2, n-1));
}
}
int main() {
cout << modFib(0, 1, 10) << endl;
return 0;
}
//Expected output is 84266613096281243382112
//I get -1022889632
In C++, the general range of an unsigned int is 0 to 4,294,967,295, so using an unsigned int will not be appropriate for this problem.
The expected output is actually larger than the maximum possible value of even an unsigned long long int, which goes from 0 to 18,446,744,073,709,551,615. This means that you cannot use either of these data types for this problem.
For such large values, you should look into the usage of BigNums.

strange behavior of unsigned long long int in loop

While was solving this problem on hackerrank, I noticed a strange thing in the for loop. First, let me show an example code:
#include <bits/stdc++.h>
using namespace std;
#define modVal 1000000007;
int main() {
for(long long int i=2;i>=0;--i){
cout<<"here: "<<i<<endl;
}
}
input: 123
output: here: 2
here: 1
here: 0
164
Now, when I change long long int to unsigned long long int in for loop for the initialization of variable i. The variable i gets initialized with 18446744073709551615. Why is this happening?
When the variable is unsigned, i >= 0 is always true. So your loop never ends. When i gets to 0, the next -- makes i 0xFFFFFFFFFFFFFFFF (decimal 18446744073709551615).
Because unsigned types can't be negative, attempting to set them to a negative value will make them wrap around and instead hold std::numeric_limits<T>::max() - abs(value) + 1 where T is the type and value the value below 0.
In your loop once i reaches 0 the condition i >= 0 is still met and thus it would get decremented to -1 but that is impossible for unsigned types as explained above and thus the loop will never exit.
The unsigned numbers as the name suggests don't take signed values. So when i = -1 it is actually 0xFFFFFFFFFFFFFFFF(18446744073709551615 in decimal).
You can see that yourself with the modified program.
#include <bits/stdc++.h>
using namespace std;
#define modVal 1000000007;
int main() {
for(unsigned long long int i=2;i>=0;--i){
cout<<"here: "<<i<<endl;
if(i > 3)
return 0;
}
}

Runtime Error - SIGFPE

I HAVE THE FOLLOWING CODE for hackerearth competetion and WRITTEN IN C++ (g++ 4.8.4)
it is giving SIGFPE on runtime
I am just done with it
plz tell how tofix it
#include<iostream>
using namespace std;
int factorial(int n);
int main()
{
int n , k ,totitem , totways=0 , har1,har2, ansh=1;
int res;
cin>>n>>k;
totitem = (n/k);
ansh=factorial(n);
if(totitem>0)
for(int i=0;i<=totitem*k;i+=k)
{
har1=factorial(i);
har2=factorial(n-i);
totways+=(ansh/(har1*har2));
}
cout<<totways;
return 0;
}
int factorial(int n)
{
if(n>1)
return n*factorial(n-1);
else
// if(n==0 || n==1)
return 1;
}
It is usually division by zero error.
There are two divide statements in your code.
1:
totitem = (n/k);
where you don't sanitise your input.
2:
har1=factorial(i);
har2=factorial(n-i);
totways+=(ansh/(har1*har2));
And this will fail if any of the har parameters equals to zero.
The most probable cause of the problem is that you are using 32-bit signed integers (int) to do factorial calculations, which are limited to factorial of 12! Trying to do factorial with larger numbers will cause overflow and thus incorrect result and eventually a zero value, that caused your runtime error.

Bytelandian gold coins

I am solving this problem -> http://www.spoj.com/problems/COINS/ . A very simple DP problem with a very straight forward DP approach.I found enough hints in the problem statement to use DP. All the test cases are running perfectly in my compiler but I am getting a WA in SPOJ. My code is as follows :
My code
#include <cstdio>
#include <map>
#include <cstring>
#include<algorithm>
using namespace std;
map< long long,long long > data;
map < long long,long long> :: iterator p;
int max(int a,int b)
{
if(a>b)return a;
return b;
}
long long calc(int n)
{
long long c;
if(n==0 || n==1 || n==2)
return n;
p = data.find(n);
if(p==data.end())
{
c = max(n, calc(n/2) + calc(n/3) + calc(n/4));
data.insert(p, pair < long long, long long > (n, c));
return c;
}
else return (*p).second;
}
int main()
{
int t;
long long n;
scanf("%d",&t);
if(t>10)return 0;
while(t--)
{
scanf("%lld",&n);
if(n<0 || n>1000000000)
break;
data.clear();
printf("%lld",calc(n));
}
return 0;
}
I am finding it really difficult for me to figure out where I am going wrong!
A test case which contradicts my code would also do.
Perhaps a stack overflow in calculate. The recursion is killing your program :-)
Or simply the fact that calculate(1000000000) is too much slow.
Use Dynamic programming , store your result in an array . Since the value can go upto 10^9, and you cann't take array of that size , just take array of size till 10^6 and store their result and rest value calculate using simple recursion .
Here is a solution in python
import sys
mydict = {}
def count(n):
if n <= 5:
return n
elif n in mydict.keys():
return mydict[n]
else:
k=max(n,count(n / 2) + count(n / 3) + count(n / 4))
mydict[n]=k
return mydict[n]
for line in sys.stdin:
res = count(int(line))
print(int(res))
Here's my solution, uses dp :
#include<bits/stdc++.h>
using namespace std;
map<long long int,long long int> m;
long long int dp(long long int k){
long long int a;
if(k==0){
return 0;
}
a=m[k];
/* if(k<12){
return k;
} */
if(k<12){
return k;
}
else if(a==0){
a=max(k,dp(k/2)+dp(k/4)+dp(k/3));
m[k]=a;
}
return a;
}
int main(){
long long int n,t;
while(scanf("%lld",&n)>0){
t=dp(n);
cout << t << endl;
}
return 0;
}