# Am I a Pillai prime?

A Pillai prime is a prime number $p$ for which there exists some positive $m$ such that $(m! + 1) \equiv 0 \:(\text{mod } p)$ and $p \not\equiv 1\:(\text{mod }m)$.

In other words, an integer $p$ is a Pillai prime if it is a prime number, if there exists another positive integer $m$ such that the factorial of $m$, plus $1$ is divisible by $p$ and if $p - 1$ isn't divisible by $m$.

Given a positive integer as input, decide whether it is a Pillai prime. The sequence of Pillai primes is OEIS A063980.

For example, $23$ is a Pillai prime because:

• It is a prime number, having only 2 factors.
• $m = 14$ and $m = 18$ satisfy the above conditions: $23 \mid (14! + 1)$ and $14$ does not divide $22$; $23 \mid (18! + 1)$ and $18$ does not divide $22$ either.

## Test cases

Truthy:

23
59
83
109
139
593


Falsy:

5
7
8
73
89
263
437


For the truthy cases, the respective m's are [(23, [14, 18]), (59, [15, 40, 43]), (83, [13, 36, 69]), (109, ), (139, ), (593, )].

You can either follow the standard output format (that is, truthy / falsy values) or have a consistent value for Pillai primes and a non-consistent value otherwise or vice-versa.

You can compete in any programming language and can take input and provide output through any standard method, while taking note that these loopholes are forbidden by default. This is , so the shortest submission (in bytes) for every language wins.

• Can the input be a composite integer? – JungHwan Min Apr 27 '18 at 17:59
• @JungHwanMin Yes, the input can be a composite integer. – Mr. Xcoder Apr 27 '18 at 18:01
• I suggest a test case like 437, which is composite but divides 18!+1. – Nitrodon Apr 27 '18 at 18:16
• @Nitrodon Added that test case, thank you! – Mr. Xcoder Apr 27 '18 at 18:19
• @DanielIndie Here you go: [(23, 14), (23, 18), (59, 15), (59, 40), (59, 43), (83, 13), (83, 36), (83, 69), (109, 86), (139, 16), (593, 274)]. I've also added them to the challenge. – Mr. Xcoder Apr 27 '18 at 18:39

# Python 2, 115111110 109 bytes

-6 bytes thanks to Mr. Xcoder

lambda n:n>2and cmp(*map(all,zip(*[[n%x==1or~f(x)%n,n%x]for x in range(2,n)])))<0
f=lambda x:0**x or x*f(x-1)


Try it online!

The functions consist of two parts ~-n%x<1or~f(x)%n>0 that verifies if n don't satisfies the "Pillai conditions", and n%x>0 for the prime validation.
After that all is applied to both items, the first item will contain False/0 if there is a valid "Pillai number", and the second will contain True/1 if n is prime.
These are passed to cmp that will return -1 in this cenario (is a valid Pillai prime). The other combinations [[0, 0], [1, 0], [1, 1]] will return 0 or 1

• +1, clever algorithms (and their explanations) are why I love this SE – IanF1 Apr 27 '18 at 20:25

# Pari/GP, 44 bytes

p->isprime(p)&&sum(m=2,p,p%m-1&&!((m!+1)%p))


Try it online!

# Jelly, 11 8 bytes

Ṗ!%ẹ’ḍ’E


Returns 0 for Pillai prime, 1 otherwise.

Try it online!

### How it works

Ṗ!%ẹ’ḍ’E  Main link. Argument: n

Ṗ         Pop; yield [1, ..., n-1].
!        Take the factorial of each integer.
%       Take the factorials modulo p.
ẹ’     Find all indices of n-1.
ḍ’   Test n-1 for divisibility by each of these indices.
E  Return 1 if all of the resulting Booleans are equal (all 1 means there is
no suitable m, all 0 means n is not prime), 0 if they are different.

• That's roughly how I would have done it too, but I didn't manage to prove that m ∈ [1, n). – Erik the Outgolfer Apr 28 '18 at 16:32
• If m ≥ n, then m! is divisble by n, so m! + 1 ≡ 1 (mod n). – Dennis Apr 28 '18 at 22:41

# Brachylog, 19 bytes

ṗ>.ḟ+₁;?%0&-₁;.%>0∧


Try it online!

Pretty straightforward translation of the question:

ṗ          Input is a prime
>.         And output is a number less than the input
ḟ+₁;?%0    And output's factorial + 1 mod input is 0
&-₁;.%>0   And input - 1 mod output is greater than 0
∧          No further constraints


# Python 2, 656453 52 bytes

f=lambda n,k=3,m=2:~m%n<1<n%k%(n%~-k)or f(n,k+1,m*k)


Output is via presence or absence of an error.

Try it online!

# Python 2, 109 107 bytes

lambda p:any(~-p%m>~l(m)%p<1for m in range(2,p))*all(p%i for i in range(2,p-1))
l=lambda a:0**a or a*l(a-1)


Try it online!

Explanation

The l finds the factorial of the number passed in, so 5 as input returns 120.

The all(p%i for i in range(2,p-1)) checks to see if a number is prime, we ignore 0 and 1 as our other conditions already rule those out.

Finally, we use any(~-p%m>-~l(m)%p==0for m in range(2,p)) to iterate through all potential m's looking to see if any satisfies our needs. ~-p means p+1. Then we check to see if it is greater than -~l(m)%p (which translates to (m!-1)%p, and then we compare it to 0. Basically ~-p%m must be greater than 0 and -~l(m)%p must be 0.

Sources

Improvements

# J, 30 26 bytes

-4 bytes thanks to FrownyFrog

1 e.i.((|1+!)~<1~:|)1&p:*]


Try it online!

## Explanation:

                        1&p:*]      checks if the number is prime and if not sets it to 0
1~:|             checks if p is not 1 mod m
(|1+!)~                  m factorial plus 1 modulo n
<                 are both conditions met?
i.                           generates successive m's (a list 0..n-1)
1 e.                             1's are at the indices of m, so if there's 1 - Pillai

• Check that modulo n is less than 1~:| to save 2 bytes. – FrownyFrog Apr 28 '18 at 8:49
• (]|1+!@[) is just (|1+!)~ – FrownyFrog Apr 28 '18 at 8:51
• @FrownyFrog - Thank you! I was thinking about ~ and it makes sence with your previous comment. – Galen Ivanov Apr 28 '18 at 9:05

### as you probably can see in the tio link not all cases pass, thats because js cant handle big numbers,if such requirement exists ill try to implement it :)

there is a double check F%n>n-2&(F+1)%n<1 to prevent false positive(but not the other way around with js big number issues,we do really need (F+1)%n<1 for smaller numbers whice reduces the solution byte count to 60

# JavaScript (Node.js), 90888672 68 bytes

• thanks to Arnauld for reducing by 1 byte
f=(n,F=i=2,g=0)=>n%i?f(n,F*=++i,g|=F%n>n-2&(F+1)%n<1&~-n%i>0):i==n*g


Try it online!

# [Perl], 45 bytes

use ntheory":all";is_prime($n)&&is_pillai($n)


The number theory module has the predicates as built-in functions (is_pillai actually returns either 0 or the smallest m, so solves A063828 as well). The underlying C and Perl code is not golfed (of course). The C code looks like:

UV pillai_v(UV n) {
UV v, fac = 5040 % n;
if (n == 0) return 0;
for (v = 8; v < n-1 && fac != 0; v++) {
fac = (n < HALF_WORD) ? (fac*v) % n : mulmod(fac,v,n);
if (fac == n-1 && (n % v) != 1)
return v;
}
return 0;
}


(generically replace UV with uint64_t or similar, and HALF_WORD decides whether we can optimize the mulmod into simple native ops).

The pure Perl code is similar to:

sub is_pillai {
my $p = shift; return 0 if$p <= 2;
my($pm1,$nfac) = ($p-1, 5040 %$p);
for (my $n = 8;$n < $p;$n++) {
$nfac = mulmod($nfac, $n,$p);
return $n if$nfac == $pm1 && ($p % \$n) != 1;
}
0;
}


# Whispers v2, 230 bytes

> 1
> Input
>> 1…2
>> L!
>> L+1
>> L∣2
>> L⋅R
>> 2%L
>> Each 4 3
>> Each 5 9
>> Each 6 10
>> Each 7 11 3
> {0}
>> 12∖13
>> Each 8 14
>> L≠1
>> Each 16 15
>> Each 7 17 15
>> 18∖13
>> 
>> 2’
>> 21⋅20
>> Output 22


Try it online!

This returns an empty list for non-Pillai primes, and a non-empty list otherwise.

## How it works

Whispers was designed for manipulation on real/complex numbers, with a little bit of array commands added for good measure, hence the repeated use of Each to iterate over the generated lists.

A bit of background on Whispers:

Whispers is slightly different in it's execution path to most other languages. Rather than work through each line linearly, only branching at conditionals, Whispers begins on the last line in the file beginning with > (the rules are slightly more complicated than that, but that's all we need to know for now), and the meanings of numbers differ, depending on whether the line starts with > or >>.

If the line starts with >, such as > 1 or > Input, this is a constant line - it returns the same value each time. Here, numbers represent their numerical form, so the first line will always return 1 when called.

If the line starts with >> however, numbers are treated as references to other lines, sort of like function calls, if you will. For example, in the line >> 1…2, this does not perform the … command on the integers 1 and 2, but rather on the values returned from lines 1 and 2. In this case, those values are the integer 1 and whatever integer we're passed as input.

For this example, let's consider the input of 23. Keep in mind that, due to Whispers' preprocessing, the second line (> Input) is converted to > 23.

Our first command is on line 3: >> 1…2. … is dyadic range, in this case from 1 to 23, yielding {1, 2, ... 22, 23}. Next, we skip down to lines 9 through 12:

>> Each 4 3
>> Each 5 9
>> Each 6 10
>> Each 7 11 3


Here we have 4 consectutive Each statements, each of which iterate over the previous result, essentially mapping the 4 commands over the array on line 3: the range. The first three statements are simple maps, with lines 4, 5 and 6:

>> L!
>> L+1
>> L∣2


These three commands, over an integer n, yields (n!+1)∣x, where ! denotes factorial, denotes divisbility and x is the input. Finally, line 12 has a dyadic map structure.

A dyadic map structure takes three integers: the target, the left and the right, each indexes to other lines. Here, we zip the left and the right to produce a list of pairs, then reduce each pair by the dyadic command (the target). Here, if the input is 23, the lists are {1, 2, ... 22, 23} and {0, 0, ... 1, 0} and the command is

>> L⋅R


which multiplies the left argument by the right. This produces an array of integers, with 0 at the indexes of integers whose factorials incremented aren't divisible by the inputs, and the original index where they are. We'll call this array A. Next, we remove the 0s from A by taking the set difference between {0} and A:

> {0}
>> 12∖13


With our example input, this produces the set {14, 18, 22}. Next we take the remainder of the input being divided by each value in the set, and check if that remainder is not equal to 1:

>> 2%L
>> Each 8 14
>> L≠1
>> Each 16 15


Again, we have a list of either 0 or 1s and need to remove the 0s and replace the 1s with the original values. Here we repeat the code we saw above, but with >> 18∖13 rather than 12. Finally, we cast this resulting set to a list for a final check. Unfortunately, our code must also reject composite numbers which achieve all these criteria, such as 437. So we add our final check, multiplying our final list by the primality of the input. Due to how Python multiplication works on lists, 0 replaces it with an empty list, and 1 has no effect. So we calculate the primality of the input, multiply that by the list of ms for the input and ouput the final result:

>> 2’
>> 21⋅20
>> Output 22


# C (gcc), 64 bytes

f(n,k,m,r){for(k=m=1,r=0;k<n;m=m*++k%n)r|=m/~-n<<(n%k==1);r/=3;}


Try it online!