5
\$\begingroup\$

Six is a number perfect in itself, and not because God created all things in six days; rather, the converse is true. God created all things in six days because the number six is perfect.

I am fascinated by numbers. As were Sophie Germain and Marin Mersenne. To be more specific, these two were fascinated by primes: a number with only two integer divisors: itself and 1. In fact, they were so fascinated by primes that classes of primes were named after them:

A Mersenne prime is a prime number which can be generated by the formula 2p - 1 where p is a prime. For example, 7 = 2^3 - 1 therefore 7 is a Mersenne prime.

A Germain prime is similar. It is a prime number that when plugged into the formula 2p + 1 it also produces a prime. E.g. 11 is Germain as 2*11 + 1 = 23 which is prime.

But now let's move on to the next three numbers: perfect, vampire and narcissistic numbers.

A perfect number is very easy to understand. It can be easily defined as

A number where all its divisors except itself sum to itself. For example, 6 is a perfect number as the divisors of 6 (not including 6) are 1,2,3 which sum to make 6.

A vampire number may be the most difficult to code. A vampire number is a number whose digits can be split into two numbers, of equal length, made from all those digits, that when multiplied, produce the original number. Leading 0s aren't allowed in either of the numbers E.g. 136,948 = 146 x 938

Finally a narcissistic number, probably the hardest to understand. A narcissistic number is a number in which the individual digits, raised to the power of the total number of digits sum to make the original number. A single digit number has to be narcissistic.

For example, 8,208 is narcissistic:

84 + 24 + 04 + 84 = 4,096 + 16 + 0 + 4,096 = 8,208

Your task is to create a program that will take an integer and return what category it fits into. The categories are Mersenne, Germain, Perfect, Vampire, Narcissistic and False. Every number that doesn't fit into the first five categories is False. False doesn't have to necessarily be a falsy value.

If a value fits in more than one category, e.g. 3, you may output any correct result.

Output can be in any form, for example, 6 different numbers, as long as you say what it is in your answer.

Even if it is shorter, you aren't allowed to hard code each number as that ruins maths.

This is a so shortest code wins!

Examples

Input -> Output

10 -> False
7 -> Mersenne
8208 -> Narcissistic
28 -> Perfect
153 -> Narcissistic
2 -> Germain
17 -> False
16,758,243,290,880 -> Vampire
31 -> Mersenne
33,550,336 -> Perfect
173 -> Germain
136,948 -> Vampire
\$\endgroup\$

marked as duplicate by Peter Taylor code-golf Sep 1 '17 at 18:02

This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.

  • 4
    \$\begingroup\$ We seem to have a challenge for almost all of these tasks individually. Grouping a bunch of them together doesn't make this not a duplicate in my eyes, but I won't hammer yet in case the community disagrees. \$\endgroup\$ – FryAmTheEggman Sep 1 '17 at 14:41
  • \$\begingroup\$ FWIW I, too, think this is a duplicate \$\endgroup\$ – H.PWiz Sep 1 '17 at 15:02
  • \$\begingroup\$ Is an incorrect answer due to a precision error okay? \$\endgroup\$ – Okx Sep 1 '17 at 15:38
  • 1
    \$\begingroup\$ Out of curiosity, are there any numbers which fit in more than 1 category? \$\endgroup\$ – Socratic Phoenix Sep 1 '17 at 15:38
  • \$\begingroup\$ @SocraticPhoenix 3, stated in the challenge. \$\endgroup\$ – Okx Sep 1 '17 at 15:39
3
\$\begingroup\$

05AB1E, 43 40 39 bytes

Lo<¹å¹p&¹·>p¹p&¹Ñ¨OQ¹œε2ä}P¹å¹S¹gmOQ)Xk

-1 for False, 0 for Mersenne, 1 for Germain, 3 for Perfect, 4 for Vampire, and 5 for Narcissistic.

Try it online!

\$\endgroup\$
  • \$\begingroup\$ .²p isn't enough I think, floats are prime in 05AB1E, and may return a float. \$\endgroup\$ – Erik the Outgolfer Sep 1 '17 at 15:41
  • \$\begingroup\$ @EriktheOutgolfer Fixed. \$\endgroup\$ – Okx Sep 1 '17 at 15:49
4
\$\begingroup\$

Pyth, 71 bytes

x[.EmqQ*shdsed.cs.pM.cK`Q/lK2 2qsP{*MyPQQ&P_hyQP_Q<.&QhQP_QqQsm^sdlKK)1

Try it here! or Verify the test cases.

Alternative solution, 71 bytes:

x[.EmqQ*shdsed.cs.pM.cK`Q/lK2 2qsP{*MyPQQ&P_hyQP_Q&.AjQ2P_QqQsm^sdlKK)1

Try it here! or Verify the test cases.

This returns -1 for False, 0 for Vampire, 1 for Perfect, 2 for Sophie Germain, 3 for Mersenne and 4 for Narcissistic. In case more are truthy, this picks the one with the lowest index. Unfortunately, this memory errors for the following test cases: 33550336, 16758243290880.


Explanation

Vampire (29 bytes)

.EmqQ*shdsed.cs.pM.cK`Q/lK2 2

                  .c `Q/lK2      Get all combinations of the input's digits of half its length.
                .pM              Get all possible permutations of each.
             .cs            2    Get all possible two-number combinations, flattened.
.EmqQ*shdsed                     Check if any has the product equal to the input.

Let's go through an example. Let's assume our input is 1260.

  • First of all, we get the all the possible combinations of 2 digits (number_of_digits / 2). We get ['12', '16', '10', '26', '20', '60'].

  • Then, we get the possible permutations of each, [['12', '21'], ['16', '61'], ['10', '01'], ['26', '62'], ['20', '02'], ['60', '06']].

  • We flatten that (['12', '21', '16', '61', '10', '01', '26', '62', '20', '02', '60', '06']) and get all the possible 2-element combinations. This list is quite long:

    [['12', '21'], ['12', '16'], ['12', '61'], ['12', '10'], ['12', '01'], ['12', '26'], ['12', '62'], ['12', '20'], ['12', '02'], ['12', '60'], ['12', '06'], ['21', '16'], ['21', '61'], ['21', '10'], ['21', '01'], ['21', '26'], ['21', '62'], ['21', '20'], ['21', '02'], ['21', '60'], ['21', '06'], ['16', '61'], ['16', '10'], ['16', '01'], ['16', '26'], ['16', '62'], ['16', '20'], ['16', '02'], ['16', '60'], ['16', '06'], ['61', '10'], ['61', '01'], ['61', '26'], ['61', '62'], ['61', '20'], ['61', '02'], ['61', '60'], ['61', '06'], ['10', '01'], ['10', '26'], ['10', '62'], ['10', '20'], ['10', '02'], ['10', '60'], ['10', '06'], ['01', '26'], ['01', '62'], ['01', '20'], ['01', '02'], ['01', '60'], ['01', '06'], ['26', '62'], ['26', '20'], ['26', '02'], ['26', '60'], ['26', '06'], ['62', '20'], ['62', '02'], ['62', '60'], ['62', '06'], ['20', '02'], ['20', '60'], ['20', '06'], ['02', '60'], ['02', '06'], ['60', '06']]
    
  • The next step is getting the product of each pair:

    [252, 192, 732, 120, 12, 312, 744, 240, 24, 720, 72, 336, 1281, 210, 21, 546, 1302, 420, 42, 1260, 126, 976, 160, 16, 416, 992, 320, 32, 960, 96, 610, 61, 1586, 3782, 1220, 122, 3660, 366, 10, 260, 620, 200, 20, 600, 60, 26, 62, 20, 2, 60, 6, 1612, 520, 52, 1560, 156, 1240, 124, 3720, 372, 40, 1200, 120, 120, 12, 360]
    
  • And then compare to the input:

    [False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False]
    
  • Finally, the last step is checking if any value is truthy. And there is one (at index 19 into the list). Hence, this returns a truthy value for 1260, thanks to the pair [21, 60].

Perfect (10 bytes)

qsP{*MyPQQ

q        Q   Is equal to the input?
 s           Sum.
   {*MyPQ    Its divisors.
  P          Popped (since we want the proper divisors).

Sophie Germain (9 bytes)

&P_hyQP_Q

      P_Q    Is the input prime?
 P_hy        Is the input doubled + 1 prime?
&            Logical AND.

Mersenne (9 bytes)

<.&QhQP_Q

<             Is smaller?
 .&             Bitwise AND between:
   Q              The input
    hQ             And the input + 1 
              than:
      P_Q       Is the input prime?

This tests if the input + 1 is a power of two (i.e. if it is a Mersenne number), and then performs the primality test. In Python, bool is a subclass of int, so truthy is treated as 1 and falsy is treated as 0. To avoid checking explicitly that one is 0 and the other is 1, we compare their values using < (since we only have 1 such case).

In the alternative approach, this part is changed to &.AjQ2P_Q. This works as follows:

&.AjQ2P_Q

   jQ2      The input in binary as a list of digits.
 .A         Are all truthy (i.e equal to 1)?
&     P_Q   ... And is prime?

This uses the fact that any number of the form 2n - 1 only consists of 1 when written in binary, and also checks if it is prime.

Narcissistic (10 bytes)

qQsm^sdlKK

q            Is equal?
 Q           The Input
   m     K   Map over the string representation of the input.
    ^sdlK    Raise each digit to the power of the number of digits the input has.
  s          Summed.

When it comes to the rest of the code, [...) builds a list of bool values and x[...)1 gets the index of the first truthy element.

\$\endgroup\$
2
\$\begingroup\$

Jelly, 53 bytes

“+1l2Ḟ⁼¡Ḟ$ÆPȧÆP“_1HÆPȧÆP“ÆḌS⁼“DŒ!œs€2ḌP€ċ“D*L$S⁼”v€TX

Try it online!

Returns 1 for Mersenne, 2 for Germain, 3 for Perfect, 4 for Vampire, 5 for Narcissistic and 0 for False. Returns random in case many are true.

\$\endgroup\$
2
\$\begingroup\$

05AB1E, 51 bytes

"p¹p* "D">2.nDîpsïÿ<;ÿѨOQ œε2ä}P¹å s¹gmOQ"#ε.V}ā*à

Try it online!

Returns 1 for Mersenne, 2 for Germain, 3 for Perfect, 4 for Vampire, 5 for Narcissistic and 0 for False. Returns max in case many are true.

\$\endgroup\$
  • \$\begingroup\$ Lo<så to check if it is a power of 2 - 1. \$\endgroup\$ – Okx Sep 1 '17 at 16:53
1
\$\begingroup\$

Python 2, 292 286 274 bytes

-2 bytes thanks to @Okx
-4 bytes thanks to @Mr.Xcoder

lambda n:[n&-~n<a(n),a(n)&a(2*n+1),sum(k*(n%k<1)for k in range(1,n))==n,any(len(c)%2<1<n==int(j(c[::2]))*int(j(c[1::2]))for c in permutations(`n`)),sum(int(d)**len(`n`)for d in`n`)==n,1].index(1)
a=lambda n:all(n%k for k in range(2,n))*~-n>0
j=''.join
from itertools import*

Try it online!

Output is 0 for mersenne, 1 for germaine, 2 for perfect, 3 for vampire, 4 for narcissistic and 5 for false.


Ungolfed

from itertools import*
f=lambda n:
  [
    n&-~n == 0 and a(n),                               # Is n a Mersenne prime?         
    a(n) and a(2*n+1),                                 # Is n a Germain prime?
    sum(k for k in range(1,n) if n%k<1)==n,            # Is n a perfect number?
    any(len(c)%2<1<                                    # Is n a vampire number?
      n==int(''.join(c[:len(c)/2]))*int(''.join(c[len(c)/2:]))
      for c in permutations(`n`)),
    sum(int(d)**len(str(n)) for d in str(n))==n,       # Is n a narcissistic number?
    1
  ].index(1)                                           # Get the first position
                                                       # of a 1 (or True) in the list
a=lambda n:False if n<2 else all(n%k for k in range(2,n)) # primality check
\$\endgroup\$
  • \$\begingroup\$ 286 bytes. You had an unneeded space. \$\endgroup\$ – Mr. Xcoder Sep 1 '17 at 18:27
  • \$\begingroup\$ 272 bytes. >0 is redundant in the lambda, as bool is a subclass of int. \$\endgroup\$ – Mr. Xcoder Sep 2 '17 at 7:06
  • \$\begingroup\$ @Mr.Xcoder An output of 1 is required for the Germain test. Without >0 the code fails to recognise Germain primes. \$\endgroup\$ – ovs Sep 2 '17 at 7:17
  • \$\begingroup\$ @ovs Ok, sorry. I missed that \$\endgroup\$ – Mr. Xcoder Sep 2 '17 at 7:21
0
\$\begingroup\$

Mathematica, 275 bytes

If[!FreeQ[(S=Select)[2^Range@#-1,PrimeQ],#],1,If[!FreeQ[S[Prime@Range@#,PrimeQ[2#+1]&],#],2,If[PerfectNumberQ@#,3,If[!FreeQ[Times@@FromDigits/@#&/@S[Subsets[Tuples[v=(j=IntegerDigits)@#,{(k=IntegerLength)@#/2}],{2}],ContainsAll[Flatten@#,v]&],#],4,If[Tr[j@#^k@#]==#,5,6]]]]]&


thanx to @Mr. Xcoder for letting me know that I don't have to use the string-names!

\$\endgroup\$
  • \$\begingroup\$ Wait how did you post this? It was closed 15 minutes ago. \$\endgroup\$ – caird coinheringaahing Sep 1 '17 at 18:21
  • \$\begingroup\$ @cairdcoinheringaahing Client-side checks. \$\endgroup\$ – Mr. Xcoder Sep 1 '17 at 18:21
  • \$\begingroup\$ 275 bytes: If[!FreeQ[(S=Select)[2^Range@#-1,PrimeQ],#],1,If[!FreeQ[S[Prime@Range@#,PrimeQ[2#+1]&],#],2,If[PerfectNumberQ@#,3,If[!FreeQ[Times@@FromDigits/@#&/@S[Subsets[Tuples[v=(j=IntegerDigits)@#,{(k=IntegerLength)@#/2}],{2}],ContainsAll[Flatten@#,v]&],#],4,If[Tr[j@#^k@#]==#,5,0]]]]]&. You do not have to use the exact strings, you may use any 6 consistent values. \$\endgroup\$ – Mr. Xcoder Sep 1 '17 at 18:24

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