Open In App

Number of integers of size N having even sum of digits

Last Updated : 30 Jan, 2023
Improve
Improve
Like Article
Like
Save
Share
Report

Given the number N, the task is to count a number of ways to create a number with digit size N with the sum of digits even. print the answer modulo 109 + 7. (1 <= N <= 105)

Examples:

Input: N = 1
Output: 4
Explanation: 2, 4, 6 and 8 are the numbers.

Input: N = 2
Output:  45
Explanation: 11, 13, 15, 17, 19, 20, 22, 24, 26, 28, 31, 33, 35, 37, 39, 40, 42, 44, 46, 48, 51, 53, 55, 57, 59, 60, 62, 64, 66, 68, 71, 73, 75, 77, 79, 80, 82, 84, 86, 88, 91, 93, 95, 97, and 99 are the possible numbers.

Naive approach: The basic way to solve the problem is as follows:

The basic way to solve this problem is to generate all possible combinations by using a recursive approach.

Time Complexity: O(10N)
Auxiliary Space: O(1)

Efficient Approach:  The above approach can be optimized based on the following idea:

Dynamic programming can be used to solve this problem. For solving this problem its very simple to make finite automata machine for states with following transitions:

  • dp[i][j] represents number of ways of creating numbers with i digits and j represents current state of state machine.
  • It can be observed that the recursive function is called exponential times. That means that some states are called repeatedly. 
  • So the idea is to store the value of each state. This can be done by using the stored value of a state and whenever the function is called, return the stored value without computing again.

Follow the steps below to solve the problem:

  • Create a recursive function that takes two parameters representing i’th position to be filled with digit and j representing the current state of Finite State Machine.
  • Call the recursive function for choosing all digits from 0 to 9.
  • Base case if digit of size N formed return 1 if the current state even else returns 0.
  • Create a 2d array of dp[N][3] initially filled with -1.
  • If the answer for a particular state is computed then save it in dp[i][j].
  • If the answer for a particular state is already computed then just return dp[i][j].

Below is the implementation of the above approach:

C++




// C++ code to implement the approach
#include <bits/stdc++.h>
using namespace std;
 
const int MOD = 1e9 + 7;
 
// DP table initialized with -1
int dp[1000001][3];
 
// Recursive Function to count ways to create
// number of N digits such that its digit sum
// is even.
int recur(int i, int j)
{
    // Base case
    if (i == 0) {
 
        // If current sum is even
        if (j == 2)
            return 1;
 
        // Else if sum is odd
        else
            return 0;
    }
 
    // If answer for current state is already
    // calculated then just return dp[i][j]
    if (dp[i][j] != -1)
        return dp[i][j];
 
    // Answer initialized with zero
    int ans = 0;
 
    // start state of automata machine
    if (j == 0) {
        // If odd digit is picked then it
        // will move to automata state 1
        for (int k = 1; k <= 9; k += 2) {
            ans += recur(i - 1, 1);
            ans %= MOD;
        }
 
        // If even digit is picked then it
        // will move to automata state 2
        for (int k = 2; k <= 8; k += 2) {
            ans += recur(i - 1, 2);
            ans %= MOD;
        }
    }
 
    // Odd state of automata machine
    else if (j == 1) {
 
        // If odd digit picked then it
        // will move to automata state 2
        for (int k = 1; k <= 9; k += 2) {
            ans += recur(i - 1, 2);
            ans %= MOD;
        }
 
        // If even digit picked then it
        // will remain on same state 1
        for (int k = 2; k <= 8; k += 2) {
            ans += recur(i - 1, 1);
            ans %= MOD;
        }
    }
 
    // Even state of automata machine
    else {
 
        // If odd digit picked then it
        // will move to state 1
        for (int k = 1; k <= 9; k += 2) {
            ans += recur(i - 1, 1);
            ans %= MOD;
        }
 
        // If even digit picked then it
        // will remain on current state 2.
        for (int k = 0; k <= 8; k += 2) {
 
            ans += recur(i - 1, 2);
            ans %= MOD;
        }
    }
 
    // Save and return dp value
    return dp[i][j] = ans;
}
 
// Function to count ways to create
// number of N digits such that its digit
// sum is even.
int countWaysTo(int N)
{
 
    // Initializing dp array with - 1
    memset(dp, -1, sizeof(dp));
 
    return recur(N, 0);
}
 
// Driver Code
int main()
{
    // Input 1
    int N = 1;
 
    // Function Call
    cout << countWaysTo(N) << endl;
 
    // Input 2
    int N1 = 2;
 
    // Function Call
    cout << countWaysTo(N1) << endl;
    return 0;
}


Java




// Java code to implement the approach
 
import java.io.*;
import java.util.*;
 
class GFG {
 
static int MOD = 1000000000 + 7;
 
// DP table initialized with -1
static int dp[][] = new int[1000001][3];
 
// Recursive Function to count ways to create
// number of N digits such that its digit sum
// is even.
static int recur(int i, int j)
{
    // Base case
    if (i == 0) {
 
        // If current sum is even
        if (j == 2)
            return 1;
 
        // Else if sum is odd
        else
            return 0;
    }
 
    // If answer for current state is already
    // calculated then just return dp[i][j]
    if (dp[i][j] != -1)
        return dp[i][j];
 
    // Answer initialized with zero
    int ans = 0;
 
    // start state of automata machine
    if (j == 0) {
        // If odd digit is picked then it
        // will move to automata state 1
        for (int k = 1; k <= 9; k += 2) {
            ans += recur(i - 1, 1);
            ans %= MOD;
        }
 
        // If even digit is picked then it
        // will move to automata state 2
        for (int k = 2; k <= 8; k += 2) {
            ans += recur(i - 1, 2);
            ans %= MOD;
        }
    }
 
    // Odd state of automata machine
    else if (j == 1) {
 
        // If odd digit picked then it
        // will move to automata state 2
        for (int k = 1; k <= 9; k += 2) {
            ans += recur(i - 1, 2);
            ans %= MOD;
        }
 
        // If even digit picked then it
        // will remain on same state 1
        for (int k = 2; k <= 8; k += 2) {
            ans += recur(i - 1, 1);
            ans %= MOD;
        }
    }
 
    // Even state of automata machine
    else {
 
        // If odd digit picked then it
        // will move to state 1
        for (int k = 1; k <= 9; k += 2) {
            ans += recur(i - 1, 1);
            ans %= MOD;
        }
 
        // If even digit picked then it
        // will remain on current state 2.
        for (int k = 0; k <= 8; k += 2) {
 
            ans += recur(i - 1, 2);
            ans %= MOD;
        }
    }
 
    // Save and return dp value
    return dp[i][j] = ans;
}
 
// Function to count ways to create
// number of N digits such that its digit
// sum is even.
static int countWaysTo(int N)
{
 
    // Initializing dp array with - 1
    for(int i=0;i<1000001;i++)
    {
        for(int j=0;j<3;j++)
        {
            dp[i][j]=-1;
        }
    }
 
    return recur(N, 0);
}
 
     
// Driver code
public static void main(String[] args)
{
    // Input 1
    int N = 1;
 
    // Function Call
    System.out.println(countWaysTo(N));
 
    // Input 2
    int N1 = 2;
 
    // Function Call
    System.out.println(countWaysTo(N1));
}
}


Python3




MOD = int(1e9 + 7)
 
# DP table initialized with -1
dp = [[-1 for _ in range(3)] for _ in range(1000001)]
 
# Recursive Function to count ways to create
# number of N digits such that its digit sum
# is even.
def recur(i: int, j: int) -> int:
    # Base case
    if i == 0:
        # If current sum is even
        if j == 2:
            return 1
        # Else if sum is odd
        else:
            return 0
    # If answer for current state is already
    # calculated then just return dp[i][j]
    if dp[i][j] != -1:
        return dp[i][j]
    # Answer initialized with zero
    ans = 0
    # start state of automata machine
    if j == 0:
        # If odd digit is picked then it
        # will move to automata state 1
        for k in range(1, 10, 2):
            ans += recur(i-1, 1)
            ans %= MOD
        # If even digit is picked then it
        # will move to automata state 2
        for k in range(2, 9, 2):
            ans += recur(i-1, 2)
            ans %= MOD
    # Odd state of automata machine
    elif j == 1:
        # If odd digit picked then it
        # will move to automata state 2
        for k in range(1, 10, 2):
            ans += recur(i-1, 2)
            ans %= MOD
        # If even digit picked then it
        # will remain on same state 1
        for k in range(2, 9, 2):
            ans += recur(i-1, 1)
            ans %= MOD
    # Even state of automata machine
    else:
        # If odd digit picked then it
        # will move to state 1
        for k in range(1, 10, 2):
            ans += recur(i-1, 1)
            ans %= MOD
        # If even digit picked then it
        # will remain on current state 2.
        for k in range(0, 9, 2):
            ans += recur(i-1, 2)
            ans %= MOD
    # Save and return dp value
    dp[i][j] = ans
    return ans
 
# Function to count ways to create
# number of N digits such that its digit
# sum is even.
def countWaysTo(N: int) -> int:
    return recur(N, 0)
 
# Driver Code
if __name__ == "__main__":
    # Input 1
    N = 1
    # Function Call
    print(countWaysTo(N))
    # Input 2
    N1 = 2
    # Function Call
    print(countWaysTo(N1))


C#




// C# code to implement the approach
 
using System;
using System.Collections.Generic;
 
class GFG {
     
    static int MOD = 1000000007;
 
    // DP table initialized with -1
    static int[,] dp=new int[1000001,3];
     
    // Recursive Function to count ways to create
    // number of N digits such that its digit sum
    // is even.
    static int recur(int i, int j)
    {
        // Base case
        if (i == 0) {
     
            // If current sum is even
            if (j == 2)
                return 1;
     
            // Else if sum is odd
            else
                return 0;
        }
     
        // If answer for current state is already
        // calculated then just return dp[i][j]
        if (dp[i,j] != -1)
            return dp[i,j];
     
        // Answer initialized with zero
        int ans = 0;
     
        // start state of automata machine
        if (j == 0) {
            // If odd digit is picked then it
            // will move to automata state 1
            for (int k = 1; k <= 9; k += 2) {
                ans += recur(i - 1, 1);
                ans %= MOD;
            }
     
            // If even digit is picked then it
            // will move to automata state 2
            for (int k = 2; k <= 8; k += 2) {
                ans += recur(i - 1, 2);
                ans %= MOD;
            }
        }
     
        // Odd state of automata machine
        else if (j == 1) {
     
            // If odd digit picked then it
            // will move to automata state 2
            for (int k = 1; k <= 9; k += 2) {
                ans += recur(i - 1, 2);
                ans %= MOD;
            }
     
            // If even digit picked then it
            // will remain on same state 1
            for (int k = 2; k <= 8; k += 2) {
                ans += recur(i - 1, 1);
                ans %= MOD;
            }
        }
     
        // Even state of automata machine
        else {
     
            // If odd digit picked then it
            // will move to state 1
            for (int k = 1; k <= 9; k += 2) {
                ans += recur(i - 1, 1);
                ans %= MOD;
            }
     
            // If even digit picked then it
            // will remain on current state 2.
            for (int k = 0; k <= 8; k += 2) {
     
                ans += recur(i - 1, 2);
                ans %= MOD;
            }
        }
     
        // Save and return dp value
        return dp[i,j] = ans;
    }
     
    // Function to count ways to create
    // number of N digits such that its digit
    // sum is even.
    static int countWaysTo(int N)
    {
     
        // Initializing dp array with - 1
        for(int i=0; i<1000001; i++)
        {
            for(int j=0;j<3; j++)
                dp[i,j]=-1;
        }
        return recur(N, 0);
    }
     
    // Driver Code
    public static void Main()
    {
        // Input 1
        int N = 1;
     
        // Function Call
        Console.Write(countWaysTo(N)+"\n");
     
        // Input 2
        int N1 = 2;
     
        // Function Call
        Console.Write(countWaysTo(N1)+"\n");
    }
}


Javascript




// Javascript code to implement the approach
 
const  MOD = 1e9 + 7;
 
// DP table initialized with -1
let dp=new Array(1000001)
for(let i=0; i<1000001; i++)
    dp[i]=new Array(3).fill(-1);
 
// Recursive Function to count ways to create
// number of N digits such that its digit sum
// is even.
function recur( i, j)
{
    // Base case
    if (i == 0) {
 
        // If current sum is even
        if (j == 2)
            return 1;
 
        // Else if sum is odd
        else
            return 0;
    }
 
    // If answer for current state is already
    // calculated then just return dp[i][j]
    if (dp[i][j] != -1)
        return dp[i][j];
 
    // Answer initialized with zero
    let ans = 0;
 
    // start state of automata machine
    if (j == 0) {
        // If odd digit is picked then it
        // will move to automata state 1
        for (let k = 1; k <= 9; k += 2) {
            ans += recur(i - 1, 1);
            ans %= MOD;
        }
 
        // If even digit is picked then it
        // will move to automata state 2
        for (let k = 2; k <= 8; k += 2) {
            ans += recur(i - 1, 2);
            ans %= MOD;
        }
    }
 
    // Odd state of automata machine
    else if (j == 1) {
 
        // If odd digit picked then it
        // will move to automata state 2
        for (let k = 1; k <= 9; k += 2) {
            ans += recur(i - 1, 2);
            ans %= MOD;
        }
 
        // If even digit picked then it
        // will remain on same state 1
        for (let k = 2; k <= 8; k += 2) {
            ans += recur(i - 1, 1);
            ans %= MOD;
        }
    }
 
    // Even state of automata machine
    else {
 
        // If odd digit picked then it
        // will move to state 1
        for (let k = 1; k <= 9; k += 2) {
            ans += recur(i - 1, 1);
            ans %= MOD;
        }
 
        // If even digit picked then it
        // will remain on current state 2.
        for (let k = 0; k <= 8; k += 2) {
 
            ans += recur(i - 1, 2);
            ans %= MOD;
        }
    }
 
    // Save and return dp value
    return dp[i][j] = ans;
}
 
// Function to count ways to create
// number of N digits such that its digit
// sum is even.
function countWaysTo( N)
{
    return recur(N, 0);
}
 
// Driver Code
// Input 1
let N = 1;
 
// Function Call
console.log(countWaysTo(N));
 
// Input 2
let N1 = 2;
 
// Function Call
console.log(countWaysTo(N1));


Output

4
45

Time Complexity: O(N)  
Auxiliary Space: O(N)

Related Articles:



Like Article
Suggest improvement
Previous
Next
Share your thoughts in the comments

Similar Reads