Count Numbers in Range with difference between Sum of digits at even and odd positions as Prime in C++

C++Server Side ProgrammingProgramming

Given two numbers start and end as range variables. The goal is to find the count of numbers that lie in this range [start,end] and have a difference of sum of digits at even and sum of digits at odd positions as Prime.

That is (sum of digits at even position)-(sum of digits at odd position) = a Prime number

Let us understand with examples.

For Example

Input - start = 230, end = 270

Output - Count of Numbers in Range with difference between Sum of digits at even and odd positions as Prime are: 6

Explanation -  The number(s) between 230 to 270 that meet the condition are:

240 ( 4-2 is 2 ), 250 ( 5-2 is 3 ), 251 ( 5-3 is 2 ), 261 ( 6-3 is 3 ), 262 ( 6-4 is 2 ), 270 ( 7-2 is 5 ).

All these differences are 2, 3 and 5 which are primes.

Input - start = 1101, end = 1120

Output - Count of Numbers in Range with difference between Sum of digits at even and odd positions as Prime are: 1

Explanation - The number(s) between 1101 to 1120 that meet the condition are:

1120 ( 3-1 is 2 ). 2 is prime. 

Approach used in the below program is as follows

In this we use a dynamic programming approach and store the counts of numbers that have Prime differences of sum of even and odd position digits. This array would be arr[size][90][90][2]. Here size is the power of 10. So the largest number as input will be 10size

In each recursive call to function check(int place, int eve, int od, int temp, vector<int> vec) we will build a number by placing digits 0 to 9 from left to right.

In arr[size][x][y][temp], x is for sums of digits at even positions placed upto x and y is for sums of odd digits placed upto y. Check if the required difference is Prime or not using array arr_2[] which stores all prime numbers upto 100 in order. 

  • Take variables start and end as input.
  • Take global array arr[size][90][90][2] and array arr_2[] for primes up to 100.
  • Function check(int place, int eve, int od, int temp, vector<int> vec) takes current position of digit as place, current sum of eve position digits as even and odd position digits as od, value of temp and vector vec which has digits. 
  • It populates values at arr[place][eve][od][temp] recursively.
  • Take initial value for current element as count=0.
  • For current position, check if place is last position using if(place == vec.size()). If yes check if that position is odd or even.
  • if(vec.size() & 1) results true then current position is odd so swap eve with od as it is odd length number.
  • Calculate temp_2 as difference of sums as eve-od.
  • Using for loop, traverse arr_2[] and check if temp_2 is found. If yes then its prime. So return 1 else return 0.
  • If arr[place][eve][od][temp] is already computed then it would not be -1 so return it.
  • If temp is non-zero then set temp_3=9. Temp_3 is the maximum limit of the digit which we can place. If it is 0 then place vec[place] otherwise the number is already smaller so place any digit say 9.
  • Traverse digits from 0 to temp_3. If the current position is odd then update  set_odd = set_odd + i; ( previous odd position sum + current digit i ).
  • If the current position is even then update  set_even = set_even + i; ( previous even position sum + current digit i ).
  • Set count += check(place + 1, set_even, set_odd, set_temp, vec); and return arr[place][eve][od][temp] = count.
  • Function place_prime(int val) takes the number val and generates a vector vec containing its digit from LSB to MSB.
  • Set the whole array arr[][][][] with -1.
  • Take count = check(0, 0, 0, 0, vec) which will return the result at end.
  • Return the count as result. 

Example

Live Demo

#include <bits/stdc++.h>
using namespace std;
const int size = 18;
int arr[size][90][90][2];
//firt 100 prime Numbers
int arr_2[] = {
   2,
   3,
   5,
   7,
   11,
   13,
   17,
   19,
   23,
   29,
   31,
   37,
   43,
   47,
   53,
   59,
   61,
   67,
   71,
   73,
   79,
   83,
   89,
   97
};

int check(int place, int eve, int od, int temp, vector < int > vec) {
   int count;
   int temp_3;
   if (place == vec.size()) {
      if (vec.size() & 1) {
         swap(od, eve);
      }
      int temp_2 = eve - od;
      for (int i = 0; i < 24; i++) {
         if (temp_2 == arr_2[i]) {
            return 1;
         }
      }
      return 0;
   }
   if (arr[place][eve][od][temp] != -1) {
      int set = arr[place][eve][od][temp];
      return set;
   }
   if (temp) {
      temp_3 = 9;
   } else {
      temp_3 = vec[place];
   }
   for (int i = 0; i <= temp_3; i++) {
      int set_temp = temp;
      int set_even = eve;
      int set_odd = od;
      if (i < vec[place]) {
         set_temp = 1;
      }
      if (place & 1) {
         set_odd = set_odd + i;
      } else {
         set_even = set_even + i;
      }
      count += check(place + 1, set_even, set_odd, set_temp, vec);
   }
   return arr[place][eve][od][temp] = count;
}

int place_prime(int val) {
   vector < int > vec;

   while (val) {
      vec.push_back(val % 10);
      val = val / 10;
   }
   reverse(vec.begin(), vec.end());
   memset(arr, -1, sizeof(arr));
   int count = check(0, 0, 0, 0, vec);
   return count;
}
int main() {
   int start = 20, end = 80;
   int count = place_prime(end) - place_prime(start - 1);
   cout << "Count of Numbers in Range with difference between Sum of digits at even and odd positions as Prime are: " << count;
   return 0;
}

If we run the above code it will generate the following output −

Output

Count of Numbers in Range with difference between Sum of digits at even and odd positions as Prime are: 15
raja
Published on 29-Jan-2021 12:23:11
Advertisements