Open In App

Count of integers in a range which have even number of odd digits and odd number of even digits

Improve
Improve
Like Article
Like
Save
Share
Report

Given a range [L, R], the task is to count the numbers which have even number of odd digits and odd number of even digits. For example, 

  1. 8 has 1 even digit and 0 odd digit – Satisfies the condition since 1 is odd and 0 is even.
  2. 545 has 1 even digit and 2 odd digits – Satisfies the condition since 1 is odd and 2 is even.
  3. 4834 has 3 even digits and 1 odd digit – Does not satisfy the condition since there are odd numbers(i.e 1) of odd digits.

Examples: 

Input: L = 1, R = 9 
Output:
2, 4, 6 and 8 are the only integers from the 
given range that satisfy the given conditions.

Input: L = 1, R = 19 
Output:

Input: L = 123, R = 984 
Output: 431 

Approach:  

  • Case 1 
    There is a pattern in which these numbers occur between 1         and 10^{k}         (where 1<=k<=18). 
    Number of occurrences from 
    • 1 – 10 and 1 – 100 are 4
    • 1 – 1000 and 1 – 10000 are 454
    • 1 – 10000 and 1 – 100000 are 45454
  • Case 2 
    • If the number of digits in a number is even then it cannot satisfy the given condition because we need an odd number(of digits) and an even number(of digits) to satisfy our condition and odd number + even number is always odd
    • So if the number of digits for a given number(say n) is even then its number of occurrences from 1 is equal to the number of occurrences from 1         to largest 10^{k}         (1<=k<=18) which is less than n

Example: 
Let n = 19, number of digits in 19 are 2 
Therefore number of occurrences from 1 – 19 = number of occurrences from 1 – 10 (since 10 the largest 10^{k}         less than 19) 
 

  • Case 3 
    If number of digits for a given number(say n) are odd then number of occurrences between 10^{k}+1         and n is equal to

where 10^{i}         is the largest 10^{k}         less than n.


Implementation: Now we now how to calculate the number of occurrences from 1 to given n. Therefore, 
Number of occurrences from L to R = NumberOfOccurrencesUpto(R) – NumberOfOccurrencesUpto(L – 1) where L is not equal to 1.

Below is the implementation of the above approach:  

C++14

// C++ implementation of the approach
#include <bits/stdc++.h>
using namespace std;
 
#define ll long long
 
// Pattern table from Case 1
map<ll, ll> values{{1, 0},
                   {10, 4},
                   {100, 4},
                   {1000, 454},
                   {10000, 454},
                   {100000, 45454},
                   {1000000, 45454},
                   {10000000, 4545454},
                   {100000000, 4545454},
                   {1000000000, 454545454},
                   {10000000000, 454545454},
                   {100000000000, 45454545454},
                   {1000000000000, 45454545454},
                   {10000000000000, 4545454545454},
                   {100000000000000, 4545454545454},
                   {1000000000000000, 454545454545454},
                   {10000000000000000, 454545454545454},
                   {100000000000000000, 45454545454545454},
                   {1000000000000000000, 45454545454545454}};
 
// Function that returns the number of
// even and odd digits in val
pair<ll, ll> count_even_odd(ll val)
{
    ll even = 0, odd = 0;
    while (val)
    {
        ll num = val % 10;
        if (num % 2 == 0)
            even++;
        else
            odd++;
        val /= 10;
    }
    return make_pair(even, odd);
}
 
// Function that returns True if num
// satisfies the given condition
bool satisfies_condition(ll num)
{
    pair<ll, ll> answer = count_even_odd(num);
    ll even = answer.first;
    ll odd = answer.second;
 
    if (even % 2 == 1 and
         odd % 2 == 0) return true;
    return false;
}
 
// Function to return the count of
// numbers from 1 to val that
// satisfies the given condition
ll count_upto(ll val)
{
    // If the value is already present
    // in the values dict
    if (values.find(val) != values.end())
        return values[val];
 
    ll index = 1;
    for (int i = 0;
             i < to_string(val).length() - 1;
             i++)
         index *= 10;
 
    // If the value is even
    // Case 2
    if (to_string(val).length() % 2 == 0)
        return values[index];
 
    ll val_len = to_string(val).length();
    ll cnt = values[index];
 
    // Now the problem is to count the desired
    // numbers from 10**(val_len-1) + 1 to val
    ll left_end = index + 1;
 
    // Case 3
    // Eliminating all the even numbers
    cnt += (val - left_end) / 2;
    if (satisfies_condition(val) or
        satisfies_condition(left_end))
        cnt++;
 
    return cnt;
}
 
// Driver Code
int main()
{
    // Input l and r
    ll l = 123, r = 984;
    ll right = count_upto(r);
    ll left = 0;
 
    if (l == '1')
        left = 0;
    else
        left = count_upto(l - 1);
 
    cout << right - left << endl;
    return 0;
}
 
// This code is contributed by
// sanjeev2552

                    

Java

// Java implementation of the approach
import java.io.*;
import java.lang.*;
import java.util.*;
 
class GFG{
 
// Pattern table from Case 1
static HashMap<Long, Long> values = new HashMap<>();
 
public static void intitializeMap()
{
    values = new HashMap<>();
    values.put(1L, 0L);
    values.put(10L, 4L);
    values.put(100L, 4L);
    values.put(1000L, 454L);
    values.put(10000L, 454L);
    values.put(100000L, 45454L);
    values.put(1000000L, 45454L);
    values.put(10000000L, 4545454L);
    values.put(100000000L, 4545454L);
    values.put(1000000000L, 454545454L);
    values.put(10000000000L, 454545454L);
    values.put(100000000000L, 45454545454L);
    values.put(1000000000000L, 45454545454L);
    values.put(10000000000000L, 4545454545454L);
    values.put(100000000000000L, 4545454545454L);
    values.put(1000000000000000L, 454545454545454L);
    values.put(10000000000000000L, 454545454545454L);
    values.put(100000000000000000L, 45454545454545454L);
    values.put(1000000000000000000L, 45454545454545454L);
}
 
// Function that returns the number of
// even and odd digits in val
static long[] count_even_odd(long val)
{
    long even = 0, odd = 0;
    while (val > 0)
    {
        long num = val % 10;
        if (num % 2 == 0)
            even++;
        else
            odd++;
             
        val /= 10;
    }
    return (new long[] { even, odd });
}
 
// Function that returns True if num
// satisfies the given condition
static boolean satisfies_condition(long num)
{
    long[] answer = count_even_odd(num);
    long even = answer[0];
    long odd = answer[1];
 
    if (even % 2 == 1 && odd % 2 == 0)
        return true;
         
    return false;
}
 
// Function to return the count of
// numbers from 1 to val that
// satisfies the given condition
static long count_upto(long val)
{
     
    // If the value is already present
    // in the values dict
    if (values.containsKey(val))
        return values.get(val);
 
    long index = 1;
    for(int i = 0;
            i < Long.toString(val).length() - 1;
            i++)
        index *= 10;
 
    // If the value is even
    // Case 2
    if (Long.toString(val).length() % 2 == 0)
        return values.get(index);
 
    long val_len = Long.toString(val).length();
    long cnt = values.get(index);
 
    // Now the problem is to count the desired
    // numbers from 10**(val_len-1) + 1 to val
    long left_end = index + 1;
 
    // Case 3
    // Eliminating all the even numbers
    cnt += (val - left_end) / 2;
    if (satisfies_condition(val) ||
        satisfies_condition(left_end))
        cnt++;
 
    return cnt;
}
 
// Driver Code
public static void main(String[] args)
{
     
    // Input l and r
    long l = 123, r = 984;
 
    // Function to initialize the Map
    intitializeMap();
 
    long right = count_upto(r);
    long left = 0;
 
    if (l == '1')
        left = 0;
    else
        left = count_upto(l - 1);
 
    System.out.println(right - left);
}
}
 
// This code is contributed by Kingash

                    

Python3

# Python3 implementation of the approach
 
# Pattern table from Case 1
values = {
    1: 0,
    10: 4,
    100: 4,
    1000: 454,
    10000: 454,
    100000: 45454,
    1000000: 45454,
    10000000: 4545454,
    100000000: 4545454,
    1000000000: 454545454,
    10000000000: 454545454,
    100000000000: 45454545454,
    1000000000000: 45454545454,
    10000000000000: 4545454545454,
    100000000000000: 4545454545454,
    1000000000000000: 454545454545454,
    10000000000000000: 454545454545454,
    100000000000000000: 45454545454545454,
    1000000000000000000: 45454545454545454,
}
 
# Function that returns the number of
# even and odd digits in val
def count_even_odd(val):
    even = odd = 0
    while val > 0:
        num = val % 10
        if num % 2 == 0:
            even += 1
        else:
            odd += 1
        val //= 10
 
    return even, odd
 
# Function that returns True if num
# satisfies the given condition
def satisfies_condition(num):
    even, odd = count_even_odd(num)
    if even % 2 == 1 and odd % 2 == 0:
        return True
    return False
 
 
# Function to return the count of numbers
# from 1 to val that satisfies the given condition
def count_upto(val):
 
    # If the value is already present in the
    # values dict
    if int(val) in values:
        return values[int(val)]
 
    # If the value is even
    # Case 2
    if len(val) % 2 == 0:
        return values[int('1' + '0' * (len(val) - 1))]
 
    val_len = len(val)
    count = values[int('1' + '0' * (val_len - 1))]
 
    # Now the problem is to count the desired
    # numbers from 10**(val_len-1) + 1 to val
    left_end = int('1' + '0' * (val_len - 1)) + 1
 
    # Case 3
    # Eliminating all the even numbers
    count += (int(val) - left_end) // 2
 
    if satisfies_condition(int(val)) or satisfies_condition(left_end):
        count += 1
    return count
 
 
if __name__ == '__main__':
 
    # Input L and R ( as a string )
    l, r = '123', '984'
 
    right = count_upto(r)
 
    left = 0
    if(l == '1'):
        left = 0
    else:
        left = count_upto(str(int(l)-1))
 
    print(right - left)

                    

C#

// C# implementation of the approach
using System;
using System.Collections.Generic;
 
class GFG{
 
// Pattern table from Case 1
static Dictionary<long,
                  long> values = new Dictionary<long,
                                                long>();
 
public static void intitializeMap()
{
    values = new Dictionary<long, long>();
    values.Add(1L, 0L);
    values.Add(10L, 4L);
    values.Add(100L, 4L);
    values.Add(1000L, 454L);
    values.Add(10000L, 454L);
    values.Add(100000L, 45454L);
    values.Add(1000000L, 45454L);
    values.Add(10000000L, 4545454L);
    values.Add(100000000L, 4545454L);
    values.Add(1000000000L, 454545454L);
    values.Add(10000000000L, 454545454L);
    values.Add(100000000000L, 45454545454L);
    values.Add(1000000000000L, 45454545454L);
    values.Add(10000000000000L, 4545454545454L);
    values.Add(100000000000000L, 4545454545454L);
    values.Add(1000000000000000L, 454545454545454L);
    values.Add(10000000000000000L, 454545454545454L);
    values.Add(100000000000000000L, 45454545454545454L);
    values.Add(1000000000000000000L, 45454545454545454L);
}
 
// Function that returns the number of
// even and odd digits in val
static long[] count_even_odd(long val)
{
    long even = 0, odd = 0;
     
    while (val > 0)
    {
        long num = val % 10;
        if (num % 2 == 0)
            even++;
        else
            odd++;
             
        val /= 10;
    }
    return (new long[]{ even, odd });
}
 
// Function that returns True if num
// satisfies the given condition
static bool satisfies_condition(long num)
{
    long[] answer = count_even_odd(num);
    long even = answer[0];
    long odd = answer[1];
 
    if (even % 2 == 1 && odd % 2 == 0)
        return true;
         
    return false;
}
 
// Function to return the count of
// numbers from 1 to val that
// satisfies the given condition
static long count_upto(long val)
{
     
    // If the value is already present
    // in the values dict
    if (values.ContainsKey(val))
        return values[val];
 
    long index = 1;
    for(int i = 0;
            i < val.ToString().Length - 1;
            i++)
        index *= 10;
 
    // If the value is even
    // Case 2
    if (val.ToString().Length % 2 == 0)
        return values[index];
 
    long val_len = val.ToString().Length;
    long cnt = values[index];
 
    // Now the problem is to count the desired
    // numbers from 10**(val_len-1) + 1 to val
    long left_end = index + 1;
 
    // Case 3
    // Eliminating all the even numbers
    cnt += (val - left_end) / 2;
    if (satisfies_condition(val) ||
        satisfies_condition(left_end))
        cnt++;
 
    return cnt;
}
 
// Driver Code
public static void Main(String[] args)
{
     
    // Input l and r
    long l = 123, r = 984;
 
    // Function to initialize the Map
    intitializeMap();
 
    long right = count_upto(r);
    long left = 0;
 
    if (l == '1')
        left = 0;
    else
        left = count_upto(l - 1);
 
    Console.WriteLine(right - left);
}
}
 
// This code is contributed by umadevi9616

                    

Javascript

<script>
 
// JavaScript implementation of the approach
 
// Pattern table from Case 1
let values = new Map();
values.set(1, 0)
values.set(10, 4)
values.set(100, 4)
values.set(1000, 454)
values.set(10000, 454)
values.set(100000, 45454)
values.set(1000000, 45454)
values.set(10000000, 4545454)
values.set(100000000, 4545454)
values.set(1000000000, 454545454)
values.set(10000000000, 454545454)
values.set(100000000000, 45454545454)
values.set(1000000000000, 45454545454)
values.set(10000000000000, 4545454545454)
values.set(100000000000000, 4545454545454)
values.set(1000000000000000, 454545454545454)
values.set(10000000000000000, 454545454545454)
values.set(100000000000000000, 45454545454545454)
values.set(1000000000000000000, 45454545454545454)
 
// Function that returns the number of
// even and odd digits in val
function count_even_odd(val)
{
    let even = 0, odd = 0;
    while (val)
    {
        let num = val % 10;
        if (num % 2 == 0)
            even++;
        else
            odd++;
        val = Math.floor(val/10);
    }
    return [even, odd];
}
 
// Function that returns True if num
// satisfies the given condition
function satisfies_condition(num)
{
    let answer = count_even_odd(num);
    let even = answer[0];
    let odd = answer[1];
 
    if (even % 2 == 1 &&
        odd % 2 == 0) return true;
    return false;
}
 
// Function to return the count of
// numbers from 1 to val that
// satisfies the given condition
function count_upto(val)
{
 
    // If the value is already present
    // in the values dict
    if (values.has(val) == true)
        return values.get(val);
 
    let index = 1;
    for (let i = 0;i < val.toString().length - 1;i++)
        index *= 10;
 
    // If the value is even
    // Case 2
    if (val.toString().length % 2 == 0)
        return values.get(index);
 
    let val_len = Number.toString(val).length;
    let cnt = values.get(index);
 
    // Now the problem is to count the desired
    // numbers from 10**(val_len-1) + 1 to val
    let left_end = index + 1;
 
    // Case 3
    // Eliminating all the even numbers
    cnt += Math.floor((val - left_end) / 2);
    if (satisfies_condition(val) ||
        satisfies_condition(left_end))
        cnt++;
 
    return cnt;
}
 
// Driver Code
 
// Input l and r
let l = 123, r = 984;
let right = count_upto(r);
let left = 0;
 
if (l == '1')
    left = 0;
else
    left = count_upto(l - 1);
 
document.write(right - left);
 
// This code is contributed by shinjanpatra
 
</script>

                    

Output: 
431

 

Time Complexity: O(logn)
 Auxiliary Space: O(19*2)



Last Updated : 25 Feb, 2022
Like Article
Save Article
Previous
Next
Share your thoughts in the comments
Similar Reads