Smith Number

23 Jun, 2022
Given a number n, the task is to find out whether this number is smith or not. A Smith Number is a composite number whose sum of digits is equal to the sum of digits in its prime factorization. Examples:
Input  : n = 4
Output : Yes
Prime factorization = 2, 2  and 2 + 2 = 4
Therefore, 4 is a smith number

Input  : n = 6
Output : No
Prime factorization = 2, 3  and 2 + 3 is
not 6. Therefore, 6 is not a smith number

Input   : n = 666
Output  : Yes
Prime factorization = 2, 3, 3, 37 and
2 + 3 + 3 + (3 + 7) = 6 + 6 + 6 = 18
Therefore, 666 is a smith number

Input   : n = 13
Output  : No
Prime factorization = 13 and 13 = 13,
But 13 is not a smith number as it is not
a composite number
The idea is first find all prime numbers below a limit using Sieve of Sundaram (This is especially useful when we want to check multiple numbers for Smith). Now for every input to be checked for Smith, we go through all prime factors of it and find sum of digits of every prime factor. We also find sum of digits in given number. Finally we compare two sums. If they are same, we return true. 
C++
Java
Python
C#
PHP
Javascript
// C++ program to check whether a number is// Smith Number or not.#include<bits/stdc++.h>using namespace std;const int MAX  = 10000; // array to store all prime less than and equal to 10^6vector <int> primes; // utility function for sieve of sundaramvoid sieveSundaram(){    // In general Sieve of Sundaram, produces primes smaller    // than (2*x + 2) for a number given number x. Since    // we want primes smaller than MAX, we reduce MAX to half    // This array is used to separate numbers of the form    // i+j+2ij from others where 1 <= i <= j    bool marked[MAX/2 + 100] = {0};     // Main logic of Sundaram. Mark all numbers which    // do not generate prime number by doing 2*i+1    for (int i=1; i<=(sqrt(MAX)-1)/2; i++)        for (int j=(i*(i+1))<<1; j<=MAX/2; j=j+2*i+1)            marked[j] = true;     // Since 2 is a prime number    primes.push_back(2);     // Print other primes. Remaining primes are of the    // form 2*i + 1 such that marked[i] is false.    for (int i=1; i<=MAX/2; i++)        if (marked[i] == false)            primes.push_back(2*i + 1);} // Returns true if n is a Smith number, else false.bool isSmith(int n){    int original_no = n;     // Find sum the digits of prime factors of n    int pDigitSum = 0;    for (int i = 0; primes[i] <= n/2; i++)    {        while (n % primes[i] == 0)        {            // If primes[i] is a prime factor,            // add its digits to pDigitSum.            int p = primes[i];            n = n/p;            while (p > 0)            {                pDigitSum += (p % 10);                p = p/10;            }        }    }     // If n!=1 then one prime factor still to be    // summed up;    if (n != 1 && n != original_no)    {        while (n > 0)        {            pDigitSum = pDigitSum + n%10;            n = n/10;        }    }     // All prime factors digits summed up    // Now sum the original number digits    int sumDigits = 0;    while (original_no > 0)    {        sumDigits = sumDigits + original_no % 10;        original_no = original_no/10;    }     // If sum of digits in prime factors and sum    // of digits in original number are same, then    // return true. Else return false.    return (pDigitSum == sumDigits);} // Driver codeint main(){   // Finding all prime numbers before limit. These   // numbers are used to find prime factors.   sieveSundaram();    cout << "Printing first few Smith Numbers"           " using isSmith()n";   for (int i=1; i<500; i++)      if (isSmith(i))          cout << i << " ";    return 0;}
// Java program to check whether a number is// Smith Number or not. import java.util.Vector; class Test{         static int MAX  = 10000;          // array to store all prime less than and equal to 10^6    static Vector <Integer>  primes = new Vector<>();         // utility function for sieve of sundaram    static void sieveSundaram()    {        // In general Sieve of Sundaram, produces primes smaller        // than (2*x + 2) for a number given number x. Since        // we want primes smaller than MAX, we reduce MAX to half        // This array is used to separate numbers of the form        // i+j+2ij from others where 1 <= i <= j        boolean marked[] = new boolean[MAX/2 + 100];              // Main logic of Sundaram. Mark all numbers which        // do not generate prime number by doing 2*i+1        for (int i=1; i<=(Math.sqrt(MAX)-1)/2; i++)            for (int j=(i*(i+1))<<1; j<=MAX/2; j=j+2*i+1)                marked[j] = true;              // Since 2 is a prime number        primes.addElement(2);              // Print other primes. Remaining primes are of the        // form 2*i + 1 such that marked[i] is false.        for (int i=1; i<=MAX/2; i++)            if (marked[i] == false)                primes.addElement(2*i + 1);    }          // Returns true if n is a Smith number, else false.    static boolean isSmith(int n)    {        int original_no = n;              // Find sum the digits of prime factors of n        int pDigitSum = 0;        for (int i = 0; primes.get(i) <= n/2; i++)        {            while (n % primes.get(i) == 0)            {                // If primes[i] is a prime factor,                // add its digits to pDigitSum.                int p = primes.get(i);                n = n/p;                while (p > 0)                {                    pDigitSum += (p % 10);                    p = p/10;                }            }        }              // If n!=1 then one prime factor still to be        // summed up;        if (n != 1 && n != original_no)        {            while (n > 0)            {                pDigitSum = pDigitSum + n%10;                n = n/10;            }        }              // All prime factors digits summed up        // Now sum the original number digits        int sumDigits = 0;        while (original_no > 0)        {            sumDigits = sumDigits + original_no % 10;            original_no = original_no/10;        }              // If sum of digits in prime factors and sum        // of digits in original number are same, then        // return true. Else return false.        return (pDigitSum == sumDigits);    }         // Driver method    public static void main(String[] args)    {        // Finding all prime numbers before limit. These        // numbers are used to find prime factors.        sieveSundaram();                  System.out.println("Printing first few Smith Numbers" +                           " using isSmith()");                 for (int i=1; i<500; i++)           if (isSmith(i))              System.out.print(i + " ");    }}
# Python program to check whether a number is# Smith Number or not. import math MAX  = 10000 # array to store all prime less than and equal to 10^6primes = [] # utility function for sieve of sundaramdef sieveSundaram ():    #In general Sieve of Sundaram, produces primes smaller    # than (2*x + 2) for a number given number x. Since    # we want primes smaller than MAX, we reduce MAX to half    # This array is used to separate numbers of the form    # i+j+2ij from others where 1 <= i <= j    marked  = [0] * ((MAX/2)+100)    # Main logic of Sundaram. Mark all numbers which    # do not generate prime number by doing 2*i+1    i = 1    while i <= ((math.sqrt (MAX)-1)/2) :        j = (i* (i+1)) << 1        while j <= MAX/2 :            marked[j] = 1            j = j+ 2 * i + 1        i = i + 1    # Since 2 is a prime number    primes.append (2)         # Print other primes. Remaining primes are of the    # form 2*i + 1 such that marked[i] is false.    i=1    while i <= MAX /2 :        if marked[i] == 0 :            primes.append( 2* i + 1)        i=i+1 #Returns true if n is a Smith number, else false.def isSmith( n) :    original_no = n         #Find sum the digits of prime factors of n    pDigitSum = 0;    i=0    while (primes[i] <= n/2 ) :                 while n % primes[i] == 0 :            #If primes[i] is a prime factor ,            # add its digits to pDigitSum.            p = primes[i]            n = n/p            while p > 0 :                pDigitSum += (p % 10)                p = p/10        i=i+1    # If n!=1 then one prime factor still to be    # summed up    if not n == 1 and not n == original_no :        while n > 0 :            pDigitSum = pDigitSum + n%10            n=n/10           # All prime factors digits summed up    # Now sum the original number digits    sumDigits = 0    while original_no > 0 :        sumDigits = sumDigits + original_no % 10        original_no = original_no/10             #If sum of digits in prime factors and sum    # of digits in original number are same, then    # return true. Else return false.    return pDigitSum == sumDigits#-----end of function isSmith------ #Driver method# Finding all prime numbers before limit. These# numbers are used to find prime factors.sieveSundaram();print "Printing first few Smith Numbers using isSmith()"i = 1while i<500 :    if isSmith(i) :        print i,    i=i+1     #This code is contributed by Nikita Tiwari
// C# program to check whether a number is// Smith Number or not.using System;using System.Collections; class Test{         static int MAX = 10000;         // array to store all prime less than and equal to 10^6    static ArrayList primes = new ArrayList(10);         // utility function for sieve of sundaram    static void sieveSundaram()    {        // In general Sieve of Sundaram, produces primes smaller        // than (2*x + 2) for a number given number x. Since        // we want primes smaller than MAX, we reduce MAX to half        // This array is used to separate numbers of the form        // i+j+2ij from others where 1 <= i <= j        bool[] marked = new bool[MAX/2 + 100];             // Main logic of Sundaram. Mark all numbers which        // do not generate prime number by doing 2*i+1        for (int i=1; i<=(Math.Sqrt(MAX)-1)/2; i++)            for (int j=(i*(i+1))<<1; j<=MAX/2; j=j+2*i+1)                marked[j] = true;             // Since 2 is a prime number        primes.Add(2);             // Print other primes. Remaining primes are of the        // form 2*i + 1 such that marked[i] is false.        for (int i=1; i<=MAX/2; i++)            if (marked[i] == false)                primes.Add(2*i + 1);    }         // Returns true if n is a Smith number, else false.    static bool isSmith(int n)    {        int original_no = n;             // Find sum the digits of prime factors of n        int pDigitSum = 0;        for (int i = 0; (int)primes[i] <= n/2; i++)        {            while (n % (int)primes[i] == 0)            {                // If primes[i] is a prime factor,                // add its digits to pDigitSum.                int p = (int)primes[i];                n = n/p;                while (p > 0)                {                    pDigitSum += (p % 10);                    p = p/10;                }            }        }             // If n!=1 then one prime factor still to be        // summed up;        if (n != 1 && n != original_no)        {            while (n > 0)            {                pDigitSum = pDigitSum + n%10;                n = n/10;            }        }             // All prime factors digits summed up        // Now sum the original number digits        int sumDigits = 0;        while (original_no > 0)        {            sumDigits = sumDigits + original_no % 10;            original_no = original_no/10;        }             // If sum of digits in prime factors and sum        // of digits in original number are same, then        // return true. Else return false.        return (pDigitSum == sumDigits);    }         // Driver method    public static void Main()    {        // Finding all prime numbers before limit. These        // numbers are used to find prime factors.        sieveSundaram();                 Console.WriteLine("Printing first few Smith Numbers" +                        " using isSmith()");                 for (int i=1; i<500; i++)        if (isSmith(i))            Console.Write(i + " ");    }}// This Code is contributed by mits
<?php// PHP program to check whether a// number is Smith Number or not.$MAX = 10000; // array to store all prime less// than and equal to 10^6$primes = array(); // utility function for sieve of sundaramfunction sieveSundaram(){    global $MAX, $primes;         // In general Sieve of Sundaram, produces    // primes smaller than (2*x + 2) for a    // number given number x. Since we want    // primes smaller than MAX, we reduce MAX    // to half. This array is used to separate    // numbers of the form i+j+2ij from others    // where 1 <= i <= j    $marked = array_fill(0, ($MAX / 2 + 100), false);     // Main logic of Sundaram. Mark all numbers which    // do not generate prime number by doing 2*i+1    for ($i = 1; $i <= (sqrt($MAX) - 1) / 2; $i++)        for ($j = ($i * ($i + 1)) << 1;             $j <= $MAX / 2; $j = $j + 2 * $i + 1)            $marked[$j] = true;     // Since 2 is a prime number    array_push($primes, 2);     // Print other primes. Remaining primes are of the    // form 2*i + 1 such that marked[i] is false.    for ($i = 1; $i <= $MAX / 2; $i++)        if ($marked[$i] == false)            array_push($primes, 2 * $i + 1);} // Returns true if n is a Smith number, else false.function isSmith($n){    global $MAX, $primes;    $original_no = $n;     // Find sum the digits of prime    // factors of n    $pDigitSum = 0;    for ($i = 0; $primes[$i] <= $n / 2; $i++)    {        while ($n % $primes[$i] == 0)        {            // If primes[i] is a prime factor,            // add its digits to pDigitSum.            $p = $primes[$i];            $n = $n / $p;            while ($p > 0)            {                $pDigitSum += ($p % 10);                $p = $p / 10;            }        }    }     // If n!=1 then one prime factor still    // to be summed up;    if ($n != 1 && $n != $original_no)    {        while ($n > 0)        {            $pDigitSum = $pDigitSum + $n % 10;            $n = $n / 10;        }    }     // All prime factors digits summed up    // Now sum the original number digits    $sumDigits = 0;    while ($original_no > 0)    {        $sumDigits = $sumDigits + $original_no % 10;        $original_no = $original_no / 10;    }     // If sum of digits in prime factors and sum    // of digits in original number are same, then    // return true. Else return false.    return ($pDigitSum == $sumDigits);} // Driver code // Finding all prime numbers before limit. These// numbers are used to find prime factors.sieveSundaram(); echo "Printing first few Smith Numbers" .                    " using isSmith()\n";for ($i = 1; $i < 500; $i++)    if (isSmith($i))        echo $i . " "; // This code is contributed by mits?>
// JavaScript program to check whether a number is// Smith Number or not.let MAX  = 10000; // array to store all prime less than and equal to 10^6let primes = []; // utility function for sieve of sundaramfunction sieveSundaram(){     // In general Sieve of Sundaram, produces primes smaller    // than (2*x + 2) for a number given number x. Since    // we want primes smaller than MAX, we reduce MAX to half    // This array is used to separate numbers of the form    // i+j+2ij from others where 1 <= i <= j    let LEN = Math.floor(MAX/2) + 100;    let marked = [];    for (let i=0; i < LEN; i++) {        marked.push(0);    }     // Main logic of Sundaram. Mark all numbers which    // do not generate prime number by doing 2*i+1    for (let i=1; i<=Math.floor((Math.sqrt(MAX)-1)/2); i++){        for (let j=(i*(i+1))<<1; j<=Math.floor(MAX/2); j=j+2*i+1){            marked[j] = 1;        }    }     // Since 2 is a prime number    primes.push(2);             // Print other primes. Remaining primes are of the    // form 2*i + 1 such that marked[i] is false.    for (let i=1; i<=Math.floor(MAX/2); i++){        if (marked[i] == 0){            primes.push(2*i + 1);        }    }                 } // Returns true if n is a Smith number, else false.function isSmith(n){    let original_no = n;     // Find sum the digits of prime factors of n    let pDigitSum = 0;    for (let i = 0; primes[i] <= Math.floor(n/2); i++){        while (n % primes[i] == 0){             // If primes[i] is a prime factor,            // add its digits to pDigitSum.            let p = primes[i];            n = Math.floor(n/p);            while (p > 0){                pDigitSum += (p % 10);                p = Math.floor(p/10);            }        }    }     // If n!=1 then one prime factor still to be    // summed up;    if (n != 1 && n != original_no){        while (n > 0){            pDigitSum = pDigitSum + n%10;            n = Math.floor(n/10);        }    }     // All prime factors digits summed up    // Now sum the original number digits    let sumDigits = 0;    while (original_no > 0){        sumDigits = sumDigits + original_no % 10;        original_no = Math.floor(original_no/10);    }     // If sum of digits in prime factors and sum    // of digits in original number are same, then    // return true. Else return false.    return (pDigitSum === sumDigits);} // Driver code // Finding all prime numbers before limit. These// numbers are used to find prime factors.{    sieveSundaram();     console.log("Printing first few Smith Numbers using isSmith() ");    for (let i=1; i<500; i++){        // console.log(i);        if (isSmith(i)){            console.log(i);        }    }} // The code is contributed by Gautam goel (gautamgoel962)
Output:
Printing first few Smith Numbers using isSmith()
4 22 27 58 85 94 121 166 202 265 274 319 346 355 378 382 391 438 454 483 
Time Complexity: O(n log n) Auxiliary Space: O(n)
Smith Number | GeeksforGeeks - YouTubeGeeksforGeeks529K subscribersSmith Number | GeeksforGeeksWatch laterShareCopy linkInfoShoppingTap to unmuteIf playback doesn't begin shortly, try restarting your device.More videosMore videosYou're signed outVideos you watch may be added to the TV's watch history and influence TV recommendations. To avoid this, cancel and sign in to YouTube on your computer.CancelConfirmSwitch cameraShareInclude playlistAn error occurred while retrieving sharing information. Please try again later.Watch on0:000:000:00 / 7:06•Live•<div class="player-unavailable"><h1 class="message">An error occurred.</h1><div class="submessage"><a href="https://www.youtube.com/watch?v=nJVF9YkXxNA" target="_blank">Try watching this video on www.youtube.com</a>, or enable JavaScript if it is disabled in your browser.</div></div>
This article is contributed by Aarti_Rathi and Sahil Chhabra(KILLER). If you like GeeksforGeeks and would like to contribute, you can also write an article using write.geeksforgeeks.org or mail your article to review-team@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks. Please write comments if you find anything incorrect, or you want to share more information about the topic discussed above.
SushilKumar4
Mithun Kumar
Akanksha_Rai
surinderdawra388
gautamgoel962
codewithshinchan
series
sieve
Mathematical
Mathematical
series
sieve
Writing code in comment?
Please use ide.geeksforgeeks.org,
generate link and share the link here.
Algorithm to solve Rubik's Cube
Merge two sorted arrays with O(1) extra space
Program to print prime numbers from 1 to N.
Find next greater number with same set of digits
Segment Tree | Set 1 (Sum of given range)
Check if a number is Palindrome
Count ways to reach the n'th stair
Fizz Buzz Implementation
Count all possible paths from top left to bottom right of a mXn matrix
Product of Array except itself