Count of integer whose factorial of digit sum contains every digit of original number
Given an array arr[] of length n which contains positive integers (0 ≤ arr[i] ≤ 109), the task is to count the number of elements present in the given array such that the factorial of their digit sum (we will do digit sum while its value is greater than 10) contains every digit present in the original integer.
Examples:
Input: arr[] = [653, 663, 242, 7170, 30006]
Output: 2
Explanation:
- For 653 digits are: (3, 5, 6), digit sum: 6 + 5 + 3 = 14(as 14 ≥ 10) -> 1 + 4 = 5 and 5! = 120, so digits are: (0, 1, 2), it doesn’t contain 3, 5 and 6 so it is not an integer we need to count.
- For 663 digits are: (3, 6), digit sum: 6 + 6 + 3 = 15(as 15 ≥ 10) -> 1 + 5 = 6 and 6! = 720, so digits are: (0, 2, 7), it doesn’t contain 3 and 6 so it is not an integer we need to count.
- For 242 digits are: (2, 4), digit sum: 2 + 4 + 2 = 8 and 8! = 40320, so digits are: (0, 2, 3, 4), which contains both 2 and 4 so it is an integer we need to count.
- For 7170 digits are: (0, 1, 7), digit sum: 7 + 1 + 7 + 0 = 15(as 15 ≥ 10) -> 1 + 5 = 6 and 6! = 720, so digits are: (0, 2, 7), it doesn’t contain 1 so it is not an integer we need to count.
- For 30006 digits are: (0, 3, 6), digit sum: 3 + 0 + 0 + 0 + 6 = 9 and 9! = 362880, so digits are: (0, 2, 3, 6, 8), which contains every digit of 30006, so it is an integer we need to count.
Therefore, the required integers in the given array are 242 and 30006.
Input: arr[] = [833, 3055, 8521, 360, 2202, 310, 2111]
Output: 3
Approach 1: Implement the idea below to solve the problem:
The problem is based on Bitwise concept and can be solved by using some observations. For more clarification see the Concept of approach section.
Steps were taken to solve the problem:
- Firstly, calculate factorials of integers from 1 to 9 as the digit sum will be in the range of [1, 9]. Similarly, store digits are present in factorials.
- After that, find the digit sum of arr[i] while it is greater than or equal to 10.
- Now, after calculating its digit sum, then find the factorial.
- At last, check if every digit of arr[i] is present in that factorial or not.
- Update the count variable if every digit of arr[[i] is present in that factorial value.
Implementation of the above approach:
“
C++
#include <iostream> #include <unordered_set> using namespace std; // Find the digit sum int getSum( int n) { int sum = 0; while (n != 0) { sum = sum + n % 10; n = n / 10; } return sum; } // Function to find number of elements int functionTOFindInt( int arr[], int n) { // Factorial of the digits from 0 to 9 unordered_set< int > factDigits[10]; for ( int i = 1; i < 10; i++) { int fact = 1; for ( int j = 2; j <= i; j++) { fact *= j; } while (fact != 0) { factDigits[i].insert(fact % 10); fact /= 10; } } // Count integers int count = 0; for ( int i = 0; i < n; i++) { int x = arr[i]; while (x >= 10) { x = getSum(x); } unordered_set< int > digits = factDigits[x]; bool flag = true ; while (arr[i] > 0) { int dig = arr[i] % 10; if (digits.find(dig) == digits.end()) { flag = false ; break ; } arr[i] /= 10; } if (flag) { count++; } } return count; } int main() { int n = 7; int arr[] = { 833, 3055, 8521, 360, 2202, 310, 2111 }; // Function Call cout << functionTOFindInt(arr, n) << endl; return 0; } |
Java
// Java algorithm for the above approach import java.util.*; class GFG { // Driver Code public static void main(String[] args) { int n = 7 ; int [] arr = { 833 , 3055 , 8521 , 360 , 2202 , 310 , 2111 }; // Function Call System.out.println(functionTOFindInt(arr, n)); } // Function to find number of elements public static int funtionTOFindInt( int [] arr, int n) { // Factorial of the digits from // 0 to 9 Set<Integer>[] factDigits = new HashSet[ 10 ]; for ( int i = 1 ; i < 10 ; i++) { int fact = factorial(i); factDigits[i] = new HashSet<>(); while (fact != 0 ) { factDigits[i].add(fact % 10 ); fact /= 10 ; } } // Count integers int count = 0 ; for ( int i = 0 ; i < n; i++) { int x = arr[i]; while (x >= 10 ) { x = getSum(x); } Set<Integer> digits = factDigits[x]; boolean flag = true ; while (arr[i] > 0 ) { int dig = arr[i] % 10 ; if (!digits.contains(dig)) { flag = false ; break ; } arr[i] /= 10 ; } if (flag) count++; } return count; } // Find the factorial of the number public static int factorial( int n) { return (n == 1 || n == 0 ) ? 1 : n * factorial(n - 1 ); } // Find the digit sum public static int getSum( int n) { int sum = 0 ; while (n != 0 ) { sum = sum + n % 10 ; n = n / 10 ; } // Return the sum return sum; } } |
Python3
# Find the digit sum def getSum(n): sum = 0 while n ! = 0 : sum + = n % 10 n / / = 10 return sum # Function to find number of elements def functionTOFindInt(arr, n): # Factorial of the digits from 0 to 9 factDigits = [ set () for i in range ( 10 )] for i in range ( 1 , 10 ): fact = 1 for j in range ( 2 , i + 1 ): fact * = j while fact ! = 0 : factDigits[i].add(fact % 10 ) fact / / = 10 # Count integers count = 0 for i in range (n): x = arr[i] while x > = 10 : x = getSum(x) digits = factDigits[x] flag = True while arr[i] > 0 : dig = arr[i] % 10 if dig not in digits: flag = False break arr[i] / / = 10 if flag: count + = 1 return count if __name__ = = "__main__" : n = 7 arr = [ 833 , 3055 , 8521 , 360 , 2202 , 310 , 2111 ] # Function Call print (funtionTOFindInt(arr, n)) # This code is contributed by Prajwal Kandekar |
C#
// C# algorithm for the above approach using System; using System.Collections.Generic; public class GFG { static public void Main() { // Code int n = 7; int [] arr = { 833, 3055, 8521, 360, 2202, 310, 2111 }; // Function Call Console.WriteLine(functionTOFindInt(arr, n)); } // Function to find number of elements static int funtionTOFindInt( int [] arr, int n) { // Factorial of the digits from // 0 to 9 HashSet< int >[] factDigits = new HashSet< int >[ 10 ]; for ( int i = 1; i < 10; i++) { int fact = factorial(i); factDigits[i] = new HashSet< int >(); while (fact != 0) { factDigits[i].Add(fact % 10); fact /= 10; } } // Count integers int count = 0; for ( int i = 0; i < n; i++) { int x = arr[i]; while (x >= 10) { x = getSum(x); } HashSet< int > digits = factDigits[x]; bool flag = true ; while (arr[i] > 0) { int dig = arr[i] % 10; if (!digits.Contains(dig)) { flag = false ; break ; } arr[i] /= 10; } if (flag) count++; } return count; } // Find the factorial of the number static int factorial( int n) { return (n == 1 || n == 0) ? 1 : n * factorial(n - 1); } // Find the digit sum static int getSum( int n) { int sum = 0; while (n != 0) { sum = sum + n % 10; n = n / 10; } // Return the sum return sum; } } // This code is contributed by karthik. |
Javascript
// Find the digit sum function getSum(n) { let sum = 0; while (n !== 0) { sum += n % 10; n = Math.floor(n / 10); } return sum; } // Function to find number of elements function functionToFindInt(arr, n) { // Factorial of the digits from 0 to 9 let factDigits = []; for (let i = 1; i < 10; i++) { let fact = 1; for (let j = 2; j <= i; j++) { fact *= j; } while (fact !== 0) { factDigits[i] = factDigits[i] || new Set(); factDigits[i].add(fact % 10); fact = Math.floor(fact / 10); } } // Count integers let count = 0; for (let i = 0; i < n; i++) { let x = arr[i]; while (x >= 10) { x = getSum(x); } let digits = factDigits[x] || new Set(); let flag = true ; while (arr[i] > 0) { let dig = arr[i] % 10; if (!digits.has(dig)) { flag = false ; break ; } arr[i] = Math.floor(arr[i] / 10); } if (flag) { count++; } } return count; } // Driver code let n = 7; let arr = [833, 3055, 8521, 360, 2202, 310, 2111]; // Function call console.log(functionToFindInt(arr, n)); |
3
Time Complexity: O(n * (log(n))^2)
Auxiliary Space: 0(1)
Approach 2: Optimised approach
We can optimize the above function getSum to O(1). We need not add these digits again and again. Just find the remainder of the given number when divided by 9.
Input: arr[] = [653, 663, 242, 7170, 30006]
Output: 2
Explanation:For 653 digits are: 653%9 = 5 and 5! = 120, so digits are: (0, 1, 2), it doesn’t contain 3, 5 and 6 so it is not an integer we need to count.
For 663 digits are: 663%3 = 6 and 6! = 720, so digits are: (0, 2, 7), it doesn’t contain 3 and 6 so it is not an integer we need to count.
For 242 digits are: 242%9=8 and 8! = 40320, so digits are: (0, 2, 3, 4), which contains both 2 and 4 so it is an integer we need to count.
For 7170 digits are: 7170%9=6 and 6! = 720, so digits are: (0, 2, 7), it doesn’t contain 1 so it is not an integer we need to count.
For 30006 digits are: 30006%9 = 0 so we can take it as 9 and 9! = 362880, so digits are: (0, 2, 3, 6, 8), which contains every digit of 30006, so it is an integer we need to count.Therefore, the required integers in the given array are 242 and 30006.
And remaining steps are the same.
C++
#include <iostream> #include <unordered_set> using namespace std; // Function to find number of elements int functionTOFindInt( int arr[], int n) { // Factorial of the digits from 0 to 9 unordered_set< int > factDigits[10]; for ( int i = 1; i < 10; i++) { int fact = 1; for ( int j = 2; j <= i; j++) { fact *= j; } while (fact != 0) { factDigits[i].insert(fact % 10); fact /= 10; } } // Count integers int count = 0; for ( int i = 0; i < n; i++) { int x = arr[i]%9; unordered_set< int > digits; if (x==0) digits = factDigits[9]; else digits = factDigits[x]; bool flag = true ; while (arr[i] > 0) { int dig = arr[i] % 10; if (digits.find(dig) == digits.end()) { flag = false ; break ; } arr[i] /= 10; } if (flag) { count++; } } return count; } int main() { int n = 7; int arr[] = { 833, 3055, 8521, 360, 2202, 310, 2111 }; // Function Call cout << functionTOFindInt(arr, n) << endl; return 0; } |
3
Time Complexity: O(n * log(n))
Auxiliary Space: 0(1)
Please Login to comment...