Calculating Modulo between 2 large numbers represented as strings - c++

I am trying to compute % of large numbers. I managed so far with the dividend to be large and the mod represented as integer. I have no idea how to do otherwise. I need this exactly for Large numbers division that is why I need this. No, I will not use BigInts library, as it is not accepted by online judges. Moreover, I'd like to know how to do it myself.
This is what I have written for just one large number.
int mod(string num, int a)
{
int res = 0;
for (int i = 0; i < num.length(); i++)
res = (res*10 + (int)num[i] - '0') %a;
return res;
}

Related

Problem when i used some large large value i get wrong output with my function

So I'm new to stackoverflow and coding I was learning about functions in c++ and how the stack frame works etc..
in that I made a function for factorials and used that to calculate binomial coefficients. it worked fine for small values like n=10 and r=5 etc... but for large a medium value like 23C12 it gave 4 as answer.
IDK what is wrong with the code or I forgot to add something.
My code:
#include <iostream>
using namespace std;
int fact(int n)
{
int a = 1;
for (int i = 1; i <= n; i++)
{
a *= i;
}
return a;
}
int main()
{
int n, r;
cin >> n >> r;
if (n >= r)
{
int coeff = fact(n) / (fact(n - r) * fact(r));
cout << coeff << endl;
}
else
{
cout << "please enter valid values. i.e n>=r." << endl;
}
return 0;
}
Thanks for your help!
You're not doing anything "wrong" per se. It's just that factorials quicky become huge numbers.
In your example you're using ints, which are typically 32-bit variables. If you take a look at a table of factorials, you'll note that log2(13!) = 32.535.... So the largest factorial that will fit in a 32-bit number is 12!. For a 64-bit variable, the largest factorial you can store is 20! (since log2(21!) = 65.469...).
When you get 4 as the result that's because of overflow.
If you need to be able to calculate such huge numbers, I suggest a bignum library such as GMP.
Factorials overflow easily. In practice you rarely need bare factorials, but they almost always appear in fractions. In your case:
int coeff = fact(n) / (fact(n - r) * fact(r));
Note the the first min(n,n-r,r) factors of the denominator and numerator are identical. I am not going to provide you the code, but I hope an example will help to understand what to do instead.
Consider n=5, r=3 then coeff is
5*4*3*2*1 / 2*1 * 3*2*1
And before actually carrying out any calculations you can reduce that to
5*4 / 2*1
If you are certain that the final result coeff does fit in an int, you can also calculate it using ints. You just need to take care not to overflow the intermediate terms.

How to compute catalan numbers with n=100 in C/C++?

My output's false when n is larger than 20. So i need help to compute Catalan's number C(n) with n is smaller than 100
To calculate result for large input values, you have to treat huge integers (larger than any build-in type like int64 (long long)). Big integer arithmetics support is included in some languages like C# and Python.
In C++ you should use some library like GMP, Boost.Multiprecision, or some lightweight library (because you need only addition and multiplication).
#include <gmp.h>
mpz_t a, b;
mpz_init_set_str (a, "191999293783437378367363763763"argv[1], 10);
mpz_init_set_str (b, "44766484748782378237827328-1829087234976123097", 10);
mpz_add (t, a, b);
It is quite possible to write implementation of these operations by yourself.
Call the function through a for loop
unsigned long int catalan(unsigned int n){
if (n <= 1) return 1;
unsigned long int res = 0;
 for (int i=0; i<n; i++)
res += catalan(i)*catalan(n-i-1);
return res;
}

C++ Finding the minimum quotient from two different integer arrays of the same size

I have 2 different arrays numerator[ ], and denominator[ ] and int size which is 9. They both consist of 9 different integers, and I need to find the lowest quotient of 2 ints
(the percentage - (numerator[ ])/(denominator[ ]) ) in the two arrays. How would I go about doing this?
Do you want to return the percentage or the quotient(with no remainder)?
Following code returns the percentage. Change double to int, if you want the quotient.
#include<limits>
double lowestQuotient(const int *numerator, const int *denominator)
{
double min=DBL_MAX;
double quotient;
for(i=0;i<9;i++)
{
if (denominator[i]==0)
continue;
quotient = (double)numerator [i]/denominator [i];
if (i==0 || quotient<min)
min=quotient;
}
return min;
}
Edit: This answer was written before the problem statement was changed to clarify that the intention was not to compare every combination, but instead to only take pair-wise quotients. That simplifies the problem quite a bit and makes my lengthy solution here overkill. This was also written before a solution involving floating point values was indicated; I assumed that the questioner was interested in the mathematical definition of the quotient of two integers, which is itself necessarily an integer. All the same I'll leave this here for posterity...
Edit 2: Fixed the compilation error -- thanks James Root for pointing out the error.
This is a math problem first and a programming problem second.
The naive implementation is to compute every combination of numerators from the first array divided by denominators from the second array, track the minimum quotient as we go, and compute the result.
This would look something like the following:
#include <climits>
#include <algorithm>
int minimum_quotient(int numerator[], int denominator[], int size)
{
int minimum = INT_MAX; // minimum quotient
for (int i = 0; i < size; ++i)
for (int j = 0; j < size; ++j)
if (denominator[j] != 0) // avoid division by 0
minimum = std::min(minimum, numerator[i] / denominator[j]);
return 0;
}
With size being a known, small number, this should be sufficient. However, if we are concerned about the case in which size becomes very large, we may want to avoid the above written solution, which scales proportionate to the square of the size of the input.
Here is an idea for a solution that scales better with larger sizes. Specifically it scales linearly with the size of the input. We can take advantage of the following facts:
If the numerators and denominators both have the same sign, then the smallest quotient will be from the numerator with the smallest absolute value and the denominator with the largest absolute value.
If the numerators and denominators have opposite signs, then the opposite is true: for the smallest quotient we want the numerator with the largest absolute value and the denominator with the smallest absolute value.
We can iterate through both lists once, accumulating the largest and smallest numerators and denominators, and then compare these at the end to find the smallest quotient:
#include <climits>
#include <algorithm>
int minimum_quotient(int numerator[], int denominator[], int size)
{
int min_num = INT_MAX, min_den = INT_MAX;
int max_num = INT_MIN, max_den = INT_MIN;
for (int i = 0; i < size; ++i)
{
min_num = std::min(min_num, numerator[i]);
max_num = std::max(max_num, numerator[i]);
min_den = std::min(min_den, denominator[i]);
max_den = std::max(max_den, denominator[i]);
}
int minimum = INT_MAX;
if (min_den != 0)
{
minimum = std::min(minimum, min_num / min_den);
minimum = std::min(minimum, max_num / min_den);
}
if (max_den != 0)
{
minimum = std::min(minimum, min_num / max_den);
minimum = std::min(minimum, max_num / max_den);
}
return minimum;
}

Computing large combinations

How would you compute a combination such as (100,000 choose 50,000)?
I have tried three different approaches thus far but for obvious reasons each has failed:
1) Dynamic Programming- The size of the array just gets to be so ridiculous it seg faults
unsigned long long int grid[p+1][q+1];
//Initialise x boundary conditions
for (long int i = 0; i < q; ++i) {
grid[p][i] = 1;
}
//Initialise y boundary conditions
for (long int i = 0; i < p; ++i) {
grid[i][q] = 1;
}
for (long int i = p - 1; i >= 0; --i) {
for (long int j = q - 1; j >= 0; --j) {
grid[i][j] = grid[i+1][j] + grid[i][j+1];
}
}
2) Brute Force - Obviously calculating even 100! isn't realistic
unsigned long long int factorial(long int n)
{
return (n == 1 || n == 0) ? 1 : factorial(n - 1) * n;
}
3) Multiplicative Formula- I'm unable to store the values they are just so large
const int gridSize = 100000; //say 100,000
unsigned long long int paths = 1;
for (int i = 0; i < gridSize; i++) {
paths *= (2 * gridSize) - i;
paths /= i + 1;
}
// code from (http://www.mathblog.dk/project-euler-15/)
If it helps for context the aim of this is to solve the "How many routes are there through an m×n grid" problem for large inputs. Maybe I am miss-attacking the problem?
C(100000, 50000) is a huge number with 30101 decimal digits: http://www.wolframalpha.com/input/?i=C%28100000%2C+50000%29
Obviously unsigned long long will not be enough to store it. You need some arbitrary large integers library, like GMP: http://en.wikipedia.org/wiki/GNU_Multiple_Precision_Arithmetic_Library
Otherwise, multiplicative formula should be good enough.
"How would you compute ..." depends very much on the desired accuracy. Precise results can only be computed with arbitrary precission numbers (eg. GMP), but it is rather likely that you don't really need the exact result.
In that case I would use the Stirling Approximation for factorials ( http://en.wikipedia.org/wiki/Stirling%27s_approximation ) and calculate with doubles. The number of summands in the expansion can be used to regulate the error. The wikipedia page will also give you an error estimate.
Here is recursive formula that might help : -
NCk = (N-1)C(k-1)*N/K
Use a recursive call for (N-1)C(K-1) first then evaluate NCk on result.
As your numbers will be very large use one of following alternatives.
GMP
Use your own implementation where you can store numbers as sequence of binary bits in array and use booth's algorithm for multiplication
and shift & subtract for division.

RSA encryption in C++

I want to encrypt (RSA) a character to an integer using its ASCII value. Eg. 'a' is encrypted as 48.
For encryption: c=pow(m,e)%n where c is cipher text, m is the plain text and (e,n) is the public key.
If pow(m,e) is large say 67^7, it won't fit in int or long. But if I use double, I cannot use it with modulus % operator. So I wrote this function for encryption using a for loop:
int encrypt(int m, int e, int n)
{
int res=m, i;
for(i=0; i<e-1;i++)
res=(res*res)%n;
return res;
}
It worked for 67^7mod11 which is 67 but then I came to know it's not actually correct. Where have I gone wrong?
Your loop
for(i=0; i<e-1;i++)
res=(res*res)%n;
squares e-1 times modulo n, that means it computes m^(2^(e-1)) modulo n. To compute m^e modulo n with the simple algorithm, use
for(i = 0; i < e-1; ++i)
res = (res*m) % n;
instead.
For a somewhat faster algorithm when the exponent is larger, you can use exponentiation by repeated squaring:
res = 1;
while (e > 0) {
if (e % 2 != 0) {
res = (m*res) % n;
}
m = (m*m) % n;
e /= 2;
}
return res;
Usually when using encryption parameters you use "big int" instead of int's.
Exactly for that reason.
There are some suggestions here:
Bigint (bigbit) library