Trovare numeri non abbastanza primi


17

La tua sfida, se scegli di accettarla, è quella di codificare il golf in una funzione che restituisce vero o falso (o una simile rappresentazione significativa di sì e no) se un numero soddisfa i seguenti criteri:

  1. L'intero stesso è un numero primo OR
  2. Uno dei numeri interi vicini è primo

Ad esempio:
un input di 7restituisce True.
Un input di 8restituisce anche True.
Un input di 15restituisce False. (Né 14, 15 o 16 sono primi)

L'input deve essere in grado di restituire correttamente i numeri compresi tra 2 ^ 0 e 2 ^ 20 inclusi, quindi non è necessario preoccuparsi di problemi di segno o overflow di numeri interi.


Overflow di numeri a 32 bit, non overflow del buffer, immagino.
utente sconosciuto

Whoops, significa "overflow dei numeri interi". Il cervello ha fatto il pilota automatico.
Mr. Llama,

Risposte:


11

J, 17

*/<:$&q:(<:,],>:)

Restituisce i booleani codificati come codici di ritorno del processo: zero per vero, diverso da zero per falso. Esempio di utilizzo:

   */<:$&q:(<:,],>:) 7
0
   */<:$&q:(<:,],>:) 8
0
   */<:$&q:(<:,],>:) 15
3

*/0 p:<:,],>:è più breve e una funzione (lambda) corretta è([:*/0 p:<:,],>:)
randomra,

9

Haskell, 47 personaggi

f n=any(\k->all((>0).mod k)[2..k-1])[n-1..n+1]

6

Python 85 80

def f(n):g=lambda n:all(n%i!=0for i in range(2,n));return g(n)or g(n-1)or g(n+1)

La prima volta su Code Golf quindi probabilmente mi mancano alcuni trucchi.


È possibile rimuovere il []. tutti saranno più che felici di lavorare con un'espressione generatrice. Se non ti dispiace che il tuo codice sia brutto, puoi anche rimuovere gli spazi tra 0e for, e )e or.
Stranac,

@stranac Fantastico. Grazie mille.
Kris Harper,

3
Ha apportato alcune semplici modifiche, si spera che funzioni ancora:f=lambda n:any(all(m%i for i in range(2,m))for m in[n,n-1,n+1])
Nabb

@Nabb Molto bello. Molto bene.
Kris Harper,

5

Non è un vero contendente nella brevità del codice in alcun modo, ma continua a sottomettersi poiché determinare la primitudine con l'espressione regolare è contorto in molti modi!

Python (2.x), 85 caratteri

import re
f=lambda n:any(not re.match(r"^1?$|^(11+?)\1+$","1"*x)for x in[n,n-1,n+1])

Puoi rimuovere il ciclo for e inserirlo nel regexp testando "1" * (n + 1) ma iniziando con ^ 1? 1? anziché.
Howard,

4

Ruby (55 o 50 come lambda)

def f q;(q-1..q+1).any?{|n|(2..n-1).all?{|d|n%d>0}};end

o come lambda (usare g[23]per chiamarlo)

g=->q{(q-1..q+1).any?{|n|(2..n-1).all?{|d|n%d>0}}}

Coffeescript (53)

p=(q)->[q-1..q+1].some (n)->[2..n-1].every (d)->n%d>0

<pedantic> Dovrebbe essere "proc" non "lambda" </pedantic> ;-)
Maniglia della porta

3

La noiosa Mathematica, la soluzione 35 !

PrimeQ[n-1]||PrimeQ[n]||PrimeQ[n+1]

15
Almeno puoi giocare a golf Or@@PrimeQ/@{n-1,n,n+1}.
Howard,

Questa non è una funzione.
Martin Ender,

@ MartinBüttner: non conosco Mathematica, scusa.
Ry,

2
Usando la versione di Howard Or@@PrimeQ@{#-1,#,#+1}&(non è necessaria la barra nel suo codice)
Martin Ender,

3

C, 112 82 72 caratteri

Dopo il commento di Ilmari Karonen, salvato 30 caratteri rimuovendolo main, ora Prestituisce vero / falso. Ha anche sostituito il loop con la ricorsione e alcune altre modifiche.

p(n,q){return++q==n||n%q&&p(n,q);}P(n){return p(-~n,1)|p(n,1)|p(~-n,1);}

Versione originale:

p(n,q,r){for(r=0,q=2;q<n;)r|=!(n%q++);return!r;}
main(int n,int**m){putchar(48|p(n=atoi(*++m))|p(n-1)|p(n+1));}

Puoi salvare 2 caratteri con main(n,m)int**m;.
Ilmari Karonen,

... e inoltre, la sfida dice "code-golf una funzione ".
Ilmari Karonen,

3

Mathematica, 24 byte

Non so perché questo vecchio post sia comparso nella mia lista oggi, ma ho capito che Mathematica è competitiva qui.

Or@@PrimeQ/@{#-1,#,#+1}&

Funzione senza nome che accetta un argomento intero e restituisce Trueo False. Implementazione diretta.


PrimeQfiltra gli elenchi, quindi Or@@PrimeQ@{#-1,#,#+1}&(o Or@@PrimeQ[#+{-1,0,1}]&) funziona anche per -1 byte. (Anche se, immagino di non sapere se gli PrimeQelenchi siano stati inseriti nel 2012.)
Misha Lavrov,

3

Stax , 6 byte

Ç▀<╝ºΩ

Esegui ed esegui il debug

Spiegazione (non imballata):

;v:Pv<! Full program, implicit input  Example: 7
;v      Copy input and decrement               7 6
  :P    Next prime                             7 7
    v   Decrement                              7 6
     <! Check if input is >= result            1

2

JavaScript (71 73 80 )

n=prompt(r=0);for(j=n-2;p=j++<=n;r|=p)for(i=1;++i<j;)p=j%i?p:0;alert(r)

Demo: http://jsfiddle.net/ydsxJ/3/

Edit 1: Cambiare for(i=2;i<j;i++)per for(i=1;++i<j;)(grazie @minitech). Converti ifistruzione in ternario. Spostato r|=pep=1 verso l'esterno forper eliminare le parentesi graffe interne. Salvati 7 caratteri.

Modifica 2: Combina p=1e j++<=nto p=j++<=n, salva 2 caratteri (grazie @ugoren).


Puoi usare for(i=1;++i<j;)invece di for(i=2;i<j;i++)salvare un altro personaggio.
Ry,

1
@minitech: !j%inon funzionerà a causa della precedenza. Un'alternativa di lavoro è j%i<1.
Nabb,

@Nabb: Wow, hai ragione. È sciocco.
Ry,

Che ne dici p=j++<=n? Se Javascript è come C qui, dovrebbe funzionare.
ugoren,

@ugoren: sembra che abbia funzionato, grazie!
mellamokb,

2

Regex (ECMAScript), 20 byte

^x?x?(?!(x+)(x\1)+$)

Provalo online!

La versione precedente non gestisce correttamente zero, ma richiede solo 1 byte aggiuntivo:

^x?x?(?!(x+)(x\1)+$)x

Come bonus aggiuntivo, ecco una versione che fornisce una corrispondenza di ritorno 1per uno in meno di un numero primo, 2per un numero primo e 3per uno in più di un numero primo:

^x?x??(?!(x+)(x\1)+$)x

Provalo online!


L'intervallo di cui parla la domanda è "tra 2 ^ 0 e 2 ^ 20" quindi 1..2 ^ 20 quindi 0 non c'è ...
RosLuP

@RosLuP Questo è esattamente il motivo per cui la mia risposta principale è di 20 byte e non gestisce correttamente 0. Trovo valore andando oltre le specifiche precise della domanda e dando risposte più solide, insieme alla risposta che corrisponde minimamente alle specifiche della domanda.
Deadcode

A volte faccio lo stesso (scrivo test "non necessari") ma questo sembra andare contro il modo di pensare di codegolf, e le persone che li scrivono non sono considerate "serie" ...
RosLuP

1
@RosLuP Ma qual è il danno, purché fornisca la risposta minima come risposta principale? E puoi fare qualche esempio di persone che la pensano davvero in quel modo? Potrei capirlo se avessi dato la mia unica risposta come quella robusta, ma non lo sto facendo.
Deadcode

1

C #, 96

Restituisce -1,0,1 per true, tutto il resto è falso.

Qualsiasi suggerimento per renderlo più breve sarebbe meraviglioso!

int p(int q){var r=q-1;for(var i=2;i<r&r<q+2;i++){if(i==r-1)break;if(r%i==0)r+=i=1;}return r-q;}

Forma estesa:

int p(int q){
    var r=q-1;
    for(var i=2;i<r&r<q+2;i++){
        if(i==r-1)break;
        if(r%i==0)r+=i=1;
    }
    return r-q;     
}

Non ne sono del tutto sicuro, ma penso che potresti rimuovere if(i==r-1)break;e cambiare il centro del forloop da i<ra i<r-1. Ti porterebbe a 82.
Ciaran_McCarthy

1

GolfScript: 26

)0\{.:i,{i\%!},,2=@|\(}3*;

Spiegazione: Il blocco più interno {.:i,{i\%!},,2=@|\(} determina se la parte superiore della pila è primaria verificando se ci sono esattamente 2 fattori in meno rispetto alla parte superiore della pila. Quindi disgiunge questo con il secondo oggetto nello stack, che contiene lo stato di se un primo è stato ancora visto. Infine, decrementa il numero in cima alla pila.

Inizia incrementando l'ingresso, inizializzando lo stato prime-visto e ripeti il ​​blocco 3 volte. Dal momento che questo diminuirà due volte, ma abbiamo iniziato incrementando, questo coprirà n+1e n-1.


1

C #, 87 97 caratteri

bool p(int q){return new[]{q-1,q,q+1}.Any(x=>Enumerable.Range(2,Math.Abs(x-2)).All(y=>x%y!=0));}

Non credo che funzioni con 1 o 2 come input
Ben Reich,

@BenReich No. Ho dovuto aggiungere dieci caratteri per risolverlo :(
Steve Clanton il

1

CJam, 12 byte

CJam è molto più giovane di questa sfida, quindi questa risposta non è ammissibile per il segno di spunta verde (che dovrebbe comunque essere aggiornato alla risposta di randomra). Tuttavia, giocare a golf è stato piuttosto divertente: ho iniziato a 17 byte e poi ho cambiato completamente approccio tre volte, risparmiando uno o due byte ogni volta.

{(3,f+:mp:|}

Questo è un blocco, l'equivalente più vicino a una funzione in CJam, che prevede l'input nello stack e lascia un 1 (verità) o 0 (falsa) nello stack.

Provalo qui.

Ecco come funziona:

(3,f+:mp:|
(          "Decrement the input N.";
 3,        "Push an array [0 1 2].";
   f+      "Add each of those to N-1, to get [N-1 N N+1].";
     :mp   "Test each each element for primality, yielding 0 or 1.";
        :| "Fold bitwise OR onto the list, which gives 1 if any of them was 1.";

1

F #, 68 byte (non concorrenti)

let p n=Seq.forall(fun x->n%x>0){2..n-1}
let m n=p(n-1)||p n||p(n+1)

Provalo online!

Questo è il motivo per cui amo il codice golf. Sono ancora molto ecologico con F # ma imparo molto su come funziona la lingua e su cosa può fare da questo tipo di sfide.


Perché non è in competizione?
Nit

1
Perché non sono sicuro se sto usando qualcosa in F # oggi che non esisteva quando la domanda è stata posta nel 2012. Ammetto che è pedante - anche paranoico. Ma scrivo software farmaceutico per vivere. La paranoia è sana. ;)
Ciaran_McCarthy

1
Guarda la tabella delle versioni di F # in Wikipedia . A seconda della versione di cui hai bisogno, potrebbe essere più vecchia della domanda.



1

Java 8, 83 byte

n->n==1|p(n-1)+p(n)+p(n+1)>0int p(int n){for(int i=2;i<n;n=n%i++<1?0:n);return--n;}

Restituisce true/ falsecome valori di verità / falsità.

Provalo online.

Spiegazione: "

n->                    // Method with integer parameter and boolean return-type
  n==1                 //  Return whether the input is 1 (edge-case)
  |p(n-1)+p(n)+p(n+1)>0//  Or if the sum of `n-1`, `n`, and `n+1` in method `p(n)` is not 0

int p(int n){          // Separated method with integer as both parameter and return-type
  for(int i=2;i<n;     //  Loop `i` in the range [2, `n`)
    n=n%i++<1?         //   If `n` is divisible by `i`
       0               //    Change `n` to 0
      :                //   Else:
       n);             //    Leave `n` as is
                       //  (After the loop `n` is either 0, 1, or unchanged,
                       //   if it's unchanged it's a prime, otherwise not)
  return--n;}          //  Return `n` minus 1

Quindi int p(int n)comporterà -1per n=0e non primi e comporterà n-1per n=1o primi. Dap(0)+p(1)+p(2) diventerà-1+0+1 = 0 e ritornerebbe falso (anche se 2è un numero primo), n=1è un caso limite usare questo approccio.


Sarebbe un singolo ciclo senza metodo separato 85 byte :

n->{int f=0,j=2,i,t;for(;j-->-1;f=t>1?1:f)for(t=n+j,i=2;i<t;t=t%i++<1?0:t);return f;}

ritorna 1/ 0come valori di verità / falsità.

Provalo online.

Spiegazione:

n->{              // Method with integer as both parameter and return-type
  int f=0,        //  Result-integer, starting at 0 (false)
      j=2,i,      //  Index integers
      t;          //  Temp integer
  for(;j-->-1;    //  Loop `j` downwards in range (2, -1]
      f=          //    After every iteration: Change `f` to:
        t>1?      //     If `t` is larger than 1 (`t` is a prime):
         1        //      Change `f` to 1 (true)
        :         //     Else:
         f)       //      Leave `f` the same
    for(t=n+j,    //   Set `t` to `n+j`
        i=2;i<t;  //   Inner loop `i` in the range [2, t)
      t=t%i++<1?  //    If `t` is divisible by `i`:
         0        //     Change `t` to 0
        :         //    Else:
         t);      //     Leave `t` the same
                  //   (If `t` is still the same after this inner loop, it's a prime;
                  //   if it's 0 or 1 instead, it's not a prime)
  return f;}      //  Return the result-integer (either 1/0 for true/false respectively)


0

R, 68 caratteri

f=function(n){library(gmp);i=isprime;ifelse(i(n-1)|i(n)|i(n+1),1,0)}

Utilizzo (1 per VERO, 0 per FALSO):

f(7)
[1] 1
f(8)
[1] 1
f(15)
[1] 0

1
Non so davvero come funzioni la R, ma potresti semplicemente fare i(n-1)|i(n)|i(n+1)invece di ifelse(i(n-1)|i(n)|i(n+1),1,0)?
Ry,

Hai ragione: g = function (n) {library (gmp); i = isprime; i (n-1) | i (n) | i (n + 1)} - fino a 56 caratteri! ;-)
Paolo

0

C ++

k=3;cin>>i;i--;
while(k)
{l[k]=0;
  for(j=2;j<i;j++)
   if(!(i%j))
     l[k]++;
  k--;
  i++;
}
if(!l[1]|!l[2]|!l[3])
     cout<<"1";
else cout<<"0";

Benvenuto in CodeGold.SE. Se guardi le altre risposte noterai un formato comune usato per le risposte alle domande [code-golf]. Potresti voler applicarlo anche alle tue risposte.
Dmckee,

0

Q, 43 caratteri 36

{any min each a mod 2_'til each a:x+-1 0 1}
{any(min')a mod 2_'(til')a:x+-1 0 1}

0

J, 16 caratteri

   (_2&<@-4 p:]-2:)

   (_2&<@-4 p:]-2:) 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
1 1 1 1 1 1 1 1 0 1 1 1 1 1 0 1 1 1 1

0

Python, 69 67 caratteri

any(all(i%j for j in range(2,i))for i in range(input()-1,8**7)[:3])

8**7 > 2**20 pur essendo leggermente più breve da scrivere



0

C ++ 97

ugoren sembra avermi battuto alla soluzione intelligente. Quindi è una versione abbreviata del ciclo che si avvicina tre volte:

P(int k){int j=1;for(int i=2;i<k;){j=k%i++&&j;}return j;}
a(int b){return P(b)|P(b+1)|P(b-1);}

0

Forth (gforth) , 104 byte

: p dup 1 > if 1 over 2 ?do over i mod 0> * loop else 0 then nip ;
: f dup 1- p over 1+ p rot p + + 0< ;

Provalo online!

Spiegazione

Primo controllo (p)

dup 1 > if          \ if number to check if greater than 1
   1 over 2 ?do     \ place a 1 on the stack to act as a boolean and loop from 2 to n
      over i  mod   \ take the modulo of n and i
      0> *          \ check if greater than 0 (not a divisor) and multiply result by boolean
   loop             \ end the loop, result will be -1 if no divisor was found (prime)
else                \ if n is less than 2
   0                \ put 0 on the stack (not prime)
then                \ end the loop
nip                 \ drop n from the stack

Funzione principale (f)

dup 1- p             \ get n-1 and check if prime
over 1+ p            \ get n+1 and check if prime
rot p                \ rotate stack to put n on top and check if prime
+ + 0<               \ add the three results and check if less than 0 (at least 1 was prime)


0

Gelatina , 5 byte

‘r’ẒẸ

Provalo online!

Come funziona

‘r’ẒẸ    Monadic main link. Input: integer n
‘r’      Generate range n-1..n+1
   ẒẸ    Is any of them a prime?
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.