Compute sum of digits in all numbers from 1 to N for a given N

In this article, we are going to see how to compute sum of digits in all numbers from 1 to N for a given N?
Submitted by Vivek Kothari, on December 17, 2018

Problem statement: We have given a number N and we have to find out the sum of digits in all numbers from 1 to N.

Solution

Brute force approach:

Simple idea for solution is that if we get number greater than 9, i.e., the number having more than one digit, we extract every individual digit of that and sum together to find final result.

    function sum(N) //brute force approach
        sum = 0;
        for(i =1 to N)
        {
            temp = i;
            while(temp != 0)
            {
                sum = sum + temp%10;
                temp = temp/10;
            }
        }
        return sum;
    END FUNCTION

The time complexity for this solution in O(Nlog10(N)) as we have to sum N items and in worst case the number of digits a number has is log10(N).

Better approach using Dynamic Programming

Now, we figure out the solution which takes only log10(N) time. We can use dynamic programming here to find the solution which takes log10(N) time, the optimal substructure for the problem is discussed below:

Let you want to calculate sum(9999) & in order to find it you have to calculate sum(999). To calculate sum(999) you have to find out sum(99) and similarly for sum(99) you have to calculate sum(9).

sum(9999)=>sum(999)=>sum(99)=>sum(9)

sum (10 – 1) = sum(9) = 1 + 2 + 3 + 4 ... + 9 = 45
Similarly , 
sum(100 – 1) =  sum(99)  = 45 + (10 + 45) + (20 + 45) + ... (90 + 45)
            = 45*10 + (10 + 20 + .................+ 80 + 90)
            = 45*10 + 10(1 + 2 + ..................+ 8 + 9)
            = 45*10 + 10 * 45
            = sum(9)*10 + 10*45
sum(1000 – 1) = sum(999) = sum(99)*10 + 100 * 45
so, we can write recursive formula of overlapping 
sub-problems for computing sum(10d – 1) as: 
sum(10d - 1) = sum(10d-1 - 1) * 10 + 45*(10d-1)

Example explanation using DP:

Now, let’s see for N = 3266 i.e we have to find sum of digits of first 3266 numbers.

If you want to find sum for N = 3266 then we can think it like this:


Sum of numbers from (0 – 999) + from(1000 – 1999) + from(2000 – 2999) + from(3000 – 3266)
Now it can be written as :
=>sum(999)+ { sum(999) + 1 occur 1000 times } + { sum(999) + 2 occur 1000 times } + {sum(266) + 3 occur 266 times}
=>sum(999) + { sum(999) + 1 * 1000 } + { sum(999) + 2 * 1000 } + {sum(266) + 3 * 266}
=> 3 * sum(999) + (1 + 2 )*1000 + 3 * 266 + sum(266)
Now sum(266) can be written as :
=> sum(0 to 99) + sum(100 to 199) + sum(200 to 266)
=> sum(99) + { sum(99) + 1 * 100 } + { 2 * 66 + sum(66) }
=> 2 * sum(99) + 1*100 + 2 * 66 + sum(66)

Now observe the pattern here:

Computer sum of digits

Algorithm: Now, see algorithm for solving above problem.

calculate_sum(d) 
{
	a[0] = 0
	a[i] = 45
	for(i=2 to d)
	{
		a[i] = a[i-1]*10 + 45*10^(i-1)
	}
}

sum_of_digits(N)
{	
	d = log(N)
	if (N<10) 
		return N*(N+1)/2
	//now calculate sum of digits from 
	//1 to 10^d-1 using calculate_sum()
	//function
	lmd = N/10^d // left most digit
	return lmd * a[d] + (lmd*(lmd-1)/2) * 10^d +
	lmd * (1+N % 10^d) + sum_of_digits(N % 10^d) 
}

Program 1: brute force approach for solving above problem

#include <bits/stdc++.h>
using namespace std;

long long sum(int N)
{ 
	long long sum = 0;
	long long i,temp;
	for(i =1;i<=N;i++)
	{
		temp = i;
		while(temp != 0)
		{
			//extracting last digit and adding to sum
			sum = sum + temp%10;
			//removing digit
			temp = temp/10;
		}
	}
	return sum;
}

int main()
{
	int N;
	
	cout<<"enter the value of N : ";
	cin>>N;
	cout << "Sum of digits of first " << N << " natural numbers is = "<<sum(N);
	
	return 0;
}

Output

enter the value of N : 450
Sum of digits of first 450 natural numbers is = 4734

Program 2: In this program we see the implementation of efficient approach

#include <bits/stdc++.h>
using namespace std; 

int a[100000];

void calculate_sum(int d) 
{
	a[0] = 0;
	a[1] = 45;
	for(int i=2;i<=d;i++)
	{
		//sum(10^d - 1) = sum((10^d-1)-1)*10 + 45 * 10^(d-1)
		a[i] = a[i-1]*10 + 45*pow(10,i-1);
	}
}

long long sum_of_digits(int N)
{
	//base condition
	//if N less than 10
	//return sum of first N numbers
	if (N<10) 
		return N*(N+1)/2;

	//calculating number of digits in N   	
	int d = log10(N);

	//calculate sum of digits from 1 to 10^d-1
	calculate_sum(d);

	//left most digit
	int lmd = N/pow(10,d);

	//store the value of 10^d
	int t = ceil(pow(10,d));

	return lmd * a[d] + (lmd*(lmd-1)/2) * t + lmd * (1 + N % t) + sum_of_digits(N % t); 
}

int main() 
{ 
	int N;
	cout<<"enter the value of N : ";
	cin>>N;
	cout << "Sum of digits of first " << N << " natural numbers is = "<<sum_of_digits(N);
	return 0;
}

Output

enter the value of N : 450
Sum of digits of first 450 natural numbers is = 4734

Related Tutorials



Comments and Discussions!

Load comments ↻





Copyright © 2024 www.includehelp.com. All rights reserved.