Open In App

Count numbers in given range such that sum of even digits is greater than sum of odd digits

Improve
Improve
Like Article
Like
Save
Share
Report

Given two integers L and R denoting a range [L, R]. The task is to find the total count of numbers in the given range [L,R] whose sum of even digits is greater than the sum of odd digits. 

Examples:

Input : L=2 R=10 
Output : 4 Numbers having the property that sum of even digits is greater than sum of odd digits are: 2, 4, 6, 8 

Input : L=2 R=17 
Output : 7

Prerequisites: Digit-DP 

Approach: Firstly, count the required numbers up to R i.e. in the range [0, R]. To reach the answer in the range [L, R] solve for the range from zero to R and then subtracting the answer for the range from zero to L – 1. Define the DP states as follows:

  • Consider the number as a sequence of digits, one state is the position at which we are currently at. This position can have values from 0 to 18 if we are dealing with the numbers up to 10^18. In each recursive call, try to build the sequence from left to right by placing a digit from 0 to 9.
  • First state is the sum of the even digits that has been placed so far.
  • Second state is the sum of the odd digits that has been placed so far.
  • Another state is the boolean variable tight which tells the number we are trying to build has already become smaller than R so that in the upcoming recursive calls we can place any digit from 0 to 9. If the number has not become smaller, the maximum limit of digit we can place is the digit at the current position in R.

Below is the implementation of the above approach: 

C++




// C++ code to count number in the range
// having the sum of even digits greater
// than the sum of odd digits
#include <bits/stdc++.h>
 
// as the number can be up to 10^18
#define int long long
 
using namespace std;
 
vector<int> v;
 
int dp[18][180][180][2];
 
int memo(int index, int evenSum,
                      int oddSum, int tight)
{
    // Base Case
 
    if (index == v.size()) {
        // check if condition satisfied or not
        if (evenSum > oddSum)
            return 1;
        else
            return 0;
    }
 
    // If this result is already computed
    // simply return it
    if (dp[index][evenSum][oddSum][tight] != -1)
        return dp[index][evenSum][oddSum][tight];
 
    // Maximum limit upto which we can place
    // digit. If tight is 0, means number has
    // already become smaller so we can place
    // any digit, otherwise num[pos]
 
    int limit = (tight) ? v[index] : 9;
 
    int ans = 0;
 
    for (int d = 0; d <= limit; d++) {
        int currTight = 0;
 
        if (d == v[index])
            currTight = tight;
 
        // if current digit is odd
        if (d % 2 != 0)
            ans += memo(index + 1, evenSum,
                        oddSum + d, currTight);
 
        // if current digit is even
        else
            ans += memo(index + 1, evenSum + d,
                        oddSum, currTight);
    }
 
    dp[index][evenSum][oddSum][tight] = ans;
    return ans;
}
// Function to convert n into its
// digit vector and uses memo() function
// to return the required count
int CountNum(int n)
{
    v.clear();
    while (n) {
        v.push_back(n % 10);
        n = n / 10;
    }
 
    reverse(v.begin(), v.end());
 
    // Initialize DP
    memset(dp, -1, sizeof(dp));
    return memo(0, 0, 0, 1);
}
 
// Driver Code
 
int32_t main()
{
    int L, R;
    L = 2;
    R = 10;
    cout << CountNum(R) - CountNum(L - 1) << "\n";
    return 0;
}


Java




// Java code to count number in the range
// having the sum of even digits greater
// than the sum of odd digits
import java.util.*;
 
class GFG
{
 
    static Vector<Integer> v = new Vector<>();
 
    static int[][][][] dp = new int[18][180][180][2];
 
    static int memo(int index, int evenSum,
    int oddSum, int tight)
    {
        // Base Case
 
        if (index == v.size())
        {
            // check if condition satisfied or not
            if (evenSum > oddSum)
            {
                return 1;
            }
            else
            {
                return 0;
            }
        }
 
        // If this result is already computed
        // simply return it
        if (dp[index][evenSum][oddSum][tight] != -1)
        {
            return dp[index][evenSum][oddSum][tight];
        }
 
        // Maximum limit upto which we can place
        // digit. If tight is 0, means number has
        // already become smaller so we can place
        // any digit, otherwise num[pos]
        int limit = (tight > 0) ? v.get(index) : 9;
 
        int ans = 0;
 
        for (int d = 0; d <= limit; d++)
        {
            int currTight = 0;
 
            if (d == v.get(index))
            {
                currTight = tight;
            }
 
            // if current digit is odd
            if (d % 2 != 0)
            {
                ans += memo(index + 1, evenSum,
                        oddSum + d, currTight);
            } // if current digit is even
            else
            {
                ans += memo(index + 1, evenSum + d,
                        oddSum, currTight);
            }
        }
 
        dp[index][evenSum][oddSum][tight] = ans;
        return ans;
    }
    // Function to convert n into its
    // digit vector and uses memo() function
    // to return the required count
 
    static int CountNum(int n)
    {
        v.clear();
        while (n > 0)
        {
            v.add(n % 10);
            n = n / 10;
        }
 
        Collections.reverse(v);
 
        // Initialize DP
        for (int i = 0; i < 18; i++)
        {
            for (int j = 0; j < 180; j++)
            {
                for (int k = 0; k < 180; k++)
                {
                    for (int l = 0; l < 2; l++)
                    {
                        dp[i][j][k][l] = -1;
                    }
                }
            }
        }
 
        return memo(0, 0, 0, 1);
    }
 
    // Driver Code
    public static void main(String[] args)
    {
        int L, R;
        L = 2;
        R = 10;
        System.out.println(CountNum(R) - CountNum(L - 1));
 
    }
}
 
// This code is contributed by Princi Singh


Python3




# Python code to count number in the range
# having the sum of even digits greater
# than the sum of odd digits
 
def memo(index, evenSum, oddSum, tight):
 
    # Base Case
    if index == len(v):
 
        # check if condition satisfied or not
        if evenSum > oddSum:
            return 1
        else:
            return 0
 
    # If this result is already computed
    # simply return it
    if dp[index][evenSum][oddSum][tight] != -1:
        return dp[index][evenSum][oddSum][tight]
 
    # Maximum limit upto which we can place
    # digit. If tight is 0, means number has
    # already become smaller so we can place
    # any digit, otherwise num[index]
    limit = v[index] if tight else 9
 
    ans = 0
 
    for d in range(limit + 1):
        currTight = 0
 
        if d == v[index]:
            currTight = tight
 
        # if current digit is odd
        if d % 2 != 0:
            ans += memo(index + 1, evenSum,
                        oddSum + d, currTight)
 
        # if current digit is even
        else:
            ans += memo(index + 1, evenSum + d,
                            oddSum, currTight)
 
    dp[index][evenSum][oddSum][tight] = ans
    return ans
 
# Function to convert n into its digit vector
# and uses memo() function to return the
# required count
def countNum(n):
    global dp, v
 
    v.clear()
    num = []
    while n:
        v.append(n % 10)
        n //= 10
 
    v.reverse()
 
    # Initialize dp
    dp = [[[[-1, -1] for i in range(180)] for j in range(180)]
        for k in range(18)]
    return memo(0, 0, 0, 1)
 
# Driver Code
if __name__ == "__main__":
    dp = []
    v = []
 
    L = 2
    R = 10
    print(countNum(R) - countNum(L - 1))
 
# This code is contributed by
# sanjeev2552


C#




// C# code to count number in the range
// having the sum of even digits greater
// than the sum of odd digits
using System.Collections.Generic;
using System;
 
class GFG
{
 
    static List<int> v = new List<int>();
 
    static int [,,,]dp = new int[18,180,180,2];
 
    static int memo(int index, int evenSum,
    int oddSum, int tight)
    {
        // Base Case
 
        if (index == v.Count)
        {
            // check if condition satisfied or not
            if (evenSum > oddSum)
            {
                return 1;
            }
            else
            {
                return 0;
            }
        }
 
        // If this result is already computed
        // simply return it
        if (dp[index,evenSum,oddSum,tight] != -1)
        {
            return dp[index,evenSum,oddSum,tight];
        }
 
        // Maximum limit upto which we can place
        // digit. If tight is 0, means number has
        // already become smaller so we can place
        // any digit, otherwise num[pos]
        int limit = (tight > 0) ? v[index] : 9;
 
        int ans = 0;
 
        for (int d = 0; d <= limit; d++)
        {
            int currTight = 0;
 
            if (d == v[index])
            {
                currTight = tight;
            }
 
            // if current digit is odd
            if (d % 2 != 0)
            {
                ans += memo(index + 1, evenSum,
                        oddSum + d, currTight);
            } // if current digit is even
            else
            {
                ans += memo(index + 1, evenSum + d,
                        oddSum, currTight);
            }
        }
 
        dp[index,evenSum,oddSum,tight] = ans;
        return ans;
    }
     
    // Function to convert n into its
    // digit vector and uses memo() function
    // to return the required count
    static int CountNum(int n)
    {
        v.Clear();
        while (n > 0)
        {
            v.Add(n % 10);
            n = n / 10;
        }
 
        v.Reverse();
 
        // Initialize DP
        for (int i = 0; i < 18; i++)
        {
            for (int j = 0; j < 180; j++)
            {
                for (int k = 0; k < 180; k++)
                {
                    for (int l = 0; l < 2; l++)
                    {
                        dp[i,j,k,l] = -1;
                    }
                }
            }
        }
 
        return memo(0, 0, 0, 1);
    }
 
    // Driver Code
    public static void Main(String[] args)
    {
        int L, R;
        L = 2;
        R = 10;
        Console.WriteLine(CountNum(R) - CountNum(L - 1));
 
    }
}
 
/* This code is contributed by PrinciRaj1992 */


Javascript




// JS code to count number in the range
// having the sum of even digits greater
// than the sum of odd digits
 
let v = [];
 
let dp = new Array(18);
for (var i = 0; i < 18; i++)
{
    dp[i] = new Array(180);
    for (var j = 0; j < 180; j++)
    {
        dp[i][j] = new Array(180);
        for (var k = 0; k < 180; k++)
        {
            dp[i][j][k] = new Array(2);
            for (var l = 0; l < 2; l++)
                dp[i][j][k][l] = -1;
        }
    }
}
 
function memo(index, evenSum, oddSum, tight)
{
    // Base Case
 
    if (index == v.length) {
        // check if condition satisfied or not
        if (evenSum > oddSum)
            return 1;
        else
            return 0;
    }
 
    // If this result is already computed
    // simply return it
    if (dp[index][evenSum][oddSum][tight] != -1)
    {
        console.log(dp[index][evenSum][oddSum][tight])
        return dp[index][evenSum][oddSum][tight];
    }
 
    // Maximum limit upto which we can place
    // digit. If tight is 0, means number has
    // already become smaller so we can place
    // any digit, otherwise num[pos]
 
    let limit = (tight > 0) ? v[index] : 9;
 
    let ans = 0;
 
    for (let d = 0; d <= limit; d++) {
        var  currTight = 0;
 
        if (d == v[index])
            currTight = tight;
 
        // if current digit is odd
        if (d % 2 != 0)
            ans += memo(index + 1, evenSum,
                        oddSum + d, currTight);
 
        // if current digit is even
        else
            ans += memo(index + 1, evenSum + d,
                        oddSum, currTight);
    }
 
    dp[index][evenSum][oddSum][tight] = ans;
    return ans;
}
 
// Function to convert n into its
// digit vector and uses memo() function
// to return the required count
function CountNum(n)
{
    v = [];
    while (n > 0) {
        v.push(n % 10);
        n = Math.floor(n / 10);
    }
 
    v.reverse();
     
    // Initialize DP
    for (var i = 0; i < 18; i++)
        for (var j = 0; j < 180; j++)
            for (var k = 0; k < 180; k++)
                for (var l = 0; l < 2; l++)
                    dp[i][j][k][l] = -1
    return memo(0, 0, 0, 1);
}
 
// Driver Code
let L = 2;
let R = 10;
let a1 = CountNum(R);
let a2 = CountNum(L - 1);
console.log(a1 - a2)
 
// This code is contributed by Phasing17.


Output

4

Time Complexity : There would be at max 18*(180)*(180)*2 computations when 0 < a,b < 1018

Auxiliary Space: O(18*180*180*2), as we are using extra space.

Approach: Iterative Counting with Digit Sum Calculation

We can iterate through all the numbers in the given range and check if the sum of even digits is greater than the sum of odd digits for each number. If the condition is true, we increment a counter.

Here’s the step-by-step approach to solving this problem:

  1. Initialize a counter variable to 0.
  2. Iterate through all the numbers in the range [L,R].
  3. For each number, compute the sum of even digits and the sum of odd digits.
  4. If the sum of even digits is greater than the sum of odd digits, increment the counter.
  5. Return the counter as the final answer.

C++




#include <iostream>
#include <string>
 
using namespace std;
 
int count_numbers_with_even_digits_sum(int L, int R) {
    int count = 0;
     
    for (int num = L; num <= R; num++) {
        int even_sum = 0, odd_sum = 0;
        string num_str = to_string(num);
        for (char digit : num_str) {
            int d = digit - '0';
            if (d % 2 == 0) {
                even_sum += d;
            } else {
                odd_sum += d;
            }
        }
        if (even_sum > odd_sum) {
            count++;
        }
    }
     
    return count;
}
 
int main() {
    int L = 2;
    int R = 10;
    cout << count_numbers_with_even_digits_sum(L, R) << endl;  // Output: 4
 
    L = 2;
    R = 17;
    cout << count_numbers_with_even_digits_sum(L, R) << endl;  // Output: 7
     
    return 0;
}


Java




public class Main {
    public static int countNumbersWithEvenDigitsSum(int L, int R) {
        int count = 0;
 
        for (int num = L; num <= R; num++) {
            int evenSum = 0, oddSum = 0;
            String numStr = Integer.toString(num);
            for (int i = 0; i < numStr.length(); i++) {
                int d = numStr.charAt(i) - '0';
                if (d % 2 == 0) {
                    evenSum += d;
                } else {
                    oddSum += d;
                }
            }
            if (evenSum > oddSum) {
                count++;
            }
        }
 
        return count;
    }
 
    public static void main(String[] args) {
        int L = 2;
        int R = 10;
        System.out.println(countNumbersWithEvenDigitsSum(L, R));  // Output: 4
 
        L = 2;
        R = 17;
        System.out.println(countNumbersWithEvenDigitsSum(L, R));  // Output: 7
    }
}


Python3




def count_numbers_with_even_digits_sum(L, R):
    count = 0
     
    for num in range(L, R+1):
        even_sum = odd_sum = 0
        for digit in str(num):
            if int(digit) % 2 == 0:
                even_sum += int(digit)
            else:
                odd_sum += int(digit)
        if even_sum > odd_sum:
            count += 1
     
    return count
# Example 1
L = 2
R = 10
print(count_numbers_with_even_digits_sum(L, R))  # Output: 4
 
# Example 2
L = 2
R = 17
print(count_numbers_with_even_digits_sum(L, R))  # Output: 7


C#




using System;
 
public class Program
{
    public static int CountNumbersWithEvenDigitsSum(int L, int R) {
        int count = 0;
 
        for (int num = L; num <= R; num++) {
            int even_sum = 0, odd_sum = 0;
            string num_str = num.ToString();
            foreach (char digit in num_str) {
                int d = digit - '0';
                if (d % 2 == 0) {
                    even_sum += d;
                } else {
                    odd_sum += d;
                }
            }
            if (even_sum > odd_sum) {
                count++;
            }
        }
 
        return count;
    }
 
    public static void Main()
    {
        int L = 2;
        int R = 10;
        Console.WriteLine(CountNumbersWithEvenDigitsSum(L, R)); // Output: 4
 
        L = 2;
        R = 17;
        Console.WriteLine(CountNumbersWithEvenDigitsSum(L, R)); // Output: 7
    }
}


Javascript




// A function to count the numbers in a given range [L, R]
// such that the sum of digits at even places is greater than
// the sum of digits at odd places
function count_numbers_with_even_digits_sum(L, R) {
    let count = 0;
     
    // Iterate over the numbers in the range [L, R]
    for (let num = L; num <= R; num++) {
        let even_sum = 0, odd_sum = 0;
         
        // Convert the current number to a string to iterate over its digits
        let num_str = num.toString();
        for (let digit of num_str) {
            let d = parseInt(digit);
             
            // If the current digit is even, add it to even_sum
            // Otherwise, add it to odd_sum
            if (d % 2 === 0) {
                even_sum += d;
            } else {
                odd_sum += d;
            }
        }
         
        // If the sum of digits at even places is greater than the sum
        // of digits at odd places, increment the count
        if (even_sum > odd_sum) {
            count++;
        }
    }
     
    // Return the final count of numbers with even digits sum greater than odd digits sum
    return count;
}
 
// Test the function with some sample inputs
let L = 2;
let R = 10;
console.log(count_numbers_with_even_digits_sum(L, R));  // Output: 4
 
L = 2;
R = 17;
console.log(count_numbers_with_even_digits_sum(L, R));  // Output: 7
 
//This code is written by sundaram


Output

4
7

The time complexity of the given approach is O((R-L+1)*d), where d is the number of digits in the largest number in the range [L,R]. 

The auxiliary space used by the algorithm is O(d)



Last Updated : 27 Mar, 2023
Like Article
Save Article
Previous
Next
Share your thoughts in the comments
Similar Reads