Given a number n, the task is to find out whether this number is a Smith number or not. A Smith number is a composite number whose sum of digits is equal to the sum of digits of its prime factorization.
Examples:
Input: n = 648
Output: true
Explanation: 648 = 23*34, 6+4+8 = 2+2+2+3+3+3+3.
and since 648 is a composite number, 648 is a Smith number.
Input: n = 762
Output: true
Explanation: 762 = 21*31*1271 is a Smith number since 7+6+2 = 2+3+(1+2+7).
and it is a composite number.
Table of Content
Using Prime Factorization - O(√n log n) Time O(1) Space
Compute the sum of digits of the number and compare it with the sum of digits of its prime factors (including multiplicity); if both are equal and the number is not prime, it is a Smith Number.
Algorithm:
- First, calculate the sum of digits of the given number.
- Then, find all its prime factors using trial division.
- Add the digit sum of each prime factor (including repetitions).
- If the number is prime, return 0.
- Finally, compare both sums; if equal return 1, otherwise return 0.
#include <iostream>
using namespace std;
// Function to calculate sum of digits of a number
int sumofdigit(int n)
{
int sum = 0;
// Extract digits and add them
while (n > 0)
{
sum += n % 10;
n /= 10;
}
return sum;
}
// Function to check whether a number is a Smith number
bool smithNum(int n)
{
int original = n;
// Calculate sum of digits of the number
int digitSum = sumofdigit(n);
int factorSum = 0;
// Find prime factors and add their digit sums
for (int i = 2; i * i <= n; i++)
{
while (n % i == 0)
{
factorSum += sumofdigit(i);
n /= i;
}
}
// If no factors found, number is prime → not a Smith number
if (n == original)
return false;
// If there is a remaining prime factor
if (n > 1)
{
factorSum += sumofdigit(n);
}
// Check if both sums are equal
return digitSum == factorSum;
}
// driver code
int main()
{
int n = 648;
if (smithNum(n))
cout << "true" << endl;
else
cout << "false" << endl;
return 0;
}
#include <stdio.h>
// Function to calculate sum of digits of a number
int sumofdigit(int n)
{
int sum = 0;
// Extract digits and add them
while (n > 0)
{
sum += n % 10;
n /= 10;
}
return sum;
}
// Function to check whether a number is a Smith number
int smithNum(int n)
{
int original = n;
// Calculate sum of digits of the number
int digitSum = sumofdigit(n);
int factorSum = 0;
// Find prime factors and add their digit sums
for (int i = 2; i * i <= n; i++)
{
while (n % i == 0)
{
factorSum += sumofdigit(i);
n /= i;
}
}
// If no factors found, number is prime → not a Smith number
if (n == original)
return 0;
// If there is a remaining prime factor
if (n > 1)
{
factorSum += sumofdigit(n);
}
// Check if both sums are equal
return digitSum == factorSum;
}
// driver code
int main()
{
int n = 648;
if (smithNum(n))
printf("true\n");
else
printf("false\n");
return 0;
}
public class GfG {
// Function to calculate sum of digits of a number
static int sumofdigit(int n)
{
int sum = 0;
// Extract digits and add them
while (n > 0)
{
sum += n % 10;
n /= 10;
}
return sum;
}
// Function to check whether a number is a Smith number
static boolean smithNum(int n)
{
int original = n;
// Calculate sum of digits of the number
int digitSum = sumofdigit(n);
int factorSum = 0;
// Find prime factors and add their digit sums
for (int i = 2; i * i <= n; i++)
{
while (n % i == 0)
{
factorSum += sumofdigit(i);
n /= i;
}
}
// If no factors found, number is prime → not a Smith number
if (n == original)
return false;
// If there is a remaining prime factor
if (n > 1)
{
factorSum += sumofdigit(n);
}
// Check if both sums are equal
return digitSum == factorSum;
}
// driver code
public static void main(String[] args)
{
int n = 648;
if (smithNum(n))
System.out.println("true");
else
System.out.println("false");
}
}
# Function to calculate sum of digits of a number
def sumofdigit(n):
sum = 0
# Extract digits and add them
while (n > 0):
sum += n % 10
n //= 10
return sum
# Function to check whether a number is a Smith number
def smithNum(n):
original = n
# Calculate sum of digits of the number
digitSum = sumofdigit(n)
factorSum = 0
# Find prime factors and add their digit sums
for i in range(2, int(n**0.5) + 1):
while (n % i == 0):
factorSum += sumofdigit(i)
n //= i
# If no factors found, number is prime → not a Smith number
if (n == original):
return False
# If there is a remaining prime factor
if (n > 1):
factorSum += sumofdigit(n)
# Check if both sums are equal
return digitSum == factorSum
# driver code
if __name__ == "__main__":
n = 648
# Check and print result
if smithNum(n):
print('true')
else:
print('false')
using System;
class GfG
{
// Function to calculate sum of digits of a number
static int sumofdigit(int n)
{
int sum = 0;
// Extract digits and add them
while (n > 0)
{
sum += n % 10;
n /= 10;
}
return sum;
}
// Function to check whether a number is a Smith number
static bool smithNum(int n)
{
int original = n;
// Calculate sum of digits of the number
int digitSum = sumofdigit(n);
int factorSum = 0;
// Find prime factors and add their digit sums
for (int i = 2; i * i <= n; i++)
{
while (n % i == 0)
{
factorSum += sumofdigit(i);
n /= i;
}
}
// If no factors found, number is prime → not a Smith number
if (n == original)
return false;
// If there is a remaining prime factor
if (n > 1)
{
factorSum += sumofdigit(n);
}
// Check if both sums are equal
return digitSum == factorSum;
}
// driver code
static void Main()
{
int n = 648;
if (smithNum(n))
Console.WriteLine("true");
else
Console.WriteLine("false");
}
}
function sumofdigit(n) {
let sum = 0;
// Extract digits and add them
while (n > 0) {
sum += n % 10;
n = Math.floor(n / 10);
}
return sum;
}
function smithNum(n) {
let original = n;
// Calculate sum of digits of the number
let digitSum = sumofdigit(n);
let factorSum = 0;
// Find prime factors and add their digit sums
for (let i = 2; i * i <= n; i++) {
while (n % i === 0) {
factorSum += sumofdigit(i);
n = Math.floor(n / i);
}
}
// If no factors found, number is prime → not a Smith number
if (n === original) {
return false;
}
// If there is a remaining prime factor
if (n > 1) {
factorSum += sumofdigit(n);
}
// Check if both sums are equal
return digitSum === factorSum;
}
// driver code
let n = 648;
if (smithNum(n)) {
console.log('true');
} else {
console.log('false');
}
Output
true
Time Complexity:O(√n log n), √n for factorization and log n for digit sum operations
Auxiliary Space:O(1)
Efficient Approach for Multiple Queries using Sieve - O(n log log n) Time O(n) Space
The idea is to compare the sum of digits of the number with the sum of digits of its prime factors. We first compute the Least Prime Factor (LPF) using a sieve to enable fast factorization. Then, we find the digit sum of the number and its prime factors (using LPF). If both sums are equal, the number is a Smith Number; otherwise, it is not.
Why this works efficiently:
This approach is efficient because the Least Prime Factor (LPF) array is precomputed once using a sieve in O(n log log n) time, which allows fast reuse for multiple queries. Using LPF, prime factorization of any number is reduced to O(log n) time by repeatedly dividing by the smallest prime factor. It also eliminates repeated prime checks, since all smallest prime factors are already stored. Additionally, computing the digit sum is a lightweight operation, adding only O(log n) overhead, making the overall process fast and scalable.
#include <iostream>
#include <vector>
using namespace std;
vector<int> leastPrimeFactor(int n)
{
// To store least prime factors
vector<int> lpf(n + 1);
for (int i = 0; i <= n; i++)
lpf[i] = i;
// Compute Least Prime Factor for all
for (int i = 2; i * i <= n; i++)
{
// If not computed already, then i is prime
if (lpf[i] == i)
{
for (int j = i * i; j <= n; j += i)
{
if (lpf[j] == j)
lpf[j] = i;
}
}
}
return lpf;
}
int digitSum(int x)
{
int sum = 0;
while (x > 0)
{
sum += x % 10;
x /= 10;
}
return sum;
}
bool smithNum(int n)
{
vector<int> lpf = leastPrimeFactor(n);
if (lpf[n] == n)
return false;
int originalSum = digitSum(n);
int factorSum = 0;
int temp = n;
while (temp > 1)
{
int p = lpf[temp];
while (temp % p == 0)
{
factorSum += digitSum(p);
temp /= p;
}
}
return originalSum == factorSum;
}
int main()
{
int n = 648;
if (smithNum(n))
cout << "true" << endl;
else
cout << "false" << endl;
return 0;
}
import java.util.*;
class GfG {
static int[] leastPrimeFactor(int n) {
// To store least prime factors
int[] lpf = new int[n + 1];
for (int i = 0; i <= n; i++)
lpf[i] = i;
// Compute Least Prime Factor for all
for (int i = 2; i * i <= n; i++) {
// If not computed already, then i is prime
if (lpf[i] == i) {
for (int j = i * i; j <= n; j += i) {
if (lpf[j] == j)
lpf[j] = i;
}
}
}
return lpf;
}
static int digitSum(int x) {
int sum = 0;
while (x > 0) {
sum += x % 10;
x /= 10;
}
return sum;
}
static boolean smithNum(int n) {
int[] lpf = leastPrimeFactor(n);
if (lpf[n] == n)
return false;
int originalSum = digitSum(n);
int factorSum = 0;
int temp = n;
while (temp > 1) {
int p = lpf[temp];
while (temp % p == 0) {
factorSum += digitSum(p);
temp /= p;
}
}
return originalSum == factorSum;
}
public static void main(String[] args) {
int n = 648;
if (smithNum(n))
System.out.println("true");
else
System.out.println("false");
}
}
def leastPrimeFactor(n):
# To store least prime factors
lpf = [i for i in range(n + 1)]
# Compute Least Prime Factor for all
i = 2
while i * i <= n:
# If not computed already, then i is prime
if lpf[i] == i:
j = i * i
while j <= n:
if lpf[j] == j:
lpf[j] = i
j += i
i += 1
return lpf
def digitSum(x):
s = 0
while x > 0:
s += x % 10
x //= 10
return s
def smithNum(n):
lpf = leastPrimeFactor(n)
if lpf[n] == n:
return False
originalSum = digitSum(n)
factorSum = 0
temp = n
while temp > 1:
p = lpf[temp]
while temp % p == 0:
factorSum += digitSum(p)
temp //= p
return originalSum == factorSum
n = 648
if smithNum(n):
print("true")
else:
print("false")
using System;
class GfG {
static int[] leastPrimeFactor(int n) {
// To store least prime factors
int[] lpf = new int[n + 1];
for (int i = 0; i <= n; i++)
lpf[i] = i;
// Compute Least Prime Factor for all
for (int i = 2; i * i <= n; i++) {
// If not computed already, then i is prime
if (lpf[i] == i) {
for (int j = i * i; j <= n; j += i) {
if (lpf[j] == j)
lpf[j] = i;
}
}
}
return lpf;
}
static int digitSum(int x) {
int sum = 0;
while (x > 0) {
sum += x % 10;
x /= 10;
}
return sum;
}
static bool smithNum(int n) {
int[] lpf = leastPrimeFactor(n);
if (lpf[n] == n)
return false;
int originalSum = digitSum(n);
int factorSum = 0;
int temp = n;
while (temp > 1) {
int p = lpf[temp];
while (temp % p == 0) {
factorSum += digitSum(p);
temp /= p;
}
}
return originalSum == factorSum;
}
static void Main() {
int n = 648;
if (smithNum(n))
Console.WriteLine("true");
else
Console.WriteLine("false");
}
}
function leastPrimeFactor(n) {
// To store least prime factors
let lpf = Array.from(
{ length: n + 1 }, (_, i) => i
);
// Compute Least Prime Factor for all
for (let i = 2; i * i <= n; i++) {
// If not computed already, then i is prime
if (lpf[i] === i) {
for (let j = i * i; j <= n; j += i) {
if (lpf[j] === j)
lpf[j] = i;
}
}
}
return lpf;
}
function digitSum(x) {
let sum = 0;
while (x > 0) {
sum += x % 10;
x = Math.floor(x / 10);
}
return sum;
}
function smithNum(n) {
let lpf = leastPrimeFactor(n);
if (lpf[n] === n)
return false;
let originalSum = digitSum(n);
let factorSum = 0;
let temp = n;
while (temp > 1) {
let p = lpf[temp];
while (temp % p === 0) {
factorSum += digitSum(p);
temp = Math.floor(temp / p);
}
}
return originalSum === factorSum;
}
let n = 648;
if (smithNum(n))
console.log("true");
else
console.log("false");
Output
true
Time Complexity: O(n log logn)
Space Complexity: O(n)