Count of integer whose factorial of digit sum contains every digit of original number
Last Updated :
31 Aug, 2023
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;
int getSum( int n)
{
int sum = 0;
while (n != 0) {
sum = sum + n % 10;
n = n / 10;
}
return sum;
}
int functionTOFindInt( int arr[], int n)
{
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;
}
}
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 };
cout << functionTOFindInt(arr, n) << endl;
return 0;
}
|
Java
import java.util.*;
class GFG {
public static void main(String[] args)
{
int n = 7 ;
int [] arr
= { 833 , 3055 , 8521 , 360 , 2202 , 310 , 2111 };
System.out.println(functionTOFindInt(arr, n));
}
public static int funtionTOFindInt( int [] arr, int n)
{
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 ;
}
}
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;
}
public static int factorial( int n)
{
return (n == 1 || n == 0 ) ? 1
: n * factorial(n - 1 );
}
public static int getSum( int n)
{
int sum = 0 ;
while (n != 0 ) {
sum = sum + n % 10 ;
n = n / 10 ;
}
return sum;
}
}
|
Python3
def getSum(n):
sum = 0
while n ! = 0 :
sum + = n % 10
n / / = 10
return sum
def functionTOFindInt(arr, n):
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 = 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 ]
print (funtionTOFindInt(arr, n))
|
C#
using System;
using System.Collections.Generic;
public class GFG {
static public void Main()
{
int n = 7;
int [] arr
= { 833, 3055, 8521, 360, 2202, 310, 2111 };
Console.WriteLine(functionTOFindInt(arr, n));
}
static int funtionTOFindInt( int [] arr, int n)
{
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;
}
}
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;
}
static int factorial( int n)
{
return (n == 1 || n == 0) ? 1
: n * factorial(n - 1);
}
static int getSum( int n)
{
int sum = 0;
while (n != 0) {
sum = sum + n % 10;
n = n / 10;
}
return sum;
}
}
|
Javascript
function getSum(n) {
let sum = 0;
while (n !== 0) {
sum += n % 10;
n = Math.floor(n / 10);
}
return sum;
}
function functionToFindInt(arr, n) {
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);
}
}
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;
}
let n = 7;
let arr = [833, 3055, 8521, 360, 2202, 310, 2111];
console.log(functionToFindInt(arr, n));
|
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;
int functionTOFindInt( int arr[], int n)
{
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;
}
}
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 };
cout << functionTOFindInt(arr, n) << endl;
return 0;
}
|
Java
import java.util.HashSet;
public class GFG {
static int functionTOFindInt( int [] arr, int n)
{
HashSet<Integer>[] factDigits = new HashSet[ 10 ];
for ( int i = 1 ; i < 10 ; i++) {
int fact = 1 ;
for ( int j = 2 ; j <= i; j++) {
fact *= j;
}
factDigits[i] = new HashSet<>();
while (fact != 0 ) {
factDigits[i].add(fact % 10 );
fact /= 10 ;
}
}
int count = 0 ;
for ( int i = 0 ; i < n; i++) {
int x = arr[i] % 9 ;
HashSet<Integer> digits;
if (x == 0 ) {
digits = factDigits[ 9 ];
}
else {
digits = factDigits[x];
}
boolean flag = true ;
int num = arr[i];
while (num > 0 ) {
int dig = num % 10 ;
if (!digits.contains(dig)) {
flag = false ;
break ;
}
num /= 10 ;
}
if (flag) {
count++;
}
}
return count;
}
public static void main(String[] args)
{
int n = 7 ;
int [] arr
= { 833 , 3055 , 8521 , 360 , 2202 , 310 , 2111 };
System.out.println(functionTOFindInt(arr, n));
}
}
|
Python3
def functionTOFindInt(arr, n):
factDigits = {}
for i in range ( 1 , 10 ):
fact = 1
for j in range ( 2 , i + 1 ):
fact * = j
digits = set ()
while fact ! = 0 :
digits.add(fact % 10 )
fact / / = 10
factDigits[i] = digits
count = 0
for i in range (n):
x = arr[i] % 9
if x = = 0 :
digits = factDigits[ 9 ]
else :
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 ]
print (functionTOFindInt(arr, n))
|
C#
using System;
using System.Collections.Generic;
class GFG
{
static int FunctionTOFindInt( int [] arr, int n)
{
Dictionary< int , HashSet< int >> factDigits = new Dictionary< int , HashSet< int >>();
for ( int i = 1; i < 10; i++)
{
int fact = 1;
for ( int j = 2; j <= i; j++)
{
fact *= j;
}
HashSet< int > digits = new HashSet< int >();
while (fact != 0)
{
digits.Add(fact % 10);
fact /= 10;
}
factDigits[i] = digits;
}
int count = 0;
for ( int i = 0; i < n; i++)
{
int x = arr[i] % 9;
HashSet< int > digits = (x == 0) ? factDigits[9] : factDigits[x];
bool flag = true ;
int num = arr[i];
while (num > 0)
{
int dig = num % 10;
if (!digits.Contains(dig))
{
flag = false ;
break ;
}
num /= 10;
}
if (flag)
{
count++;
}
}
return count;
}
static void Main( string [] args)
{
int n = 7;
int [] arr = { 833, 3055, 8521, 360, 2202, 310, 2111 };
Console.WriteLine(FunctionTOFindInt(arr, n));
}
}
|
Javascript
function functionTOFindInt(arr) {
let n = arr.length;
let factDigits = Array(10).fill().map(() => new Set());
for (let i = 1; i < 10; i++) {
let fact = 1;
for (let j = 2; j <= i; j++) {
fact *= j;
}
while (fact !== 0) {
factDigits[i].add(fact % 10);
fact = Math.floor(fact / 10);
}
}
let count = 0;
for (let i = 0; i < n; i++) {
let x = arr[i] % 9;
let digits;
if (x === 0) {
digits = factDigits[9];
} else {
digits = factDigits[x];
}
let flag = true ;
let num = arr[i];
while (num > 0) {
let dig = num % 10;
if (!digits.has(dig)) {
flag = false ;
break ;
}
num = Math.floor(num / 10);
}
if (flag) {
count++;
}
}
return count;
}
let arr = [833, 3055, 8521, 360, 2202, 310, 2111];
console.log(functionTOFindInt(arr));
|
Time Complexity: O(n * log(n))
Auxiliary Space: 0(1)
Like Article
Suggest improvement
Share your thoughts in the comments
Please Login to comment...