How to solve 100^1000 in C? [closed] - c

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
This Question is from Hacker Earth website as follow
Input: First line contains t, the number of test cases. After that t lines follow each containing a pair of space separated integers i.e. a and b.
Output: For each test case, you need to print the sum of digits in a^b.
Constraints:
1<=t<=20000
1<=a<=100
1<=b<=1000
Sample Input (Plaintext Link)
5
2 10
3 3
5 2
2 7
100 1000
Sample Output (Plaintext Link)
7
9
7
11
1
Explanation: Consider the first test case.
2^10 = 1024
Now, 1 + 0 + 2 + 4 = 7
So, output for this test case is 7.
Now I have solve this problem as follows:
#include<stdio.h>
#define test_max 20000
#define a_max 100
#define b_max 10000
long int power(int,int);
long int check_num(int,int);
int main()
{
int t;
long int i,rem,j=0,sum=0;
long int pr;
scanf("%d",&t);
int a[t],b[t];
for(i=0;i<t;i++)
{
scanf("%d",&a[i]);
scanf("%d",&b[i]);
if(a[i]>a_max||a[i]<=0||b[i]>b_max||b[i]<=0)
{
// printf("Please Check the Enter number limitation");
exit(0);
}
}
for(i=0;i<t;i++)
{
int check=0;
check=check_num(a[i],b[i]);
if(check==0)
{
pr=power(a[i],b[i]);
//printf("%d\t%d\t%ld\t",a[i],b[i],pr);
while(pr!=0)
{
rem=pr%10;
sum=sum+rem;
pr=pr/10;
}
printf("%d\n",sum);
sum=0;
}
else if(check==1)
{
printf("1\n");
}
}
return 0;
}
long int check_num(int a,int b)
{
if(a==100||a==10||a==1) return 1;
else return 0;
}
long int power(int n,int p)
{
int i;
long int num=n;
for(i=1;i<p;i++)
{
num=num*n;
}
return num;
}
But it's not a perfect answer. Can anyone tell me how to solve this problem?
The link of this problem is here: HERE
and I know the 100^1000 is not possible without using any library and I just have to avoid this but how?

100^1000 is too large a number to fit into a long, or any other basic number type.
You need to pick a big integer (also called big number) library that helps you manage arbirtrarily big numbers.
Try libGMP, it's widely used.

Generally speaking, When you talk about large numbers, you have 3 main options:
1) Use a library that manipulates big numbers
2) Implement your own functions for big numbers (use arrays to store the numbers - the length will be equal to the number of digits)
3) Find a Math approach
I will add some details for the 3rd approach, because the 1st and the 2nd are not very complicated.
If you need only the sum for those digits, try to avoid calculating that big number.
Think about logarithms and their properties when you work with large numbers.
For example, your particular case can be written in the following form:
100^1000 = (10^2)^1000 = 10^(2*1000) * 1 = 10^2000 + 0 = 10^2000 * 1
You know that the first part (10^2000) only adds some zeros => it doesn't influence your result (sum). So, you can try to split that big numbers in 2 parts ( a part that doesn't influence the sum and a useful part for the sum - 1 ).
How can you do this using logarithms for a more general problem? The following observation can generalize the things that were mentioned above:
a^x = 10^lg(a^x) = 10^(x*lg(a))
where lg = log in base 10
Then you can write your number as: 10^c * k or 10^c + k or 10^c - k, etc. depending on your numbers.
This explanation is just for guidance, to give you a taste. But the idea is the same: think about a mathematical solution based on some properties before you try other approaches.

Related

Print if there is a number combination that equals the given number [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 2 years ago.
Improve this question
I had this question in my exam a few weeks ago (Failed to answer it) and I wanted to know how to solve this kind of questions because I see they repeat themselves.
Write C program that gets Integers till -1 is inserted. if certain product of previously written numbers is equal to the last entered integer - the program will print it.
I know its pretty hard to understand but here are few examples :
(Typed order left to right)
1 -> 2 -> 3 -> 6 (Will print 2 * 3=6) -> 36 (Will print 2 * 3 * 6) -> -1
I can see that the problem is hard to do with arrays because of the memory limitation...
so I though of using "List" but ain't got idea how to.
I don't want a complete solution! I would like to get any hint on how to solve it in C (C# is also ok but C preferred).
Use a do-while cycle with condition and a counting sort.
https://en.wikipedia.org/wiki/Counting_sort
I wrote a raw program that does what you want with the exception that it always considers 1 as the product of previous numbers, and the same is true for numbers that were already entered. I leave you the challenge to fix the issue.
#include <stdio.h>
#define SIZE 10
void combo( int pro, int sum );
int n[SIZE], found, i;
int main() {
for( ; i < SIZE && scanf("%d", &n[i]) == 1 && n[i] != -1; i++) {
found = 0;
combo(1,0);
if( found ) printf("%d ", n[i]);
}
return 0;
}
void combo( int pro, int sum )
{
if( pro == n[i] ) found = 1;
for(int j = 0; j < i - sum && !found; j++) {
combo(pro * n[j], sum + 1);
}
}
n, found, i don't have to be global variables, but since combo could call itself lots of times, I thought it would have been a good idea to avoid giving it many arguments. I really don't know if it actually is a good idea.
Anyway, the program is a brute force. combo() will try every possible products of the elements of n.
For each j, combo will call itself generating a new loop, and for each index of this new loop there will be another recursive call generating a whole new loop, and so on.
combo stops to call itself when all the loops stop running.
A loop stops when either a matching product has been found or j reaches i - sum, where i is the current number of elements stored in the array minus 1, while sum represents the number of elements involved in the current product.
Every time, before to enter a loop, the function checks whether the current product matches the last number entered in the array.
If you know that the numbers are entered in ascending order you can optimize by swapping !found with pro < n[i].
I haven't done the math, but in case the input consists in a sequence of random integers, it may be more efficient to sort the array before to call combo in main.

Given a number A(=2^N), how to get the N? [duplicate]

This question already has answers here:
How to write log base(2) in c/c++
(14 answers)
Closed 5 years ago.
For example,
Input result
2 N: 1
4 N: 2
8 N: 3
Is there such function that I can directly use in c?
Or is there any quick simple method to get the N?
Mine:
// assume A is not very big
int getN(int A) {
int i = 0;
for(i = 0;;i++) {
if( 1 << i == A ) return i;
}
}
Assuming the input fits in a long, if you don't care much about performance, use log2 to compute the logarithm in base 2 (then cast it to an int) per other answers. BTW your naive getN is practically fast enough (but would loop indefinitely for a 0 input, you could limit that with for(i = 0; i<64; i++) ), and might even be faster than a log2, and you could make it a static inline function (in some header file).
If you are using GCC and if you know that the input is a power of 2 (so has exactly one bit set), you could use the faster __builtin_ffs builtin (find first set bit).
If the number is very large, you want to do arbitrary precision arithmetic. Then use a library like GMPlib.
If you like to use a custom recursive function to get N , use this function. Otherwise go for log of input.
int getN(int num){
if((num/2)==1){
return 1;
}
else if((num%2)!=0){
return 0;
}
else{
return (1 + getN(num/2));
}
}
Sure there is - log2 ( double d )
Use like this:
#include <math.h>
#include <stdio.h>
#define N somenumber
int main(){
int a = 1 << N; // == 2 raised to the power of N
printf("%d", (int)log2((double)a)); // output: N. can leave out the cast, for double format result
return 0;
}

Why am I getting this strange output on this simple C program? [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
I am working on a personal project where one part of it deals with counting squares and cubes under a certain bound (in this case 10,000). So, I wrote a simple C program I thought would work to verify my results. Here is the little program I put together to see all of the cubes:
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
int main() {
double i;
int cubes = 0;
for (i = 1; i < 10000; i++) {
if ( i == cbrt(i) * cbrt(i) * cbrt(i) ) {
printf("%f --- %f\n",i, cbrt(i));
cubes++;
}
}
printf("%i\n", cubes);
return 0;
}
I got the (incorrect) output : 24. If you want to look at this see the problem look at numbers 15 and 20 on the output. Why I am getting the wrong answer (the correct answer is 21) is an entirely different matter. My question arose when I was messing around with my code to try and fix this and I temporarily changed it to this:
int main() {
double i;
int cubes = 0;
for (i = 1; i < 10000; i++) {
double temp = (cbrt(i) * cbrt(i) * cbrt(i));
if ( i == temp ) {
printf("%f -> %f\n", i, temp);
cubes++;
}
}
printf("%i\n", cubes);
return 0;
}
Now, the program is printing every number between 1 and 9999. So, am I missing something ridiculously easy or what is going on? All I did was instead of having cbrt(i)*cbrt(i)*cbrt(i) in the if conditional I set a double variable equal to result and placed that in the conditional. Why is my program doing this?
I am not sure why this got down voted. I feel like this is a legitimate question. Sorry S.O. community...
double cbrt(double x) returns the closest representable cubic root of x.
The inexactness of the result, then cubed, may not exactly equal 'x' again.
Why 2nd program differs:
C is not obliged to perform double math only to double precision. It may use wider (long double). Depending on many things, the 2nd code appears to have done more in long double than the first. With the extra precision, its easy to see that the results, rounded to double appear exact.
C11dr ยง5.2.4.2.2 9 Except for assignment and cast (which remove all extra range and precision), the values yielded by operators with floating operands and values subject to the usual arithmetic conversions and of floating constants are evaluated to a format whose range and precision may be greater than required by the type.
Why a typical program run (of either code) produces a result of about 3333.
Consider the double numbers from 2 to 4 and 8 to 64. double numbers are logarithmically distributed. There are as many different double from 2 to 4 as 8 to 16 as 16 to 32 as 32 to 64.
So now all 3 sets from 8 to 64 have a cube root of some answer in the 1 set of 2 to 4. Now if we cube the numbers 2 to 4, we get answers in the range 8 to 64. 1 set of numbers mapping into 3 sets. The round trip is not exact. See Pigeonhole principle. IOW: On average, 3 numbers in the range 8 to 64 have the same cubic root. Then the cube of that root will be 1 of the 3 original.
To find the count of the perfect integer cubes 0 to N
unsigned Perfect_Cube_Count(unsigned n) {
if (n == 0)
return 1;
unsigned i;
// overflow not possible
for (i = 0; i*i < n/i; i++);
return i;
}
Or
// valid for 0 <= x <= something_well_over_1e9
double Perfect_Cube_Count_d(double x) {
double y = cbrt(x);
return floor(y) + 1;
}
You probably want, as Andrew guessed, whole-number cube roots. Float math is quite tricky because of rounding errors. Generally you cannot rely on equality but must compare with an error margin.
To solve your problem though I'd construct the 21 cubes beforehand and then iterate over integers, comparing against the pre-constructed cubes. Or is that cheating? ;-)
In Samuel Becket's novel Watt there is a chapter about a Scottish "Math genius" who could in his head compute all integer third roots of integer cubes up to 10000 or so, too!
My uess, is your compiler does an optimization in the second case, eli inating cbrt calls. It just says the result of cbrt is strictly defined by the standard, so it might as well be always thte case that (i == temp)
You can twak this by some command line arguments, and force it to do exactly what is written in the code. As I recall, this should thhe default thing to do for C compilers regarding float arthimetic, but your compiler may think it is smarter than you or something.
EDIT
And yes, this code has nothing to do with finding perfect cubes...
EDIT
Totally not an answer to the question, but as a quick exercise, this I wrote this:
#include <stdlib.h>
#include <stdio.h>
#include <limits.h>
static unsigned long count_cubes(unsigned long max_n)
{
unsigned long n = 1;
while (n*n*n <= max_n) {
++n;
}
return n-1;
}
int main(int argc, char **argv)
{
unsigned long max_n;
char *p;
if (argc < 2) {
return EXIT_FAILURE;
}
max_n = strtoul(argv[1], &p, 10);
if (max_n < 1 || max_n == ULONG_MAX) {
return EXIT_FAILURE;
}
printf("%lu\n", count_cubes(max_n));
return EXIT_SUCCESS;
}
Note: no need for floating point arithmetic
EDIT
Sorry, I really got into this...
This one can be a bit faster:
#include <stdlib.h>
#include <stdio.h>
#include <limits.h>
#include <math.h>
static unsigned long count_cubes(unsigned long max_n)
{
unsigned long n;
if (max_n < 256) {
n = 1;
}
else {
n = cbrtl(max_n) - 1;
}
while (n*n*n <= max_n) {
++n;
}
return n-1;
}
int main(int argc, char **argv)
{
unsigned long max_n;
char *p;
if (argc < 2) {
return EXIT_FAILURE;
}
max_n = strtoul(argv[1], &p, 10);
if (max_n < 1 || max_n == ULONG_MAX) {
return EXIT_FAILURE;
}
printf("%lu\n", count_cubes(max_n));
return EXIT_SUCCESS;
}
EDIT ( last time, I promise... )
To show an explanation of my little loop above, starting at cbrt(max_n)-1, I tried the one suggested by #chux , here are some results with slightly larger numbers:
PerfectCubes(18446724184312856125) == 2642246
which is fine but also
PerfectCubes(18446724184312856125-10) == 2642246
which is totally not fine, since 18446724184312856125 == 2642245^3 , meaning there are 2642245 perfect cubes <= 18446724184312856125-10 .
This also results from inaccuracies in floating point representation. You can try it for yourself, if your computer is somewhat similar to mine:
printf("%f\n", cbrt( 2642245UL * 2642245UL * 2642245UL));
/* prints 2642245.000000 */
printf("%f\n", cbrt( 2642245UL * 2642245UL * 2642245UL - 10UL));
/* prints 2642245.000000 */
These two numbers clearly don't have the same cubic root, yet cbrt returns the same results. In this case, floor doesn't help either. Anyways, one always needs to be very careful using floating point arithmetics. And now I really should go to sleep.

Displaying primes from 2-10,000 in C

I'm struggling with this (optional) problem my professor recommended I try. Basically, my task is to write a program which displays all prime integers from 2-10,000 using my own user-defined function to determine prime-ness. It sounded simple enough but I'm having major difficulties debugging my program. For some reason, my code only displays 2 and 3 before ending.
#include<stdio.h>
//function declaration
int prime(int);
//main body
int main(void)
{
int x=2, y;
for (x=2;x<=30;x++)
{
y=prime(x);
if (y!=0)
printf("%d\n", x);
}
getchar();
return(0);
}
//function definition
int prime(int x)
{
int y;
for (y=2; y<=(int)sqrt(x); ++y)
{
if (x%y==0)
return 0;
}
if (y==(int)sqrt(x))
return 1;
}
Instead of returning 1 if x is prime, my prime checking function seems to return a random large number (2686xxx) but that shouldn't be an issue because all primes return 0. If I run something like:
if (y==0)
printf("%d\n", x);
I see a list of all non prime numbers. If I run something like:
printf("%d %d\n", x, y);
I see a list of all integers from 2-10,000 and the result of my prime checking function (0 for non-primes, 2686xxx for primes).
Why doesn't the opposite (y!=0) display a list of prime numbers? What is causing my code to stop after just displaying 2 and 3? Why is my prime function returning a weird integer instead of 1? Finally, I'm still a beginner but how can I write better code in general? I don't think I'm breaking any of the standard accepted practices but how can I make my code more clean or efficient?
Thanks in advance for the help!
Your loop continues if y==(int)sqrt(x). So when it finishes, they're not equal. What you wanted is:
if (y>=(int)sqrt(x))
return 1;
But this is not needed at all. Just return 1; is sufficient. You've already returned zero if the number isn't prime.
If you wanted only a single return statement:
int prime(int x)
{
bool isPrime = true;
int y;
for (y=2; y<=(int)sqrt(x); ++y)
{
if (x%y==0)
{
isPrime = false;
break;
}
}
return isPrime;
}
Don't use the sqrt() function. In mathematics if you have 'x = sqrt(y)'. If you square both sides you will get something like this 'x * x = y'. This expression in c is tremendously faster than the sqrt function. Thus instead of doing:
y <= (int)sqrt(x)
Have you for loop guard be something like this:
y * y <= x
Here is a running example of your problem:
Primes 2 -> 10000
At the end of your prime function just return 1. If it wasn't prime it would have returned 0 earlier. Right?
As it is you've made a function which sometimes returns nothing at all. Which means that it returns whatever random value happens to be in the register.
You can use sieve of eratosthenes or sieve of atkin to mark all the prime numbers in an array and then display the prime numbers. It will be time efficient although it incurs some space complexity.
e.g if you want to display prime numbers from 1 to 10
Leave of 1. Its not a prime. Its neither prime nor composite.
So start from 2.
consider this array of size 10 = 2 3 4 5 6 7 8 9 10
Traverse from 2. If an element is not highlighted highlight all its multiples.
i.e for 2 highlight its multiples 4 6 8 10
==> 2 3 4 5 6 7 8 9 10
For 3 do the same
==> 2 3 4 5 6 7 8
9
10
Then do it for the rest of the no.s i.e. 5 and 10 (Here 7 dont have multiple)
Finally print the non highlighted elements. 2,3,5,7.
Repeat this procedure for any other ranges.
Since you are interested in writing computer programs for prime numbers, perhaps you would like to turn this paper into a computer program. It deals with prime numbers and is similar to the sieve you were trying to create in C.
https://graviticpropulsion.files.wordpress.com/2015/04/prime-number-theory.pdf
I'm not sure if it is faster or less memory intensive, but I'm curious myself how high of a prime number it can find before it becomes too intensive for a computer.

Binomial coefficient in C

Here you can find the problem I'm trying to solve:
For integers n and k (0<=k<=n<1001) determine (binomial coefficient).
Input
The first line of the standard input contains one integer t (t<1001) which is the number of test cases.
In each of the next t lines there are numbers n and k.
Output
For each test print (binomial coefficient).
Example:
Input
3
0 0
7 3
1000 2
Output:
1
35
499500
I can't seem to find anything wrong in my solution (other than it's written very poorly - I've started programming quite recently):
#include <stdio.h>
int main()
{
unsigned long int t,n,k,binomial=1;
unsigned long int number=1;
for(scanf("%lu",&t);t>0;t--)
{
scanf("%lu%lu",&n,&k);
if(k<(n/2)) k=n-k;
for(binomial=1,number=1;n>k;k++)
{
binomial=binomial*(k+1)/number;
number++;
}
printf("%lu\n",binomial);
}
return 0;
}
It works fine for the example input, but the solution is judged via a problem site
(http://www.spoj.pl/SHORTEN/problems/BINOMIAL/english/)
and the solution is not accepted. I tried other inputs too and all of them gave back the right output. My question is: Is there a reason why this solution is invalid?
As 1000C500 is around 300 digits, it cant be stored in an unsigned long. In short, you need to start over and think of a better technique.

Resources