Challenge description

A Smith number is a composite number whose sum of digits is equal to the sum of sums of digits of its prime factors. Given an integer N, determine if it's a Smith number or not.

The first few Smith numbers are 4, 22, 27, 58, 85, 94, 121, 166, 202, 265, 274, 319, 346, 355, 378, 382, 391, 438 (sequence A006753 in OEIS).

Sample input / output

18: False (sum of digits: 1 + 8 = 9; factors: 2, 3, 3; sum of digits of factors: 2 + 3 + 3 = 8)
22: True
13: False (meets the digit requirement, but is prime)
666: True (sum of digits: 6 + 6 + 6 = 18; factors: 2, 3, 3, 37; sum of digits of factors: 2 + 3 + 3 + 3 + 7 = 18)
-265: False (negative numbers can't be composite)
0: False (not composite)
1: False (not composite)
4937775: True


Notes

• Your code can be a function (method) or a full working program,
• Instead of words like True and False, you can use any truthy and falsy values, as long as it's clear what they are,
• This is a challenge, so make your code as short as possible!
• I had to read this: "sum of digits is equal to the sum of sums of digits of its prime factors" a few times :P – Stewie Griffin Sep 2 '16 at 14:29
• @StewieGriffin: Yes, it's a rather complicated sentence, but I felt like I needed to give a proper definition instead of relying solely on the examples :) – shooqie Sep 2 '16 at 14:30
• This is one of those questions where I thought "Java+this=no", I upvoted for the idea though :P – Shaun Wild Sep 2 '16 at 15:03
• I sometimes notice patterns in numbers, sum of digits etc., but really, do people notice stuff like this: "Albert Wilansky coined the term Smith number when he noticed the defining property in the phone number of his brother-in-law"? – Stewie Griffin Sep 2 '16 at 15:11
• @StewieGriffin: Yeah, it's like Ramanujan and 1729, always baffled me as well. – shooqie Sep 2 '16 at 15:16

Jelly, 12 11 bytes

Æfḟȯ.DFżDSE


Returns 1 for Smith numbers and 0 otherwise. Try it online! or verify all test cases.

Background

Æf (prime factorization) and D (integer-to-decimal) are implemented so that P (product) and Ḍ (decimal-to-integer) constitute left inverses.

For the integers -4 to 4, Æf returns the following.

-4 -> [-1, 2, 2]
-3 -> [-1, 3]
-2 -> [-1, 2]
-1 -> [-1]
0 -> [0]
1 -> []
2 -> [2]
3 -> [3]
4 -> [2, 2]


For the numbers -10, -1, -0.5, 0, 0.5, 1, 10, D returns the following.

-11   -> [-1, -1]
-10   -> [-1, 0]
-1   -> [-1]
-0.5 -> [-0.5]
0   -> [0]
0.5 -> [0.5]
1   -> [1]
10   -> [1, 0]
11   -> [1, 1]


How it works

Æfḟȯ.DFżDSE  Main link. Argument: n (integer)

Æf           Yield the prime factorization of n.
ḟ          Filter; remove n from its prime factorization.
This yields an empty array if n is -1, 0, 1, or prime.
ȯ.        If the previous result is an empty array, replace it with 0.5.
D       Convert all prime factors to decimal.
F      Flatten the result.
D    Yield n in decimal.
ż     Zip the results to both sides, creating a two-column array.
S   Compute the sum of each column.
If n is -1, 0, 1, or prime, the sum of the prime factorization's
digits will be 0.5, and thus unequal to the sum of the decimal array.
If n < -1, the sum of the prime factorization's digits will be
positive, while the sum of the decimal array will be negative.
E  Test both sums for equality.

• This is a seriously cool solution I have to say! – Emigna Sep 2 '16 at 18:48
• @Emigna - It's what I did, but implemented in a far superior fashion :D – Jonathan Allan Sep 2 '16 at 18:50
• @JonathanAllan Unfortunately I don't speak Jelly so I have no idea what your code does :) – Emigna Sep 2 '16 at 18:54
• @Emigna - yeah I had planned to work out how to golf it down before adding a how does it work section. – Jonathan Allan Sep 2 '16 at 19:26

Python 2, 122115110 106 bytes

n=m=input()
s=0
for d in range(2,n):
while n%d<1:n/=d;s+=sum(map(int,d))
print n<m>s==sum(map(int,m))


Saved 4 bytes thanks to Dennis

Try it on ideone.com

Explanation

Reads a number on stdin and outputs True if the number is a Smith number or False if it is not.

n=m=input()                  # stores the number to be checked in n and in m
s=0                          # initializes s, the sum of the sums of digits of prime factors, to 0
for d in range(2,n):         # checks all numbers from 2 to n for prime factors
while n%d<1:                # while n is divisible by d
#   (to include the same prime factor more than once)
n/=d                       # divide n by d
s+=sum(map(int,d))       # add the sum of the digits of d to s
print                        # print the result: "True" if and only if
n<m                    #   n was divided at least once, i.e. n is not prime
>                      #   and m>s (always true) and
s==sum(map(int,m))   #   s is equal to the sum of digits of m (the input)

• Down voter - it might be useful to add a comment to explain why – Jonathan Allan Sep 2 '16 at 16:07
• @JonathanAllan The downvote was cast automatically by the Community user when the answer was edited. I consider this a bug. – Dennis Sep 2 '16 at 17:22
• The last line can be rewritten as print n<m>s==sum(map(int,m)). – Dennis Sep 3 '16 at 3:33
• @Dennis That's a great use of chained comparison! – LevitatingLion Sep 4 '16 at 11:00

Brachylog, 19 bytes

@e+S,?$pPl>1,P@ec+S  Try it online! Explanation @e+S, S is the sum of the digits of the input. ?$pP             P is the list of prime factors of the input.
Pl>1,         There are more than 1 prime factors.
P@e      Split each prime factor into a list of digits.
c     Flatten the list.
+S   The sum of this list of digits must be S.

• @JonathanAllan It does. In Brachylog the negative sign for numbers is _ (so called low minus). – Fatalize Sep 2 '16 at 16:52

05AB1E, 11 17 bytes

X›0si¹ÒSO¹SOQ¹p_&


Explanation

X›0si              # if input is less than 2 then false, else
SO          # sum of digits
¹Ò            # of prime factors with duplicates
Q      # equal to
SO       # sum of digits
¹         # of input
&  # and
¹p_   # input is not prime


Try it online!

PowerShell v3+, 183 bytes

param($n)$b=@();for($a=$n;$a-gt1){2..$a|?{'1'*$_-match'^(?!(..+)\1+$)..'-and!($a%$_)}|%{$b+=$_;$a/=$_}}$n-notin$b-and(([char[]]"$n")-join'+'|iex)-eq(($b|%{[char[]]"$_"})-join'+'|iex)  No built-in prime checking. No built-in factoring. No built-in digit-sum. Everything's hand made. :D Takes input $n as an integer, sets $b equal to an empty array. Here, $b is our collection of prime factors.

Next is a for loop. We first set $a equal to our input number, and the conditional is until $a is less-than-or-equal-to 1. This loop is going to find our prime factors.

We loop from 2 up to $a, uses Where-Object (|?{...}) to pull out primes that are also factors !($a%$_). Those are fed into an inner-loop |%{...} that places the factor into $b and divides $a (thus we'll eventually get to 1). So, now we have all of our prime factors in $b. Time to formulate our Boolean output. We need to verify that $n is -notin $b, because if it is that means that $n is prime, and so isn't a Smith number. Additionally, (-and) we need to make sure that our two sets of digit sums are -equal. The resulting Boolean is left on the pipeline and output is implicit. NB - Requires v3 or newer for the -notin operator. I'm still running the input for 4937775 (this is slow to calculate), so I'll update this when that finishes. After 3+ hours, I got a stackoverflow error. So, there's some upper-bound somewhere. Oh well. This will work for negative input, zero, or one, because the right-hand of the -and will barf out an error while it tries to calculate the digit sums (shown below), which will cause that half to go to $false when evaluated. Since STDERR is ignored by default, and the correct output is still displayed, this is fine.

Test cases

PS C:\Tools\Scripts\golfing> 4,22,27,58,85,94,18,13,666,-265,0,1|%{"$_ -> "+(.\is-this-a-smith-number.ps1$_)}
4 -> True
22 -> True
27 -> True
58 -> True
85 -> True
94 -> True
18 -> False
13 -> False
666 -> True
Invoke-Expression : Cannot bind argument to parameter 'Command' because it is an empty string.
At C:\Tools\Scripts\golfing\is-this-a-smith-number.ps1:1 char:179
+ ... "$_"})-join'+'|iex) + ~~~ + CategoryInfo : InvalidData: (:String) [Invoke-Expression], ParameterBindingValidationException + FullyQualifiedErrorId : ParameterArgumentValidationErrorEmptyStringNotAllowed,Microsoft.PowerShell.Commands.InvokeExpressionCommand -265 -> False Invoke-Expression : Cannot bind argument to parameter 'Command' because it is an empty string. At C:\Tools\Scripts\golfing\is-this-a-smith-number.ps1:1 char:179 + ... "$_"})-join'+'|iex)
+                    ~~~
+ CategoryInfo          : InvalidData: (:String) [Invoke-Expression], ParameterBindingValidationException
+ FullyQualifiedErrorId : ParameterArgumentValidationErrorEmptyStringNotAllowed,Microsoft.PowerShell.Commands.InvokeExpressionCommand

0 -> False
Invoke-Expression : Cannot bind argument to parameter 'Command' because it is an empty string.
At C:\Tools\Scripts\golfing\is-this-a-smith-number.ps1:1 char:179
+ ... "$_"})-join'+'|iex) + ~~~ + CategoryInfo : InvalidData: (:String) [Invoke-Expression], ParameterBindingValidationException + FullyQualifiedErrorId : ParameterArgumentValidationErrorEmptyStringNotAllowed,Microsoft.PowerShell.Commands.InvokeExpressionCommand 1 -> False  MATL, 17 bytes YftV!UsGV!Us=wnqh  Outputs truthy or falsey arrays where a truthy output requires that all elements be non-zero. Try it online • @JonathanAllan Yes. I'm adding a bit about the definition of truthy and falsey. – Suever Sep 2 '16 at 15:58 Jelly, 27 25 23 bytes (further golfing probably definitely possible) ḢDS× ÆFÇ€SḢ DS=Ça<2oÆP¬  Returns 0 for False or 1 for True All test cases at TryItOnline How? DS=Ça<2oÆP¬ - main link takes an argument, n DS - transform n to a decimal list and sum up Ç - call the previous link (ÆFÇ€SḢ) = - test for equality <2 - less than 2? a - logical and ÆP - is prime? o - logical or ¬ - not - all in all tests if the result of the previous link is equal to the digit sum if the number is composite otherwise returns 0. ÆFÇ€SḢ - link takes an argument, n again ÆF - list of list of n's prime factors and their multiplicities Ç€ - apply the previous link (ḢDS×) for each S - sum up Ḣ - pop head of list (there will only be one item) ḢDS× - link takes an argument, a factor, multiplicity pair Ḣ - pop head, the prime factor - modifies list leaving the multiplicity DS - transform n to a decimal list and sum up × - multiply the sum with the multiplicity  Actually, 18 bytes Unfortunately, Actually doesn't have a factorization builtin that gives a number's prime factors to multiplicity, so I had to hack one together. Golfing suggestions welcome. Try it online! ;wi$nMΣ♂≈Σ@$♂≈Σ=  Ungolfing  Implicit input n. ;w Duplicate n and get the prime factorization of a copy of n. ...M Map the following function over the [prime, exponent] lists of w. i Flatten the list. Stack: prime, exponent.$n       Push str(prime) to the stack, exponent times.
The purpose of this function is to get w's prime factors to multiplicity.
Σ        sum() the result of the map.
On a list of strings, this has the same effect as "".join()
♂≈Σ      Convert every digit to an int and sum().
@        Swap the top two elements, bringing other copy of n to TOS.
$♂≈Σ Push str(n), convert every digit to an int, and sum(). = Check if the sum() of n's digits is equal to the sum of the sum of the digits of n's prime factors to multiplicity. Implicit return.  Haskell, 120 105 bytes 1%_=[];a%x|mod a x<1=x:div a x%x|0<1=a%(x+1) p z=sum[read[c]|c<-show z] s x|z<-x%2=z<[x]&&sum(p<$>z)==p x


Octave, 80 78 bytes

t=num2str(factor(x=input('')))-48;disp(any(t<0)&~sum([num2str(x)-48 -t(t>0)]))


Explanation:

factor(x=input(''))                 % Take input, store as x and factor it
num2str(factor(x=input('')))-48     % Convert it to an array (123 -> [1 2 3])
% and store as t
any(t<0)                            % Check if there are several prime factors
% [2 3] -> [2 -16 3]
sum([num2str(x)-48 -t(t>0)])        % Check if sum of prime factor
% is equal the sum of digits


Try it online.

• That any(t<0) for non-primality is very clever – Luis Mendo Sep 2 '16 at 16:19

Pyth, 21 bytes

&&>Q1!P_QqsjQTssmjdTP


A program that takes input of an integer and prints True or False as relevant.

Try it online

How it works

&&>Q1!P_QqsjQTssmjdTP  Program. Input: Q
jQT         Yield digits of the base-10 representation of Q as a list
P  Yield prime factors of Q (implicit input fill)
mjdT   Map base-10 representation across the above, yielding digits of each
factor as a list of lists
s       Flatten the above
q             Those two sums are equal
&                      and
>Q1                  Q>1
&                     and
!P_Q              Q is not prime
Implicitly print


Perl 6, 9288 87 bytes

{sub f(\i){my \n=first i%%*,2..i-1;n??n~f i/n!!i}
!.is-prime&&$_>1&&.comb.sum==.&f.comb.sum}  {sub f(\i){my \n=first i%%*,2..^i;n??[n,|f i/n]!!|i}$_>.&f>1&&.comb.sum==.&f.comb.sum}


An anonymous function that returns a Bool.

• Now does 100% manual factorization and primality checking.
• Saved some bytes by testing both "input > 1" and "number of factors > 1" with one chained comparison, since m > Ω(m).

EDIT: -1 byte thanks to b2gills

• 2..i-1 is better spelt as 2..^i. – Brad Gilbert b2gills Sep 6 '16 at 2:54

Java 7, 509506435426419 230 bytes

boolean c(int n){return n<2|p(n)?0>1:d(n)==f(n);}int d(int n){return n>9?n%10+d(n/10):n;}int f(int n){int r=0,i;for(i=1;++i<=n;)for(;n%i<1;n/=i,r+=i>9?d(i):i);return r;}boolean p(int n){int i=2;while(i<n)n=n%i++<1?0:n;return n>1;}


I should have listened to @BasicallyAlanTuring's comment..

This is one of those questions where I thought "Java+this=no", I upvoted for the idea though :P

Ah well.. Some programming languages use a single byte for the prime-factors or prime-check, but Java is certainly not one of them.

EDIT: Halved the amount of bytes now that I had some time to think about it.

Ungolfed (sort-off..) & test cases:

Try it here.

class M{
static boolean c(int n){
return n < 2 | p(n)
? 0 > 1 //false
: d(n) == f(n);
}

// Sums digits of int
static int d(int n) {
return n > 9
? n%10 + d(n/10)
: n;
}

// Convert int to sum of prime-factors
static int f(int n) {
int r = 0,
i;
for(i = 1; ++i <= n; ){
for( ; n % i < 1; n /= i,
r += i > 9 ? d(i) : i);
}
return r;
}

// Checks if the int is a prime
static boolean p(int n){
int i = 2;
while(i < n){
n = n % i++ < 1
? 0
: n;
}
return n > 1;
}

public static void main(String[] a){
System.out.println(c(18));
System.out.println(c(22));
System.out.println(c(13));
System.out.println(c(666));
System.out.println(c(-256));
System.out.println(c(0));
System.out.println(c(1));
System.out.println(c(4937775));
}
}


Output:

false
true
false
true
false
false
false
true


¬ṗ&ẹ+.&ḋcẹ+


Try it online!

Predicate succeeds if the input is a Smith number and fails if it is not.

               The input
¬ṗ             is not prime,
&            and the input's
ẹ           digits
+          sum to
.         the output variable,
&        and the input's
ḋ       prime factors' (getting prime factors of a number < 1 fails)
c      concatenated
ẹ     digits
+    sum to
the output variable.


Japt, 14 11 bytes

ìx ¥Uk x_ìx


-3 bytes thanks to @Shaggy

Try it online!

• 11 bytes – Shaggy Mar 3 at 17:17
• Note to self: need to remember which functions can be passed functions – Quintec Mar 3 at 19:02

JavaScript (ES6),  87 86  84 bytes

m=>(i=2,S=0,g=n=>([...i+''].map(v=>s-=v,s=S),i-m?n%i?g(n,i++):g(n/i,S=s):s==2*S))(m)


Try it online!

Pyke, 16 bytes

Pm[mbs(sQ[qRlt*


Try it here!

• Errors without result for input less than 2 – Jonathan Allan Sep 2 '16 at 15:53
• @JonathanAllan no output to stdout is falsy. If warnings are disabled stderr gets ignored too – Blue Sep 2 '16 at 17:04
• I knew we can ignore stderr, but no output seems a bit weird ...but if it's acceptable then it's acceptable. – Jonathan Allan Sep 2 '16 at 17:07
• Personally I'm not sure if it's acceptable but I can say it is right? – Blue Sep 2 '16 at 17:07

Perl 6, 80 bytes

{.[0]==.flat.skip.sum}o($!={.comb.sum,($/=first $_%%*,2..^$_)&&map $!,$/,$_/$/})


Try it online!

Anonymous code block that takes an integer and returns a boolean.

APL (Dyalog Extended), 36 29 bytesSBCS

This answer owes its golfiness to Extended's ⍭ monad for returning the prime factors of a number, and that ⊤ is better at base-conversion than in Dyalog Unicode.

Edit: -7 bytes thanks to dzaima.

{2>⍵:0⋄(⊃=+/-⊃×2<≢)+⌿10⊤⍵,⍭⍵}


Try it online!

Explanation

{1⋄(3)2}  A dfn, a function in brackets. ⋄ is a statement separator.
The numbers signify the sections in the order they are explained.

2>⍵:0  If we have a number less than 2,
we immediately return 0 to avoid a DOMAIN ERROR.

+⌿10⊤⍵,⍭⍵
⍭⍵  We take the factors of ⍵, our input as our right argument,
⍵,    and append it to our input again.
10⊤      before converting the input and its factors into a matrix of their base-10 digits
(each row is the places, units, tens, hundreds, etc.)
+⌿         And taking their sum across the columns of the resulting matrix,
to give us the sum of their digits, their digit-sums.

(⊃=+/-⊃×2<≢)  We run this section over the list of sums of digits above.
⊃=+/-⊃       We check if the main digit-sum (of our input)
Is equal to the sum of our digit-sums
(minus our main digit-sum that is also still in the list)
×2<≢   The trick here is that we can sneak in our composite check
(if our input is prime there will be only two numbers,
the digit-sum of the prime,
and the digit-sum of its sole prime factor, itself)
So if we have a prime, we zero our (minus our main sum)
in the calculation above, so that primes will not succeed in the check.
We return the result of the check.

• 29 bytes - {2>⍵:0⋄(⊃=+/-⊃×2<≢)+⌿10⊤⍵,⍭⍵} – dzaima Mar 3 at 20:37

J, 31 30 bytes

0&p:*](=+/)&(1#."."0@":)q: ::1


Try it online!

C (gcc), 139 136 bytes

S(m,i,t,h,_){t=m=m<2?2:m;for(_=h=i=1;m>1;h=1){while(m%++h);for(m/=h;i+=h%10,h/=10;);}while(t%++h);for(m=t;_+=m%10,m/=10;);m=t-h?i==_:0;}


Try it online!

-3 bytes thanks to ceilingcat

Explanation:

/*
* Variable mappings:
*  is_smith      => S
*  argument      => m
*  factor_digits => i
*  arg_copy      => t
*  least_factor  => h
*  digit_sum     => _
*/
int is_smith(int argument){                     /* S(m,i,t,h,_){ */
int factor_digits;
int arg_copy;
int least_factor;
int digit_sum;

/*
* The cases of 0 and 1 are degenerate.
* Mapping them to a non-degenerate case with the right result.
*/
if (argument < 2) {                         /* t=m=m<2?2:m; */
argument = 2;
}
arg_copy = argument;

/*
* Initializing these to 1 instead of zero is done for golf reasons.
* In the end we just compare them, so it doesn't really matter.
*/
factor_digits = 1;                          /* for(_=h=i=1; */
digit_sum = 1;

/* Loop over each prime factor of argument */
while (argument > 1) {                      /* m>1; */

/*
* Find the smallest factor
* Note that it is initialized to 1 in the golfed version since prefix
* increment is used in the modulus operation.
*/
least_factor = 2;                       /* h=1){ */
while (argument % least_factor != 0)    /* while(m% */
least_factor++;                     /* ++h); */
argument /= least_factor;               /* for(m/=h; */

/* Add its digit sum to factor_digits */
while (least_factor > 0) {
factor_digits += least_factor % 10; /* i+=h%10, */
least_factor /= 10;                 /* h/=10;) */
}                                       /* ; */

}                                           /* } */

/* In the golfed version we get this for free in the for loop. */
least_factor = 2;
while (arg_copy % least_factor != 0)        /* while(t% */
least_factor++;                         /* ++h); */

/* Restore the argument */
argument = arg_copy;                        /* for(m=t; */

/* Compute the arguments digit sum */
while (argument > 0) {
digit_sum += argument % 10;             /* _+=m%10, */
argument /= 10;                         /* m/=10;) */
}                                           /* ; */

/* This return is done by assigning to first argument when golfed. */
/* m= */
if (arg_copy == least_factor) {             /* t==h? */
return 0; /* prime input */             /* 0 */
} else {                                    /* : */
return digit_sum == factor_digits;      /* i == _ */
}                                           /* ; */
}                                               /* } */

• That introduced a few bugs (e.g. 2 and 3) but I think it should still be achievable. – LambdaBeta Apr 26 at 18:48
• Suggest t-h&&i==_ instead of t-h?i==_:0 – ceilingcat May 14 at 16:33

Racket 176 bytes

(define(sd x)(if(= x 0)0(+(modulo x 10)(sd(/(- x(modulo x 10))10)))))
(require math)(define(f N)
(if(=(for/sum((i(factorize N)))(*(sd(list-ref i 0))(list-ref i 1)))(sd N))1 0))


Returns 1 if true and 0 if false:

(f 27)
1
(f 28)
0
(f 85)
1
(f 86)
0


Detailed version:

(define (sd x)   ; fn to find sum of digits
(if (= x 0)
0
(+ (modulo x 10)
(sd (/ (- x (modulo x 10)) 10)))))

(require math)
(define (f N)
(if (= (for/sum ((i (factorize N)))
(* (sd (list-ref i 0))
(list-ref i 1)))
(sd N)) 1 0))


Rust - 143 bytes

fn t(mut n:u32)->bool{let s=|k:u32| (2..=k).fold((0,k),|(a,m),_|(a+m%10,m/10));s(n).0==(2..n).fold(0,|mut a,d|{while n%d<1{n/=d;a+=s(d).0};a})}


borrowed python solution by @levitatinglion ... at least this is shorter than Java...

degolfed at play.rust-lang.org

APL(NARS), 33 char, 66 bytes

{1≥≢k←π⍵:0⋄s←{+/⍎¨⍕⍵}⋄(s⍵)=+/s¨k}


"π⍵" return list factors of ⍵, assume the input is one positive integer >=1; test:

  h←{1≥≢k←π⍵:0⋄s←{+/⍎¨⍕⍵}⋄(s⍵)=+/s¨k}
(h¨1..100)/1..100
4 22 27 58 85 94


C (gcc), 177 Bytes

Defines a function Q that returns 0 for smith numbers and nonzero for non-smith numbers

#define r return
O(D,i){for(i=0;D>0;i+=D%10,D-=D%10,D/=10);r i;}D(O,o){for(o=1;o<O;)if(O%++o<1)r o;r O;}Q(p,q,i,j){if(p^(q=D(i=p))){for(j=0;p>1;q=D(p/=q))j+=O(q);r j^O(i);}r 1;}


Try it online!

Explanation:

// Return the sum of digits of D if D > 0, otherwise 0
O(D,i){
// While D is greater than 0:
// Add the last digit of D to i, and remove the last digit from D
for(i=0;D>0;i+=D%10,D-=D%10,D/=10);
return i;
}
// Return the smallest prime factor of O if O>1 else O
D(O,o){
// Iterate over numbers less than O
for(o=1;o<O;)
// If O is divisible by o return o
if(O%++o<1)
return o;
// Otherwise return O
return O;
}
Q(p,q,i,j){
// Set q to D(p) and i to p
// If p != D(p) (i.e, p is composite and > 0)
if(p^(q=D(i=p))){
// Iterate over the prime factors of p and store their digit sum in j
for(j=0;p>1;q=D(p/=q))
j+=O(q);
// i is the original value of p. If O(i)^j == 0, O(i) == j
return j^O(i);
}
// If p was composite or < 0, return 1
return 1;
}


C# (Visual C# Interactive Compiler), 122 bytes

n=>{int m=n,b=0,a=$"{n}".Sum(x=>x-'0');for(int i=2;i<m;i++)if(n%i==0){b+=$"{i}".Sum(x=>x-'0');n/=i;i=1;}return n>0&&a==b;}
`

Try it online!