Count of numbers in range [L, R] having sum of digits of its square equal to square of sum of digits - GeeksforGeeks

16 Sep, 2021
Given two integers L and R, the task is to find the count of numbers in range [L, R] such that the sum of digits of its square is equal to the square of sum of its digits, 
Example:
Input: L = 22, R = 22Output: 1Explanation: 22 is only valid number in this range as sum of digits of its square = S(22*22) = S(484) = 16 and square of sum of its digits = S(22)*S(22) = 16
Input: L = 1, R = 58Output: 12Explanation: Total valid numbers are {1, 2, 3, 10, 11, 12, 13, 20, 21, 22, 30, 31}
Naive Approach:  Run a loop from L to R and for each number calculate the sum of digits and check whether the current number satisfies the given condition or not. 
Follow  the steps below to solve the problem:
Iterate from L to R and for each number calculate its sum of digits.
Square the current number and find its sum of digits.
If they are equal, increment the answer otherwise continue for the next element.
Time Complexity: O((R-L)*log(R))
Efficient Approach: From example 2, we can observe that all the valid numbers have digits from 0 to 3 only. Therefore there are only 4 choices for each digit present in a number. Use recursion to calculate all the valid numbers till R and check whether it satisfies the given condition or not.
Follow the steps below to solve the problem:
Notice that all valid numbers have digits from [0,3].
Numbers between [4,9] when squared carries a carry over them.S(4)*S(4) = 16 and S(16) = 7, 16 != 7.S(5)*S(5) = 25 and S(25) = 7, 25 != 7.
S(4)*S(4) = 16 and S(16) = 7, 16 != 7.
S(5)*S(5) = 25 and S(25) = 7, 25 != 7.
So, generate all possible numbers up to the R.
For each generated number there are a total of possible 4 choices between [0,3].
Calculate each possible choice and check the condition for each of them.
Below is the implementation of the above approach: 
C++
Java
Python3
C#
Javascript
// C++ program for the above approach#include <bits/stdc++.h>using namespace std; // Function to check if the number is validbool check(int num){    // Sum of digits of num    int sm = 0;     // Squared number    int num2 = num * num;     while (num) {        sm += num % 10;        num /= 10;    }     // Sum of digits of (num * num)    int sm2 = 0;    while (num2) {        sm2 += num2 % 10;        num2 /= 10;    }    return ((sm * sm) == sm2);} // Function to convert a string to an integerint convert(string s){    int val = 0;    reverse(s.begin(), s.end());    int cur = 1;    for (int i = 0; i < s.size(); i++) {        val += (s[i] - '0') * cur;        cur *= 10;    }    return val;} // Function to generate all possible// strings of length lenvoid generate(string s, int len, set<int>& uniq){    // Desired string    if (s.size() == len) {         // Take only valid numbers        if (check(convert(s))) {            uniq.insert(convert(s));        }        return;    }     // Recurse for all possible digits    for (int i = 0; i <= 3; i++) {        generate(s + char(i + '0'), len, uniq);    }} // Function to calculate unique numbers// in range [L, R]int totalNumbers(int L, int R){    // Initialize a variable    // to store the answer    int ans = 0;     // Calculate the maximum    // possible length    int max_len = log10(R) + 1;     // Set to store distinct    // valid numbers    set<int> uniq;     for (int i = 1; i <= max_len; i++) {        // Generate all possible strings        // of length i        generate("", i, uniq);    }     // Iterate the set to get the count    // of valid numbers in the range [L,R]    for (auto x : uniq) {        if (x >= L && x <= R) {            ans++;        }    }    return ans;} // Driver Codeint main(){    int L = 22, R = 22;    cout << totalNumbers(L, R);}
// Java program for the above approachimport java.util.*; class GFG{ // Function to check if the number is validstatic boolean check(int num){       // Sum of digits of num    int sm = 0;     // Squared number    int num2 = num * num;     while (num > 0) {        sm += num % 10;        num /= 10;    }     // Sum of digits of (num * num)    int sm2 = 0;    while (num2>0) {        sm2 += num2 % 10;        num2 /= 10;    }    return ((sm * sm) == sm2);} // Function to convert a String to an integerstatic int convert(String s){    int val = 0;    s = reverse(s);    int cur = 1;    for (int i = 0; i < s.length(); i++) {        val += (s.charAt(i) - '0') * cur;        cur *= 10;    }    return val;} // Function to generate all possible// Strings of length lenstatic void generate(String s, int len, HashSet<Integer> uniq){    // Desired String    if (s.length() == len) {         // Take only valid numbers        if (check(convert(s))) {            uniq.add(convert(s));        }        return;    }     // Recurse for all possible digits    for (int i = 0; i <= 3; i++) {        generate(s + (char)(i + '0'), len, uniq);    }}static String reverse(String input) {    char[] a = input.toCharArray();    int l, r = a.length - 1;    for (l = 0; l < r; l++, r--) {        char temp = a[l];        a[l] = a[r];        a[r] = temp;    }    return String.valueOf(a);}   // Function to calculate unique numbers// in range [L, R]static int totalNumbers(int L, int R){       // Initialize a variable    // to store the answer    int ans = 0;     // Calculate the maximum    // possible length    int max_len = (int) (Math.log10(R) + 1);     // Set to store distinct    // valid numbers    HashSet<Integer> uniq = new HashSet<Integer>();     for (int i = 1; i <= max_len; i++) {        // Generate all possible Strings        // of length i        generate("", i, uniq);    }     // Iterate the set to get the count    // of valid numbers in the range [L,R]    for (int x : uniq) {        if (x >= L && x <= R) {            ans++;        }    }    return ans;} // Driver Codepublic static void main(String[] args){    int L = 22, R = 22;    System.out.print(totalNumbers(L, R));}} // This code is contributed by Princi Singh
# python 3 program for the above approach from math import log10# Function to check if the number is validdef check(num):    # Sum of digits of num    sm = 0     # Squared number    num2 = num * num     while (num):        sm += num % 10        num //= 10     # Sum of digits of (num * num)    sm2 = 0    while (num2):        sm2 += num2 % 10        num2 //= 10    return ((sm * sm) == sm2) # Function to convert a string to an integerdef convert(s):    val = 0    s = s[::-1]    cur = 1    for i in range(len(s)):        val += (ord(s[i]) - ord('0')) * cur        cur *= 10    return val # Function to generate all possible# strings of length lendef generate(s, len1, uniq):    # Desired string    if (len(s) == len1):         # Take only valid numbers        if(check(convert(s))):            uniq.add(convert(s))        return     # Recurse for all possible digits    for i in range(4):        generate(s + chr(i + ord('0')), len1, uniq) # Function to calculate unique numbers# in range [L, R]def totalNumbers(L, R):    # Initialize a variable    # to store the answer    ans = 0     # Calculate the maximum    # possible length    max_len = int(log10(R)) + 1     # Set to store distinct    # valid numbers    uniq = set()     for i in range(1,max_len+1,1):        # Generate all possible strings        # of length i        generate("", i, uniq)     # Iterate the set to get the count    # of valid numbers in the range [L,R]    for x in uniq:        if (x >= L and x <= R):            ans += 1    return ans # Driver Codeif __name__ == '__main__':    L = 22    R = 22    print(totalNumbers(L, R))         # This code is contributed by ipg2016107.
// C# program for the above approachusing System;using System.Collections.Generic; class GFG{ // Function to check if the number is validstatic bool check(int num){    // Sum of digits of num    int sm = 0;     // Squared number    int num2 = num * num;     while (num>0) {        sm += num % 10;        num /= 10;    }     // Sum of digits of (num * num)    int sm2 = 0;    while (num2>0) {        sm2 += num2 % 10;        num2 /= 10;    }    return ((sm * sm) == sm2);} // Function to convert a string to an integerstatic int convert(string s){    int val = 0;    char[] charArray = s.ToCharArray();    Array.Reverse( charArray );    s = new string( charArray );    int cur = 1;    for (int i = 0; i < s.Length; i++) {        val += ((int)s[i] - (int)'0') * cur;        cur *= 10;    }    return val;} // Function to generate all possible// strings of length lenstatic void generate(string s, int len, HashSet<int> uniq){    // Desired string    if (s.Length == len) {         // Take only valid numbers        if (check(convert(s))) {            uniq.Add(convert(s));        }        return;    }     // Recurse for all possible digits    for (int i = 0; i <= 3; i++) {        generate(s + Convert.ToChar(i + (int)'0'), len, uniq);    }} // Function to calculate unique numbers// in range [L, R]static int totalNumbers(int L, int R){    // Initialize a variable    // to store the answer    int ans = 0;     // Calculate the maximum    // possible length    int max_len = (int)Math.Log10(R) + 1;     // Set to store distinct    // valid numbers    HashSet<int> uniq = new HashSet<int>();     for (int i = 1; i <= max_len; i++) {        // Generate all possible strings        // of length i        generate("", i, uniq);    }     // Iterate the set to get the count    // of valid numbers in the range [L,R]    foreach (int x in uniq) {        if (x >= L && x <= R) {            ans++;        }    }    return ans;} // Driver Codepublic static void Main(){    int L = 22, R = 22;    Console.Write(totalNumbers(L, R));} } // This code is contributed by SURENDRA_GANGWAR.
<script>// Javascript program for the above approach // Function to check if the number is validfunction check(num){   // Sum of digits of num  let sm = 0;   // Squared number  let num2 = num * num;   while (num) {    sm += num % 10;    num = Math.floor(num / 10);  }   // Sum of digits of (num * num)  let sm2 = 0;  while (num2) {    sm2 += num2 % 10;    num2 = Math.floor(num2 / 10);  }  return sm * sm == sm2;} // Function to convert a string to an integerfunction convert(s) {  let val = 0;  s = s.split("").reverse().join("");  let cur = 1;   for (let i = 0; i < s.length; i++) {    val += (s[i].charCodeAt(0) - "0".charCodeAt(0)) * cur;    cur *= 10;  }  return val;} // Function to generate all possible// strings of length lenfunction generate(s, len, uniq) {  // Desired string  if (s.length == len) {    // Take only valid numbers    if (check(convert(s))) {      uniq.add(convert(s));    }    return;  }   // Recurse for all possible digits  for (let i = 0; i <= 3; i++) {    generate(s + String.fromCharCode(i + "0".charCodeAt(0)), len, uniq);  }} // Function to calculate unique numbers// in range [L, R]function totalNumbers(L, R) {  // Initialize a variable  // to store the answer  let ans = 0;   // Calculate the maximum  // possible length  let max_len = Math.log10(R) + 1;   // Set to store distinct  // valid numbers  let uniq = new Set();   for (let i = 1; i <= max_len; i++) {    // Generate all possible strings    // of length i    generate("", i, uniq);  }   // Iterate the set to get the count  // of valid numbers in the range [L,R]  for (let x of uniq) {    if (x >= L && x <= R) {      ans++;    }  }  return ans;} // Driver Codelet L = 22,  R = 22;document.write(totalNumbers(L, R)); // This code is contributed by _saurabh_jaiswal.</script>
Output:
1
Time Complexity: (, since there are 4 choices for each of the digits till the length of R i.e log10(R) + 1, therefore the time complexity would be exponential.
Auxiliary Space:   (Recursive Stack space)
 
ipg2016107
SURENDRA_GANGWAR
singghakshay
princi singh
_saurabh_jaiswal
simmytarika5
surinderdawra388
number-theory
Greedy
Mathematical
Strings
number-theory
Strings
Greedy
Mathematical
Writing code in comment?
Please use ide.geeksforgeeks.org,
generate link and share the link here.
Optimal Page Replacement Algorithm
Program for Best Fit algorithm in Memory Management
Program for First Fit algorithm in Memory Management
Bin Packing Problem (Minimize number of used Bins)
Max Flow Problem Introduction
Program for Fibonacci numbers
C++ Data Types
Set in C++ Standard Template Library (STL)
Merge two sorted arrays
Modulo Operator (%) in C/C++ with Examples