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

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: 4
2, 4, 6 and 8 are the only integers from the
given range that satisfy the given conditions.

Input: L = 1, R = 19
Output: 4

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



Approach:

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:

filter_none

edit
close

play_arrow

link
brightness_4
code

// 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
chevron_right

filter_none

edit
close

play_arrow

link
brightness_4
code

# 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)
chevron_right

Output:
431

Time Complexity: O(logn)




Recommended Posts:


Check out this Author's contributed articles.

If you like GeeksforGeeks and would like to contribute, you can also write an article using contribute.geeksforgeeks.org or mail your article to contribute@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.

Please Improve this article if you find anything incorrect by clicking on the "Improve Article" button below.



Improved By : sanjeev2552, chaudhary_19

Article Tags :
Practice Tags :