Is it a Sphenic Number?

A Sphenic Number is a number that is the product of exactly three distinct primes. The first few Sphenic numbers are 30, 42, 66, 70, 78, 102, 105, 110, 114. This is sequence A007304 in the OEIS.

Write a program or function to determine whether an inputted integer is a Sphenic number.

Input:

An integer between 0 and 10^9, which may or may not be a Sphenic Number.

Output:

A truthy/falsy value indicating whether the input is a Sphenic Number.

30  -> true
121 -> false
231 -> true
154 -> true
4   -> false
402 -> true
79  -> false
0   -> false
60  -> false
64  -> false
8   -> false
210 -> false

Scoring:

This is , shortest code in bytes wins.

• Is 60 a sphenic number? 2 × 2 × 3 × 5 – Erik the Outgolfer Jul 23 '17 at 15:30
• @EriktheOutgolfer that's not the product of 3 distinct primes though, that's the product of 3 distinct and 1 duplicate prime. – Rɪᴋᴇʀ Jul 23 '17 at 15:31
• @Riker I'm not really sure if "3 distinct primes" means "3 primes that are all distinct" or "when uniquified there should remain 3 primes". EDIT: Oh I see, 60 isn't a sphenic number. (waiting for OP clarification) – Erik the Outgolfer Jul 23 '17 at 15:32
• @EriktheOutgolfer According to the definition of sphenic numbers, 60 is not one of them. I do not know however if 60 is valid for this challenge. – Sriotchilism O'Zaic Jul 23 '17 at 15:59
• @WheatWizard, 60 is not a sphenic number (e.g. output/return falsy). – Gryphon Jul 23 '17 at 18:31

Pari/GP, 34 bytes

n->if(n,moebius(n)*omega(n)==-3,0)

Try it online!

Perl 6, 43 bytes

{3==grep ->\a{a.is-prime&&$_%%(a^a*a)},^$_}

Try it online!

The grep produces a list of the numbers a up to, but not including, the argument to the function \$_, such that:

• a is prime (a.is-prime); and
• exactly one of a and a*a (a ^ a*a) divide the argument.

The latter condition excludes prime factors that occur in multiplicities of higher than one.

Forth, 153

: w swap ;
: d 2dup ;
: o rot ;
: sp 0 w 1
begin 1+ d mod 0= if w over / w d mod 0= if o 16 + o o then o 1+ o o then
d > 0= until drop 1 = w 3 = and ;

( 153 including spaces. Spaces are required delimiters in Forth. )

( Test frame for compressed version: )

: testsp
0 do i 8 .r space
i sp if ." true" else ." false" then
cr
loop
;

( This uses a corrected version of betseg's answer.)

( Uncompressed, with comments: )

: sphenic ( n -- f )
0 ( counter )
swap 1 ( counter n probe )
begin
1+ ( increment probe )
2dup mod ( Remainder? )
0= if
swap over / ( reduced-n )
swap ( bring probe back )
2dup mod 0= if
rot 128 + rot rot
then
rot 1+ rot rot ( count and put count back )
then ( counter reduced-n probe )
2dup > 0=
until
drop 1 =
swap 3 = and
;

: testsphenic
0 do i 8 .r space
i sphenic if ." true" else ." false" then
cr
loop
;

C#, 172 Bytes

I'd appreciate improvement suggestions:

n=>{var r=Enumerable.Range(2,n).Where(i=>Enumerable.Range(2,i-2).All(a=>i%a!=0));return r.SelectMany(x=>r.SelectMany(y=>r.Select(z=>x==z|x==y|y==z?-1:x*y*z))).Contains(n);}

With formatting:

n =>
{
var r = Enumerable.Range (2, n).Where (i => Enumerable.Range (2, i - 2).All (a => i % a != 0));
return r.SelectMany (
x => r.SelectMany (
y => r.Select (z => x == z | x == y | y == z ? -1 : x * y * z))).Contains (n);
}

And as whole programm:

using System;
using System.Linq;

namespace S
{
class P
{
static void Main ()
{
Func<int, bool> s =
n =>
{
var r = Enumerable.Range (2, n).Where (i => Enumerable.Range (2, i - 2).All (a => i % a != 0));
return r.SelectMany (
x => r.SelectMany (
y => r.Select (z => x == z | x == y | y == z ? -1 : x * y * z))).Contains (n);
}
;

for (var i = 0; i < 1000; i++)
if (s (i))
Console.WriteLine (i);
}
}
}

If you add the byte count of the using directives (which are needed for the code to compile), you'd get 203 Bytes.

Try it online!

• Would you be to make a function with a single letter name for Enumerable.Range(2, m)? You call it twice, and it might save some bytes. – Brian J Jul 27 '17 at 18:52
• @BrianJ The idea doesn't sound bad, but I don't know how I'd do it. Is it possible to define methods inside of statement lambdas? – MetaColon Jul 27 '17 at 19:03
• You can, but I forgot how verbose it becomes. Quick and dirty, I got Func<int, IEnumerable<int>> e = a => { return Enumerable.Range(2, a); };, plus another using. – Brian J Jul 27 '17 at 19:11

JavaScript (ES6), 80 bytes

n=>(p=(n,f=2)=>n%f?p(n,f+1):f,(a=p(n))<n&&(b=p(n/=a))<n&&(c=p(n/=b))==n&a<b&b<c)

Using a recursive function to get the smaller factor.
Output 1 if sphenic, false if there are 2 or less factors and 0 otherwise

Test

F=
n=>(p=(n,f=2)=>n%f?p(n,f+1):f,(a=p(n))<n&&(b=p(n/=a))<n&&(c=p(n/=b))==n&a<b&b<c)

;[30,121,231,154,4,402,79,0,60,64,8,210].forEach(
x=>console.log(x,F(x))
)

C#7 122 bytes

bool F(int n){int P(int m,int f=2)=>m%f>0?P(m,f+1):f;int a,b,c;return(a=P(n))<n&&(b=P(n/=a))<n&&(c=P(n/=b))==n&a<b&b<c;}

porting of my JS answer