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

Recommended: Please try your approach on {IDE} first, before moving on to the solution.

Approach:

• Case 1
There is a pattern in which these numbers occur between and (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

and so on…

• 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 to largest (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 less than 19)

• Case 3
If number of digits for a given number(say n) are odd then number of occurrences between and n is equal to

where is the largest 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++ implementation of the approach ` `#include ` `using` `namespace` `std; ` ` `  `#define ll long long ` ` `  `// Pattern table from Case 1 ` `map 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 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 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 `

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

Output:
```431
```

Time Complexity: O(logn)

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 :