Perfect, Germain, Vampire, Mersenne! (Don't forget narcissistic)

5

1

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

caird coinheringaahing

Posted 2017-09-01T14:23:01.247

Reputation: 13 702

Question was closed 2017-09-01T18:02:09.167

4We 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. – FryAmTheEggman – 2017-09-01T14:41:57.233

FWIW I, too, think this is a duplicate – H.PWiz – 2017-09-01T15:02:51.503

Is an incorrect answer due to a precision error okay? – Okx – 2017-09-01T15:38:39.460

1Out of curiosity, are there any numbers which fit in more than 1 category? – Socratic Phoenix – 2017-09-01T15:38:47.077

@SocraticPhoenix 3, stated in the challenge. – Okx – 2017-09-01T15:39:03.093

@Okx yes, precision errors do not need to be handled – caird coinheringaahing – 2017-09-01T15:39:20.280

@mathmandan yes, I meant narcissistic. My bad. – Mr. Xcoder – 2017-09-01T16:47:07.893

Answers

3

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!

Okx

Posted 2017-09-01T14:23:01.247

Reputation: 15 025

.²p isn't enough I think, floats are prime in 05AB1E, and may return a float. – Erik the Outgolfer – 2017-09-01T15:41:07.127

@EriktheOutgolfer Fixed. – Okx – 2017-09-01T15:49:42.550

4

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.

Mr. Xcoder

Posted 2017-09-01T14:23:01.247

Reputation: 39 774

2

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.

Erik the Outgolfer

Posted 2017-09-01T14:23:01.247

Reputation: 38 134

2

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.

Erik the Outgolfer

Posted 2017-09-01T14:23:01.247

Reputation: 38 134

Lo<så to check if it is a power of 2 - 1. – Okx – 2017-09-01T16:53:19.143

1

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

ovs

Posted 2017-09-01T14:23:01.247

Reputation: 21 408

286 bytes. You had an unneeded space. – Mr. Xcoder – 2017-09-01T18:27:15.963

272 bytes. >0 is redundant in the lambda, as bool is a subclass of int. – Mr. Xcoder – 2017-09-02T07:06:27.720

@Mr.Xcoder An output of 1 is required for the Germain test. Without >0 the code fails to recognise Germain primes. – ovs – 2017-09-02T07:17:59.150

@ovs Ok, sorry. I missed that – Mr. Xcoder – 2017-09-02T07:21:46.473

0

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!

J42161217

Posted 2017-09-01T14:23:01.247

Reputation: 15 931

Wait how did you post this? It was closed 15 minutes ago. – caird coinheringaahing – 2017-09-01T18:21:31.637

@cairdcoinheringaahing Client-side checks. – Mr. Xcoder – 2017-09-01T18:21:53.007

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. – Mr. Xcoder – 2017-09-01T18:24:27.673