Magical Numbers

Moderate
0/80
Average time to solve is 60m
profile
Contributed by
2 upvotes
Asked in companies
Anukta IT SolutionsFlipkart limited

Problem statement

You are given three integers ‘A’, ‘B’ and ’K’. Your task is to find the number of Magical Numbers between ‘A’ and ‘B’(inclusive). A number ‘N’ is said to be a magical number if the sum of its digits is prime and the number ‘N’ is divisible by ‘K’.

For example:

Forgiven A = 10, B = 15 and K = 2.
12 and 14 are magical numbers because the sum of digits of 12 and 14 is a prime number, also 12 and 14 both are divisible by 2.  
Detailed explanation ( Input/output format, Notes, Images )
Input Format:
The first line of input contains an integer ‘T’, denoting the number of test cases. Then each test case follows.

The first and the last line of each test case contains three space-separated integers denoting ‘A’, ‘B’, and ‘K’.
Output Format:
For each test case, print a single line containing one integer, denoting the number of Magical Numbers between ‘A’ and ‘B’(inclusive)

The output of each test case will be printed on a separate line.
Note:
You do not need to print anything, it has already been taken care of. Just implement the given function.
Constraints:
1 <= T <= 5
1 <= A <= B <= 10^9
1 <= K <= 100

Time Limit: 1 sec.
Sample Input 1:
2
10 15 2
2 14 7
Sample Output 1:
2
2
Explanation of Sample Output 1:
In the first test case, there are two magical numbers 12 and 14, because the sum of digits of 12 and 14 is a prime number, also 12 and 14 both are divisible by 2. 

Similarly, In the second test case, 7 and 14 are magical numbers.
Sample Input 2:
1
15 76 5
Sample Output 2:
6
Explanation of Sample Output 2:
In the first test case, the numbers 20, 25, 30, 50, 65, 70 are only magical numbers.
Hint

Try to form a sequence of numbers that is less than equal to ‘X’ and keep track of sum, remainder.

Approaches (1)
Using Digit - DP

Let, magicalNumbers(x, y) = magical number between x and y(inclusive)

Then, magicalNumbers(A, B) = magicalNumbers(1, B) - magicalNumbers(1, A -1).

 

Let's solve the above two sub-problem magicalNumbers(1, X) individually, 

 

The idea is to use digit - dp.

  • We will form a sequence of numbers that is less than equal to ‘X’.
  • Use an extra variable ‘isSmall’ to keep track of whether the number formed till now is smaller than ‘X’ or not.
  • If the sequence of numbers has become small then we can put the next digit till 9.
  • Otherwise, the limit of the next digit will be till digit in number ‘X’ at that position.
  • Keep the track of sum and remainder after attaching the new digit.
  • The number of digits in ‘A‘ and ‘B’ can maximum go till 11. So the sum of digits can maximum go till 11 * 9 = 99. So we will precalculate whether ‘sum’ is prime or not using a sieve.
  • The maximum remainder can go till K - 1.
  • To avoid repetition of subproblems we can use memoization.

 

Algorithm :

 

Consider the global array isPrime [130 ], if ‘i’ is prime then isPrime[ i ] = 1 else 0 and 4D array for memoization ‘dp[13][130][1005][3]’.

 

  • Let ‘A’, ’B’, and ‘K’ be the given numbers.
  • Initialize the ‘isPrime’ array with the ‘1’ call function ‘sieve’.
  • Declare ‘countNumber(X, K)’ function to get the magic number from 1 to ‘X.’
  • Call function countNumbers(B, K) and store the return value in ‘ans1’.
  • Call function countNumbers(A-1, K) and store the return value in ‘ans2.
  • Return ans1 - ans2.

 

Description of countNumbers(num, K) function:

  • Take an array ‘vec’, to store all the digits of num.
  • Run loop while num is not equal to zero
    • Push back (‘num’ % 10) in ‘vec’
  • Reverse the ‘vec’ array
  • Initialize ‘dp’ with -1.
  • Call helper(vec, 0, 0, 0, K, 0) function and store the return value in ‘ans’.
  • Return ‘ans’.

 

Description of helper(vec, idx, sum, rem, K, isSmall):

 

The ‘helper’ function returns the number of magical numbers which are less than or equal to the sequence of numbers in the ‘vec’ array. It takes four-parameter (‘vec’, current index, the sum of digits till current index, the remainder of a sequence of the number formed till current index, ‘K’,  ‘isSmall’ variable if it is 1, means current sequence of numbers are smaller than the given sequence in ‘vec’ else equal.  


 

  • If ‘vec’ size is equal to ‘idx’
    • If isPrime[sum] is equal to 1 and rem is equal to 0.
      • Return 1
    • Else
      • return 0
  • If dp[idx][sum][rem][isSmall] is not equal to -1
    • Return dp[idx][sum][rem][isSmall]
  • Take a variable ‘limit’, that store the limit of current index
    • If isSmall is 1
      • ‘limit’ is equal to 9.
    • Else
      • ‘limit’ is equal to vec[idx]
  • Take a variable ‘ans’ initialize it to zero.
  • Run a loop from 0 to equal to ‘limit’
    • If isSmall is 0 and counter ‘i’ is equal to limit
      • Do recursive call on helper(vec, idx +1, sum + i, (rem * 10 + ‘i’ ) % ‘K’, ‘ K’, ‘isSmall’) function and add the return value to ‘ans’
    • Else
      • Do recursive call on helper(vec, idx +1, sum + i, (rem * 10 + ‘i’ ) % ‘K’, ‘ K’, 0) function and add the return value to ‘ans’
  • Update dp[idx][sum][rem][isSmall] = ‘ans’
  • Return ‘ans’.
Time Complexity

O (((log (max(A,  B))) ^ 2) *  K), where ‘A’, ‘B’ and ‘K’ are the given integers.

 

We are solving a similar problem twice, so the time complexity depends on the number which has a higher number of digits which is equal to the max of log10(‘A’) and log10(‘B’).

‘idx’ is O(log (max(A,  B))  Sum is also the function of the number of digits O(log (max(A,  B) * 9) and the remainder can range from 0 to ‘K’ -1 so O(‘K’) and ‘isSmall’ can take value 0 or 1. 

So the overall time complexity is O(((log(max(A, B))) * (log(max(A, B)))) * K * 2) = O (((log (max(A,  B))) ^ 2) *  K).

Space Complexity

O (log((max (A,  B) ) ^ 2) *  K )   where ‘A’, ‘B’ and ‘K’ are the given integers.

 

We need O( log( max(A, B) ) ) * 9 space(maximum sum of digits) for ‘isPrime’ array and O( log(max(A, B) ^  2) * K for memoization. Hence space complexity is O(log( max(A,B)) ^2 * K) +O( log(max(A, B)) = O (log( (max(A,  B) )^ 2) *  K ).

Code Solution
(100% EXP penalty)
Magical Numbers
Full screen
Console