Trouver des nombres pas tout à fait premiers


17

Votre défi, si vous l'acceptez, consiste à coder une fonction qui renvoie vrai ou faux (ou une représentation significative similaire de oui et non) si un nombre répond aux critères suivants:

  1. L'entier lui-même est un nombre premier OU
  2. L'un de ses entiers voisins est premier

Par exemple:
Une entrée de 7renverrait True.
Une entrée de 8renverrait également True.
Une entrée de 15renvoie False. (Ni 14, 15 ou 16 ne sont premiers)

L'entrée doit pouvoir retourner correctement pour les nombres compris entre 2 ^ 0 et 2 ^ 20 inclus, donc il n'y a pas besoin de s'inquiéter des problèmes de signe ou des débordements d'entiers.


Débordements de numéro 32 bits, pas de débordements de tampon, je suppose.
utilisateur inconnu

Oups, signifie "débordement d'entier". Le cerveau est allé sur le pilote automatique.
M. Llama

Réponses:


11

J, 17

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

Renvoie des booléens encodés en codes de retour de processus: zéro pour vrai, différent de zéro pour faux. Exemple d'utilisation:

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

*/0 p:<:,],>:est plus court et une fonction appropriée (lambda) est([:*/0 p:<:,],>:)
randomra

9

Haskell, 47 caractères

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)

Première fois sur Code Golf donc il y a probablement quelques trucs qui me manquent.


Vous pouvez supprimer le fichier []. tous seront plus qu'heureux de travailler avec une expression de générateur. Si cela ne vous dérange pas que votre code soit laid, vous pouvez également supprimer les espaces entre 0et for, et )et or.
stranac

@stranac Awesome. Merci beaucoup.
Kris Harper

3
A fait quelques changements simples, j'espère que cela fonctionne toujours:f=lambda n:any(all(m%i for i in range(2,m))for m in[n,n-1,n+1])
Nabb

@Nabb Très sympa. Bien joué.
Kris Harper

5

Ce n'est pas un vrai candidat à la brièveté du code, mais nous soumettons toujours, car la détermination de la primauté par l'expression régulière est tordue à bien des égards!

Python (2.x), 85 caractères

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

Vous pouvez supprimer la boucle for et l'intégrer dans l'expression rationnelle en testant "1" * (n + 1) mais en commençant par ^ 1? 1? au lieu.
Howard

4

Rubis (55 ou 50 comme lambda)

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

ou comme lambda (utiliser g[23]pour l'appeler)

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> Ce devrait être "proc" et non "lambda" </pedantic> ;-)
Poignée de porte

3

La solution Mathematica ennuyeuse , 35 !

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

15
Au moins, vous pouvez y jouer Or@@PrimeQ/@{n-1,n,n+1}.
Howard

Ce n'est pas une fonction.
Martin Ender

@ MartinBüttner: Je ne connais pas Mathematica, désolé.
Ry-

2
En utilisant la version de Howard, Or@@PrimeQ@{#-1,#,#+1}&(la barre oblique dans son code n'est pas nécessaire)
Martin Ender

3

C, 112 82 72 caractères

Suite au commentaire d'Ilmari Karonen, sauvé 30 caractères en supprimant main, Pretourne maintenant vrai / faux. Boucle également remplacée par récursivité, et quelques ajustements supplémentaires.

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

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

Vous pouvez enregistrer 2 caractères avec main(n,m)int**m;.
Ilmari Karonen

... et en plus, le défi dit "le code-golf est une fonction ".
Ilmari Karonen

3

Mathematica, 24 octets

Je ne sais pas pourquoi cet ancien article est apparu dans ma liste aujourd'hui, mais j'ai réalisé que Mathematica est compétitif ici.

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

Fonction sans nom prenant un argument entier et retournant Trueou False. Mise en œuvre directe.


PrimeQthreads sur les listes, donc Or@@PrimeQ@{#-1,#,#+1}&(ou Or@@PrimeQ[#+{-1,0,1}]&) fonctionne également, pour -1 octet. (Bien que, je suppose que je ne sais pas si PrimeQles listes sont enfilées en 2012.)
Misha Lavrov

3

Stax , 6 octets

Ç▀<╝ºΩ

Exécuter et déboguer

Explication (déballé):

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

Démo: http://jsfiddle.net/ydsxJ/3/

Edit 1: Changez for(i=2;i<j;i++)en for(i=1;++i<j;)(merci @minitech). Convertir l' ifinstruction en ternaire. Déplacé r|=pet p=1à l'extérieur forpour éliminer les accolades intérieures. 7 caractères enregistrés.

Edit 2: Combinez p=1et j++<=nà p=j++<=n, enregistrez 2 caractères (merci @ugoren).


Vous pouvez utiliser for(i=1;++i<j;)au lieu de for(i=2;i<j;i++)pour enregistrer 1 caractère supplémentaire.
Ry-

1
@minitech: !j%ine fonctionnera pas en raison de la priorité. Une alternative de travail est j%i<1.
Nabb

@Nabb: Wow, tu as raison. C'est bête.
Ry-

Et alors p=j++<=n? Si Javascript est comme C ici, cela devrait fonctionner.
ugoren

@ugoren: On dirait que ça a fonctionné, merci!
mellamokb

2

Regex (ECMAScript), 20 octets

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

Essayez-le en ligne!

La version ci-dessus ne gère pas correctement zéro, mais cela ne prend qu'un octet supplémentaire:

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

En bonus supplémentaire, voici une version qui donne une correspondance de retour 1pour un de moins qu'un premier, 2pour un premier et 3pour un de plus qu'un premier:

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

Essayez-le en ligne!


La plage dont la question en parle est "entre 2 ^ 0 et 2 ^ 20" donc 1..2 ^ 20 donc 0 il n'y en a pas ...
RosLuP

@RosLuP C'est exactement pourquoi ma réponse principale est de 20 octets et ne gère pas correctement 0. Je trouve utile d'aller au-delà des spécifications précises de la question et de donner des réponses plus robustes, ainsi que la réponse qui correspond le moins possible aux spécifications de la question.
Deadcode

Parfois, je fais la même chose (écrire un test «inutile») mais cela semble aller à l'encontre de la façon de penser du codegolf, et les gens qui les écrivent ne sont pas considérés comme «sérieux» ...
RosLuP

1
@RosLuP Mais quel est le mal, tant que je donne la réponse minimale comme réponse principale? Et pouvez-vous donner des exemples de personnes qui pensent de cette façon? Je pourrais le comprendre si je donnais ma seule réponse comme étant la réponse robuste, mais je ne le fais pas.
Deadcode

1

C #, 96

Il renvoie -1,0,1 pour vrai, tout le reste est faux.

Toutes les suggestions pour le raccourcir seraient merveilleuses!

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

Forme développée:

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

Je ne suis pas tout à fait sûr, mais je pense que vous pouvez supprimer le if(i==r-1)break;et changer le milieu de la forboucle de i<rà i<r-1. Cela vous ramènerait à 82.
Ciaran_McCarthy

1

GolfScript: 26

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

Explication: le bloc le plus intérieur {.:i,{i\%!},,2=@|\(} détermine si le haut de la pile est premier en vérifiant s'il y a exactement 2 facteurs de moins que le haut de la pile. Il dissocie ensuite cela avec le deuxième élément de la pile, qui contient l'état de voir si un premier a encore été vu. Enfin, il décrémente le nombre en haut de la pile.

Commencez par incrémenter l'entrée, en initialisant l'état premier vu, et répétez le bloc 3 fois. Comme cela va décrémenter deux fois, mais nous avons commencé par incrémenter, cela couvrira n+1et n-1.


1

C #, 87 97 caractères

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

Je ne pense pas que cela fonctionne avec 1 ou 2 en entrée
Ben Reich

@BenReich Ce n'est pas le cas. J'ai dû ajouter dix caractères pour le réparer :(
Steve Clanton

1

CJam, 12 octets

CJam est beaucoup plus jeune que ce défi, donc cette réponse n'est pas éligible pour la coche verte (qui devrait être mise à jour de toute façon pour la réponse de randomra). Cependant, jouer au golf était en fait assez amusant - j'ai commencé à 17 octets, puis j'ai changé complètement d'approche trois fois, économisant un ou deux octets à chaque fois.

{(3,f+:mp:|}

Il s'agit d'un bloc, l'équivalent le plus proche d'une fonction dans CJam, qui attend l'entrée sur la pile et laisse un 1 (vrai) ou 0 (faux) sur la pile.

Testez-le ici.

Voici comment cela fonctionne:

(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 octets (non concurrents)

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

Essayez-le en ligne!

C'est pourquoi j'aime le golf à code. Je suis toujours très vert avec F # mais j'apprends beaucoup sur le fonctionnement du langage et ce qu'il peut faire de ce genre de défis.


Pourquoi est-ce non concurrentiel?
Nit

1
Parce que je ne sais pas si j'utilise aujourd'hui en F # quelque chose qui n'existait pas lorsque la question a été posée en 2012. J'avoue que c'est pédant - même paranoïaque. Mais j'écris des logiciels pharmaceutiques pour vivre. La paranoïa est saine. ;)
Ciaran_McCarthy

1
Regardez le tableau des versions de F # sur Wikipedia . Selon la version dont vous avez besoin, elle peut être plus ancienne que la question.



1

Java 8, 83 octets

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

Renvoie true/ en falsetant que valeurs véridiques / falsey.

Essayez-le en ligne.

Explication: "

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

Il int p(int n)en résultera donc -1pour n=0et non premiers, et se traduira par n-1pour n=1ou premiers. Puisque p(0)+p(1)+p(2)deviendra -1+0+1 = 0et retournerait faux (même si 2c'est un nombre premier), len=1 c'est un cas de bord utilisant cette approche.


Une boucle unique sans méthode séparée ferait 85 octets :

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

Retour 1/ en 0tant que valeurs véridiques / falsey.

Essayez-le en ligne.

Explication:

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 caractères

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

Utilisation (1 pour VRAI, 0 pour FAUX):

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

1
Je ne sais pas vraiment comment R fonctionne, mais pourriez-vous simplement faire à la i(n-1)|i(n)|i(n+1)place de ifelse(i(n-1)|i(n)|i(n+1),1,0)?
Ry-

Vous avez raison: g = fonction (n) {bibliothèque (gmp); i = isprime; i (n-1) | i (n) | i (n + 1)} - jusqu'à 56 caractères! ;-)
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";

Bienvenue sur CodeGold.SE. Si vous regardez les autres réponses, vous remarquerez un format commun utilisé pour les réponses aux questions [code-golf]. Vous pouvez également l'appliquer à vos réponses.
dmckee

0

Q, 43 caractères 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 caractères

   (_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 caractères

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

8**7 > 2**20 tout en étant un peu plus court à écrire



0

C ++ 97

ugoren semble m'avoir battu vers la solution intelligente. Il est donc une version abrégée de l'approche en boucle à trois reprises:

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 octets

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

Essayez-le en ligne!

Explication

Chèque principal (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

Fonction 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

Gelée , 5 octets

‘r’ẒẸ

Essayez-le en ligne!

Comment ça fonctionne

‘r’ẒẸ    Monadic main link. Input: integer n
‘r’      Generate range n-1..n+1
   ẒẸ    Is any of them a prime?
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.