31
\$\begingroup\$

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.

Your Task:

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.

Examples:

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.

\$\endgroup\$
9
  • \$\begingroup\$ Is 60 a sphenic number? 2 × 2 × 3 × 5 \$\endgroup\$ Commented Jul 23, 2017 at 15:30
  • 1
    \$\begingroup\$ @EriktheOutgolfer that's not the product of 3 distinct primes though, that's the product of 3 distinct and 1 duplicate prime. \$\endgroup\$
    – Riker
    Commented Jul 23, 2017 at 15:31
  • 1
    \$\begingroup\$ @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) \$\endgroup\$ Commented Jul 23, 2017 at 15:32
  • \$\begingroup\$ @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. \$\endgroup\$
    – Wheat Wizard
    Commented Jul 23, 2017 at 15:59
  • \$\begingroup\$ @WheatWizard, 60 is not a sphenic number (e.g. output/return falsy). \$\endgroup\$
    – Gryphon
    Commented Jul 23, 2017 at 18:31

41 Answers 41

1
2
1
\$\begingroup\$

Thunno 2, 9 bytes

Ƒsfç⁼lp3=

Attempt This Online!

Explanation:

Ƒ          # unique prime factors
 s         # swap so input is back on top
  f        # prime factors
   ç       # apply each to the stack, and wrap results:
    ⁼      #   exactly equal?
     l     #   length
      p    # product
       3=  # equal to 3?
\$\endgroup\$
1
\$\begingroup\$

Vyxal, 8 bytes

ǐ₌ÞuL*3=

Try it Online!

Seems Vyxal always beats Thunno 2 by just a byte or two...this is basically the same as my Thunno 2 answer.

\$\endgroup\$
1
\$\begingroup\$

Desmos, 96 bytes

f(k)=0^{(3-∑_{n=2}^k0^{mod(k,n)}sgn(∏_{d=3}^nmod(n,d-1))log_n(gcd(k,n^{ceil(log_nk)}))^2)^2}

Try It On Desmos!

Try It On Desmos! - Prettified

Port of Dennis's Jelly answer so make sure to upvote that one too. There is probably a shorter way to go about this though, but this is the most straightforward way I saw that could easily be ported to Desmos.

I might put a longer explanation on how this works if I have time.

\$\endgroup\$
1
\$\begingroup\$

Arturo, 43 bytes

$=>[x∧3=size x:=unique<=<=factors.prime&]

Try it!

Simply asks "are its prime factors unique and are there three?"

\$\endgroup\$
0
\$\begingroup\$

Mathematica, 66 57 bytes

Length@#1==3&&And@@EqualTo[1]/@#2&@@(FactorInteger@#)&

Defines an anonymous function.

is Transpose.

Explanation

FactorInteger gives a list of pairs of factors and their exponents. E.g. FactorInteger[2250]=={{2,1},{3,2},{5,3}}. This is transposed for ease of use and fed to the function Length@#1==3&&And@@EqualTo[1]/@#2&. The first part, Length@#1==3, checks that there are 3 unique factors, while the second, And@@EqualTo[1]/@#2 checks that all the exponents are 1.

\$\endgroup\$
0
\$\begingroup\$

Python 99 bytes

def s(n):a,k=2,0;exec('k+=1-bool(n%a)\nwhile not n%a:n/=a;k+=10**9\na+=1\n'*n);return k==3*10**9+3

First submission. Forgive me if I did something wrong. Kinda silly, counts the number of factors of n, and then the number of times n is divisible by each (by adding 10**9).

I'm pretty sure there are a few easy ways to cut off ~10-20 characters, but I didn't.

Also this is intractably slow at 10**9. Could be made okay by changing '...a+=1\n'*n to '...a+=1\n'*n**.5, as we only need to go to the square root of n.

\$\endgroup\$
0
\$\begingroup\$

Pari/GP, 34 bytes

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

Try it online!

\$\endgroup\$
0
\$\begingroup\$

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.

\$\endgroup\$
0
\$\begingroup\$

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
;
\$\endgroup\$
0
\$\begingroup\$

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);
            Console.ReadLine ();
        }
    }
}

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!

\$\endgroup\$
3
  • \$\begingroup\$ 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. \$\endgroup\$
    – Brian J
    Commented Jul 27, 2017 at 18:52
  • \$\begingroup\$ @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? \$\endgroup\$
    – MetaColon
    Commented Jul 27, 2017 at 19:03
  • \$\begingroup\$ 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. \$\endgroup\$
    – Brian J
    Commented Jul 27, 2017 at 19:11
0
\$\begingroup\$

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

\$\endgroup\$
1
2

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.