Sono un Pillai prime?


14

Un numero primo di Pillai è un numero primo per cui esiste qualche m positivo tale che ( m ! + 1 ) 0pm(m!+1)0(mod p)p1(mod m)

In altre parole, un numero intero è un numero primo di Pillai se è un numero primo , se esiste un altro numero intero positivo tale che il fattoriale di , più è divisibile perpm 1 p p - 1 mmm1p e se non è divisibile per .p1m


Dato un numero intero positivo come input, decidi se si tratta di un numero primo di Pillai. La sequenza dei numeri primi di Pillai è OEIS A063980 .

Ad esempio, è un numero primo di Pillai perché:23

  • È un numero primo, con solo 2 fattori.
  • e m = 18 soddisfano le condizioni di cui sopra: 23 ( 14 ! + 1 ) e 14 non divide 22 ; 23 ( 18 ! + 1 ) e 18 non dividononemmeno 22 .m=14m=1823(14!+1)142223(18!+1)1822

Casi test

Truthy:

23
59
83
109
139
593

Falsy:

5
7
8
73
89
263
437

Per i casi veritieri, le rispettive m sono [(23, [14, 18]), (59, [15, 40, 43]), (83, [13, 36, 69]), (109, [86]), (139, [16]), (593, [274])].


Puoi seguire il formato di output standard (ovvero valori di verità / falsità) o avere un valore coerente per i numeri primi di Pillai e un valore non coerente in caso contrario o viceversa .

Puoi competere in qualsiasi linguaggio di programmazione e puoi prendere input e fornire output attraverso qualsiasi metodo standard , tenendo presente che queste scappatoie sono vietate per impostazione predefinita. Questo è , quindi vince l'invio più breve (in byte) per ogni lingua .


L'input può essere un numero intero composito?
JungHwan Min

@JungHwanMin Sì, l'input può essere un numero intero composito.
Mr. Xcoder,

Suggerisco un caso di prova come 437, che è composito ma divide 18! +1.
Nitrodon,

@Nitrodon Aggiunto quel test, grazie!
Mr. Xcoder,

1
@DanielIndie Qui si va: [(23, 14), (23, 18), (59, 15), (59, 40), (59, 43), (83, 13), (83, 36), (83, 69), (109, 86), (139, 16), (593, 274)]. Li ho anche aggiunti alla sfida.
Mr. Xcoder,

Risposte:


9

Python 2 , 115 111 110 109 byte

-6 byte grazie a 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)

Provalo online!

Le funzioni sono composte da due parti ~-n%x<1or~f(x)%n>0 che verificano se n non soddisfano le "condizioni di Pillai" e n%x>0per la convalida primaria.
Dopo di che allviene applicato a entrambi gli elementi, il primo elemento conterrà False/ 0se v'è una valida "numero di Pillai", e il secondo conterrà True/ 1se nè primo.
Questi sono passati a cmpquello che tornerà -1in questo cenario (è un primo Pillai valido). Le altre combinazioni [[0, 0], [1, 0], [1, 1]]restituiranno 0o1


2
+1, algoritmi intelligenti (e loro spiegazioni) sono il motivo per cui adoro questo SE
IanF1

8

Gelatina , 11 8 byte

Ṗ!%ẹ’ḍ’E

Restituisce 0 per Pillai prime, 1 altrimenti.

Provalo online!

Come funziona

Ṗ!%ẹ’ḍ’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.

1
È più o meno come l'avrei fatto anche io, ma non sono riuscito a dimostrare che m ∈ [1, n) .
Erik the Outgolfer,

4
Se m ≥ n , quindi m! è divisibile per n , quindi m! + 1 ≡ 1 (mod n) .
Dennis,


5

Brachylog , 19 byte

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

Provalo online!

Traduzione abbastanza semplice della domanda:

ṗ          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

3

J , 30 26 byte

-4 byte grazie a FrownyFrog

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

Provalo online!

Spiegazione:

                        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

1
Verificare che modulo n sia inferiore a 1~:|per salvare 2 byte.
FrownyFrog,

1
(]|1+!@[)è solo(|1+!)~
FrownyFrog

@FrownyFrog - Grazie! Ci stavo pensando ~ed è evidente con il tuo commento precedente.
Galen Ivanov,


2

Python 2 , 109 107 byte

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)

Provalo online!


Spiegazione

Il ltrova il fattoriale del numero passato, così 5come l'input ritorna 120.

I all(p%i for i in range(2,p-1))controlli per vedere se un numero è primo, ignoriamo 0 e 1 poiché le altre nostre condizioni già li escludono.

Infine, usiamo any(~-p%m>-~l(m)%p==0for m in range(2,p))per scorrere tutte le potenziali m cercando di vedere se qualcuno soddisfa i nostri bisogni. ~-psignifica p+1. Quindi controlliamo per vedere se è maggiore di -~l(m)%p(che si traduce in (m!-1)%p, e quindi lo confrontiamo con 0. Fondamentalmente ~-p%mdeve essere maggiore di 0 e -~l(m)%pdeve essere 0.


fonti


miglioramenti


2

come probabilmente vedrai nel link tio, non tutti i casi passano, questo perché js non può gestire grandi numeri, se tale requisito esiste malato, cerca di implementarlo :)

c'è un doppio controllo F%n>n-2&(F+1)%n<1per prevenire falsi positivi (ma non viceversa con problemi di numeri grandi di js, abbiamo davvero bisogno (F+1)%n<1di numeri più piccoli che riducono il numero di byte della soluzione a 60

JavaScript (Node.js) , 90 88 86 72 68 byte

  • grazie ad Arnauld per la riduzione di 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

Provalo online!


2

Brachylog , 13 byte

>.ḟ+₁ḋ∋?-₁f≡ⁿ

Provalo online!

Ha successo per i numeri primi di Pillai, fornendo la m più piccola attraverso la variabile di output e non riesce per qualsiasi altra cosa. Dal momento che gran parte del modo in cui questo salva byte sulla soluzione di Sundar è che calcola ripetutamente le prime fattorizzazioni di alcuni numeri piuttosto grandi, è piuttosto incredibilmente lento su input più grandi. (Probabilmente eseguirò quei casi sulla mia installazione locale di Brachylog quando il mio laptop non è alimentato a batteria.)

 .               The output
>                is less than the input,
       ?         the input
      ∋          is an element of
     ḋ           the prime factorization of
 .               the output's
  ḟ              factorial
   +₁            plus one,
           ≡ⁿ    and the output is not an element of
          f      the list of all factors of
       ?         the input
        -₁       minus one.

1

[Perl], 45 byte

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

Il modulo di teoria dei numeri ha i predicati come funzioni integrate (is_pillai in realtà restituisce 0 o la m più piccola, quindi risolve anche A063828). Il codice C e Perl sottostante non è golfato (ovviamente). Il codice C appare come:

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;
}

(sostituisci genericamente UV con uint64_t o simili e HALF_WORD decide se possiamo ottimizzare il mulmod in semplici operazioni native).

Il codice Perl puro è simile a:

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;
}


1

Sussurri v2 , 230 byte

> 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
>> [19]
>> 2’
>> 21⋅20
>> Output 22

Provalo online!

Ciò restituisce un elenco vuoto per numeri primi non Pillai e un elenco non vuoto in caso contrario.

Come funziona

Whispers è stato progettato per essere manipolato su numeri reali / complessi, con un po 'di comandi di array aggiunti per una buona misura, quindi l'uso ripetuto di Eachiterare sugli elenchi generati.

Un po 'di background su Whispers:

Whispers è leggermente diverso nel suo percorso di esecuzione rispetto alla maggior parte delle altre lingue. Invece di lavorare su ogni riga in modo lineare, ramificando solo i condizionali, Whispers inizia sull'ultima riga del file che inizia con >(le regole sono leggermente più complicate di così, ma per ora è tutto ciò che dobbiamo sapere), e il significato dei numeri differiscono, a seconda che la linea inizi con >o >>.

Se la linea inizia con >, come > 1o > Input, si tratta di una linea costante : restituisce lo stesso valore ogni volta. Qui, i numeri rappresentano la loro forma numerica, quindi la prima riga restituirà sempre 1 quando viene chiamata.

Se la linea inizia con >>, tuttavia, i numeri vengono trattati come riferimenti ad altre linee, una sorta di chiamate di funzione simili, se lo desideri. Ad esempio, nella riga >> 1…2, questo non esegue il comando sugli interi 1 e 2 , ma piuttosto sui valori restituiti dalle righe 1 e 2 . In questo caso, quei valori sono il numero intero 1 e qualunque numero intero siamo passati come input.

Per questo esempio, consideriamo l'input di 23 . Tieni presente che, a causa della preelaborazione di Whispers, la seconda riga ( > Input) viene convertita in > 23.

Il nostro primo comando è sulla linea 3: >> 1…2. è intervallo diadico, in questo caso da 1 a 23 , producendo {1, 2, ... 22, 23} . Quindi, passiamo alle righe da 9 a 12 :

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

Qui abbiamo 4 Eachaffermazioni consecutive , ognuna delle quali scorre sul risultato precedente, essenzialmente mappando i 4 comandi sull'array sulla linea 3 : l'intervallo. Le prime tre affermazioni sono mappe semplici, con le linee 4 , 5 e 6 :

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

Questi tre comandi, su un numero intero n , producono (n! +1) ∣x , dove ! indica fattoriale , indica divisibilità e x è l'input. Infine, la linea 12 ha una struttura di mappa diadica .

Una struttura di mappa diadica prende tre numeri interi: il bersaglio, il sinistro e il destro, ciascuno si indicizza su altre linee. Qui, comprimiamo la sinistra e la destra per produrre un elenco di coppie, quindi riduciamo ciascuna coppia con il comando diadico (il bersaglio). Qui, se l'ingresso è 23 , le liste sono {1, 2, ... 22, 23} e {0, 0, ... 1, 0} e il comando è

>> L⋅R

che moltiplica l'argomento sinistro per il diritto. Questo produce una matrice di numeri interi, con 0 in corrispondenza degli indici di numeri interi i cui fattoriali incrementati non sono divisibili per gli input e l'indice originale in cui si trovano. Chiameremo questo array A . Quindi, rimuoviamo gli 0 s da A prendendo la differenza impostata tra {0} e A :

> {0}
>> 12∖13

Con il nostro esempio di input, questo produce l'insieme {14, 18, 22} . Quindi prendiamo il resto dell'input diviso per ciascun valore nell'insieme e controlliamo se quel resto non è uguale a 1 :

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

Ancora una volta, abbiamo un elenco di 0 o 1 se dobbiamo rimuovere gli 0 se sostituire gli 1 con i valori originali. Qui ripetiamo il codice che abbiamo visto sopra, ma con >> 18∖13piuttosto che 12. Infine, abbiamo inserito questo set risultante in un elenco per un controllo finale. Sfortunatamente, il nostro codice deve anche rifiutare i numeri compositi che soddisfano tutti questi criteri, come 437 . Quindi aggiungiamo il nostro controllo finale, moltiplicando il nostro elenco finale per la primalità dell'input. A causa del modo in cui la moltiplicazione Python funziona sugli elenchi, 0 lo sostituisce con un elenco vuoto e 1 non ha alcun effetto. Quindi calcoliamo la primalità dell'input, moltiplicandola per l'elenco di ms per l'input e risultato finale:

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

0

APL (NARS), 65 caratteri, 130 byte

{∼0π⍵:0⋄m←⎕ct⋄⎕ct←0⋄r←⍬≢a/⍨{0≠⍵∣p}¨a←k/⍨0=⍵∣1+!k←⍳p←¯1+⍵⋄⎕ct←m⋄r}

Qui 23x significherebbe 23r1 e quindi la frazione 23/1, quindi tutti gli altri; test:

  f←{∼0π⍵:0⋄m←⎕ct⋄⎕ct←0⋄r←⍬≢a/⍨{0≠⍵∣p}¨a←k/⍨0=⍵∣1+!k←⍳p←¯1+⍵⋄⎕ct←m⋄r}
  f¨23x 59x 83x 109x 139x 593x
1 1 1 1 1 1 
  f¨5x 7x 73x 89x 263x 437x
0 0 0 0 0 0 

0

C # (compilatore interattivo Visual C #) , 138 + 22 = 160 byte

n=>Enumerable.Range(2,n-2).All(x=>n%x>0)&Enumerable.Range(1,n).Any(x=>{BigInteger a,b=1;for(a=1;a<=x;a++)b*=a;return(b+1)%n<1&(n-1)%x>0;})

TIO non ha implementato la libreria System.Numerics nella sua versione di Mono, quindi puoi vedere i risultati Provalo online! Qui invece.

Spiegazione:

using System.Numerics; //necessary to handle large numbers created by the factorials

return 
    Enumerable.Range(2,n-2).All(x=>n%x>0)       // is prime
    &
    Enumerable.Range(1,n).Any(x=>
    {
        BigInteger a,b=1;for(a=1;a<=x;a++)b*=a; //b = a!
        return (b+1)%n<1
               &                                //the condition for PPs
               (n-1)%x>0;             
    });

0

CJam , 37 byte

ri_mp\[_{_M)m!)@%!\_M)%1=!@&\}fM]);:|

Emette 11se l'input è un primo pillai, altrimenti 00, 01oppure10

Spiegazione:

                                         e# Explanation | Stack
ri_mp\[_{_M)m!)@%!\_M)%1=!@&\}fM]);:|    e# Whole code | Example input: 593
ri                                       e# Read input as integer | 593
  _                                      e# Duplicate | 593 593
   mp                                    e# Is it prime? | 593 1
     \                                   e# Swap top two stack elements | 1 593
      [                         ]        e# Delimits an array. Any operations that
                                         e# push a value are placed into the array
       _                                 e# Duplicate | 1 593 [593]
        {                    }fM         e# A for loop from 0 to (n-1) looped through
                                         e# variable M
         _                               e# Duplicate top stack value | ...[593 593]
          M)                             e# Get M+1, as if we try M=0 we get an error
                                         e# | ...[593 593 1]
            m!                           e# Factorial | ...[593 593 1]
              )                          e# Add one | ...[593 593 2]
               @                         e# Rotate stack | ...[593 2 593]
                %                        e# Modulus | ...[593 2]
                 !                       e# Equal to 0? | ...[593 0]
                  \_                     e# Swap and duplicate | ...[0 593 593]
                    M)                   e# Push M+1 | ...[0 593 593 1]
                      %                  e# Modulus | ...[0 593 0]
                       1=!               e# Not equal to 1? | ...[0 593 1]
                          @              e# Rotate | ...[593 1 0]
                           &             e# AND | ...[593 0]
                            \            e# Swap | ...[0 593]
                             }     
                                ]
                                 );      e# Dump and discard last element
                                         e# | 1 593 [...]
                                   :|    e# Flatten array with OR | 1 1
                                         e# Implicit output

Provalo online!

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.