2

Problem: To display the sum of this pattern for n terms like 1+11+111+1111+11111..n terms

Test Data:

Input the number of terms: 5.

Expected Output:

1 + 11 + 111 + 1111 + 11111 The Sum is : 12345

I am trying this way->

//To display the sum of series like 1+11+111+11111

 #include <stdio.h>
 int
 main(void){
//Here i declared some variables for storing information
 int number,iteration,value=1,j,summation=0;


 //Message to user
 printf("Input the number of terms : ");
 //taking input from the user
 scanf("%d",&number);
 //this condition will work till the iteration reaches to the inputted number

 for(iteration=1; iteration<=number; iteration++){

    
    for(j=1; j<=iteration; j++){
            //To display the series like 1 11 111 1111 11111
            printf("%d",value);


        if(j==1){
        summation=summation+value;

        }
        else if(j==2){
        summation=summation+value*10;
        }
        else if(j==3){
        summation=summation+value*100;
        }
        else if(j==4){
        summation=summation+value*1000;
        }
        else if(j==5){
        summation=summation+value*10000;
        }




}


printf(" ");
}
printf("\n");
//To display the summation
printf("The summation is : %d",summation);
return 0;}

Now my problem is: This code does not work according to my expectation. It is working up to input value 5. But when I want to give input 6 times then I need to add an else if condition additionally in my code. I need to do this task whenever I increase the input value.

When the input value is 6 and i need to add and make the condition like that->

else if(j==6){
       summation=summation+value*100000;
             }

So I think, this is not the way of a proper solution to a problem. Every time I need to do the same thing for the inputted value. How can I solve this problem?. After that how can I simplify the solution? I believe that you guys are expert than me. Please share your knowledge with me. Thank you in advance.

  • for n terms @Yunnosch –  Aug 19 '20 at 08:51
  • Maybe try recursion? Mind the limited range of the integer types ... `unsigned long long` is at least 64 bits, capable of holding values up to `18446744073709551615` – pmg Aug 19 '20 at 08:52
  • 20 million. @Yunnosch –  Aug 19 '20 at 08:57
  • If n<=9, the last *digit* is n, and the others are easily found. If n > 9, well, do you know how to perform a sum with carry? – Bob__ Aug 19 '20 at 08:58
  • Thank you @Bob. Ok i will try –  Aug 19 '20 at 09:00
  • 2
    Adding up 20 million numbers with up to 20 million digits you need to use a bit more than just a single integer variable – Gerhardh Aug 19 '20 at 09:01
  • @Gerhardh You can always evaluate a digit at a time and store those in a string. – Bob__ Aug 19 '20 at 09:03
  • 1
    @Bob__ that string needs to hold ~40 million characters. That's what I would call "a bit more than a single variable" ;) – Gerhardh Aug 19 '20 at 09:05
  • emmm ... using python maybe a solution – MX-Qulin Aug 19 '20 at 09:07
  • @MX-Qulin I do not get your point. The question is clearly tagged C and shows C code. "Use a different language" is far from being helpful. – Yunnosch Aug 19 '20 at 09:09
  • 1
    @Ashifulislamprince do you have a link to the original problem that you're solving? – Paul Hankin Aug 19 '20 at 09:17
  • Yes sir. https://www.w3resource.com/c-programming-exercises/for-loop/c-for-loop-exercises-26.php. @Paul Hankin –  Aug 19 '20 at 09:20
  • Not even the original gives a maximum input. But the sample also assumes a very low value... May I recommend finding different set of challenges to try learning from. – Yunnosch Aug 19 '20 at 09:25
  • I could not @bob –  Aug 19 '20 at 09:28
  • 20 million was always impossible given the expected output including the terms being summed. It would have around 200 terabytes of output! – Paul Hankin Aug 19 '20 at 09:28

8 Answers8

2

Pass the input number to this function.

    int findSum(int n) 
    { 
        int sum=0, cnt= 1; 
        for (int i = 1; i <= n; i++) { 
            sum += cnt; 
            cnt = (cnt * 10) + 1; 
        } 
      
        return sum; 
    } 
1

Here's an example that uses uint64_t to represent larger numbers. It shows the output you want for 1 up to 20 digits (longer causes an overflow).

The trick is to generate the numbers 1, 11, 111, and so on from the previous one by multiplying by 10 and adding 1. For example, 11111 = 1111 * 10 + 1.

#include <inttypes.h>
#include <stdio.h>

void sum(int n) {
    uint64_t t = 0;
    uint64_t x = 1;
    for (int i = 0; i < n; i++) {
        if (i > 0) printf(" + ");
        printf("%" PRIu64, x);
        t += x;
        x = (x * 10) + 1;
    }
    printf(" = %" PRIu64 "\n", t);
}

int main() {
    for (int i = 1; i < 21; i++) {
        sum(i);
    }
}

Here's a version that works for any n. It computes the total in time linear in n, although printing the terms being summed necessarily requires O(n^2) time.

The code works by noting that the last digit of the total consists of n 1s being added, the next-to last n-1 1s and so on. Plus carry of course. Note that the result is always exactly n digits long.

#include <stdio.h>
#include <stdlib.h>

void sum(int n) {
    for (int i = 1; i <= n; i++) {
        if (i > 1) printf(" + ");
        for(int j = 0; j < i; j++) putchar('1');
    }
    printf(" = ");

    char *s = malloc(n + 1);
    s[n] = '\0';
    int t = 0;
    for (int i = n - 1; i >= 0; i--) {
        t += i + 1;
        s[i] = '0' + (t % 10);
        t /= 10;
    }
    printf("%s\n", s);
    free(s);
}

int main() {
    sum(50);
}

Output (wrapped):

1 + 11 + 111 + 1111 + 11111 + 111111 + 1111111 + 11111111 + 111111111 + 1111111111 + 11111111111 + 111111111111 +
1111111111111 + 11111111111111 + 111111111111111 + 1111111111111111 + 11111111111111111 + 1111111111111111 11 +
1111111111111111111 + 11111111111111111111 + 111111111111111111111 + 1111111111111111111111 + 11111111111111111111111 +
111111111111111111111111 + 1111111111111111111111111 + 11111111111111111111111111 + 11111111111 1111111111111111 +
1111111111111111111111111111 + 11111111111111111111111111111 + 111111111111111111111111111111 +
1111111111111111111111111111111 + 11111111111111111111111111111111 + 111111111111111111111111111111111 +
1111111111111111111111111111111111 + 11111111111111111111111111111111111 + 111111111111111111111111111111111111 +
1111111111111111111111111111111111111 + 11111111111111111111111111111111111111 + 1111111111111111111111111
11111111111111 + 1111111111111111111111111111111111111111 + 11111111111111111111111111111111111111111 +
111111111111111111111111111111111111111111 + 1111111111111111111111111111111111111111111 + 1111111111111111111111111
1111111111111111111 + 111111111111111111111111111111111111111111111 + 1111111111111111111111111111111111111111111111 +
11111111111111111111111111111111111111111111111 + 111111111111111111111111111111111111111111111111 +
1111111111111111111111111111111111111111111111111 + 11111111111111111111111111111111111111111111111111 =
12345679012345679012345679012345679012345679012340
Paul Hankin
  • 54,811
  • 11
  • 92
  • 118
1

If you want to make this work for large N (say, 1,000 or 20,000,000), you won’t be able use int or long long values. Instead, you could allocate an array of uint8s, and do your own digit-by-digit addition arithmetic, including the carry operation. Then print the results at the end. It wouldn’t be fast but it would work.

To keep your code simple, think right-to-left. Start with the least significant digit in the zero-th array element.

Howlium
  • 1,218
  • 1
  • 8
  • 19
1

For handling numbers greater than int/long limits, you can use an array to get the sums per digit and print the output as a string.

#include <stdio.h>

int
main (int argc, char *argv[])
{
    int n, i, j;
    
    scanf("%d", &n);
    
    char ones[n];
    char sum[n + 1]; // + 1 index in case of a carry out
    char output[n + 2]; // +1 more index than sum for null byte
    
    // initialize to 0s
    for (i = 0; i < n; i++) {
        ones[i] = sum[i] = output[i] = 0;
    }
    sum[n] = output[n] = output[n+1] = 0;
    
    for (i = 0; i < n; i++) {
        ones[i] = 1;
        output[i] = '1';
        for (j = 0; j <= i; j++) { // add the current number of ones to sum
            sum[j] += ones[j];
            if (sum[j] >= 10) { // if theres a carry
                sum[j + 1] += (sum[j] / 10); // add the carry to the next index
                sum[j] %= 10; // keep the last digit
            }
        }
        
        if (i == n - 1) {
            printf ("%s ", output);
        } else printf ("%s + ", output);
    }
    
    if(sum[n] == 0) {// leading digit is 0
        i = n - 1;
    } else i = n;
    
    for (j = 0; i >= 0; i--, j++) {
        output[j] = sum[i] + '0';
    }
    printf ("The sum is: %s\n", output);
    
    return 0;
}
alvinalvord
  • 394
  • 2
  • 11
0

glad to help!

(it seems like a homework, so hope you can learn something)

You're doing this with many 'if's to decide how much it should plus. And another way is to use *10+1 every time.

Please see the code:

#include <stdio.h>
long long sum,tmp=1,n;
int main(void){
    scanf("%lld",&n);
    for(int i=0;i<n;i++){
        if(i<n-1)printf("%lld + ",tmp);
        else printf("%lld ",tmp);
        sum+=tmp;
        tmp=tmp*10+1;
    }
    printf("= %lld",sum);
    return 0;
}

That's it.

Wish you a good day:)

MX-Qulin
  • 123
  • 8
0

Given your user input variable number, the code may look something like this:

//...

if (number < 0)
{
    // do some error handling
    return -1;
}

int value_to_add = 1;
int sum = 0;

while (number--)
{
    sum += value_to_add;
    value_to_add = value_to_add * 10 + 1;
}

// ... (result is in "sum")

You also may consider the possibility of overflow (when the result gets so big that it does not fit in an int). You could, for instance, limit the user input (number).

0

If I understood correctly you want to be able to programmatically add new terms without having to use an if statement. To do it I suggest you

for (j=0; j<=iteration; j++){
   int powerOf10 = (int) pow((double) 10,j); //power elevation: notice 10^0=1, 10^1=10..    
   summation+=value*powerOf10;
}

This was just to give you an idea. Obviously, this code can be further refined. If you don't understand all the casting I performed to compute powerOf10 I leave you this post: Why is my power operator (^) not working?

AndreaCostanzo1
  • 1,799
  • 1
  • 12
  • 30
  • Confirmed. @Yunnosch –  Aug 19 '20 at 09:13
  • Sorry, but I cannot believe that. 1000 digits cannot be stored into an int. – Yunnosch Aug 19 '20 at 09:15
  • Ok, what can i do for handling 1000 digits? –  Aug 19 '20 at 09:16
  • Yeah, obviously you have always to consider the size of the number you are working with. I give you another reference to some integers types that maybe you want to now (from stdint.h): https://stackoverflow.com/questions/6013245/are-types-like-uint32-int32-uint64-int64-defined-in-any-stdlib-header – AndreaCostanzo1 Aug 19 '20 at 12:19
0

Paul Hankin's answer shows how to solve this problem for values of n greater than the number of digits storable in a long long.

That approach could be combined with another, based on a simple observation. If we write the sum starting from the greatest number, we can note an emerging pattern.

 111111111111111111111111111111111111111111111...111 +
  11111111111111111111111111111111111111111111...111 +
                               ... 
         1111111111111111111111111111111111111...111 =
 ----------------------------------------------------
 123456789999999999999999999999999999999999999...999 +   
          111111111111111111111111111111111111...111 =
 ----------------------------------------------------
 123456790111111111111111111111111111111111111...110 +
           11111111111111111111111111111111111...111 +
                               ...
                  1111111111111111111111111111...111 =
 ----------------------------------------------------
 123456790123456789999999999999999999999999999...998 +
                   111111111111111111111111111...111 =
 ----------------------------------------------------
 123456790123456790111111111111111111111111111...109 +
                    11111111111111111111111111...111 +
                               ...
                           1111111111111111111...111 =
 ----------------------------------------------------
 123456790123456790123456789999999999999999999...997 +
                            111111111111111111...111 =
 ----------------------------------------------------
 123456790123456790123456790111111111111111111...108 +
 ^        ^        ^        ^  ...

In practice, we can start by "filling" the number (represented as a string of n characters) with the repeating pattern "123456790" from left to right (the most significant digit beeing always '1').

Then, starting from the least significant digit, we can apply the algorithm of the sum with carry, but only as long as the calculated digit is different from the one already there (except the last one, which is always n % 10).

Only a few steps are needed, just around the number of decimal digits of n.

Bob__
  • 12,361
  • 3
  • 28
  • 42