Nicht ganz richtige Primzahlen finden

17

Ihre Herausforderung besteht darin, eine Funktion mit Code-Golf zu akzeptieren, die true oder false (oder eine ähnliche aussagekräftige Darstellung von yes und no) zurückgibt, wenn eine Zahl die folgenden Kriterien erfüllt:

  1. Die ganze Zahl selbst ist eine Primzahl ODER
  2. Jede seiner Nachbar-Ganzzahlen ist eine Primzahl

Zum Beispiel:
Eine Eingabe von 7würde True zurückgeben.
Eine Eingabe von 8würde auch True zurückgeben.
Eine Eingabe von 15würde False zurückgeben. (Weder 14, 15 noch 16 sind Primzahlen)

Die Eingabe muss für Zahlen zwischen 2 ^ 0 und 2 ^ 20 korrekt zurückgegeben werden können, damit Sie sich keine Gedanken über Vorzeichenprobleme oder Ganzzahlüberläufe machen müssen.

Herr Lama
quelle
32-Bit-Überläufe, keine Pufferüberläufe, denke ich.
Benutzer unbekannt
Hoppla, meinte "Integer Overflow". Brain schaltete den Autopiloten ein.
Mr. Llama

Antworten:

11

J, 17

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

Gibt Boolesche Werte zurück, die als Prozessrückgabecodes codiert sind: null für wahr, ungleich null für falsch. Beispielgebrauch:

   */<:$&q:(<:,],>:) 7
0
   */<:$&q:(<:,],>:) 8
0
   */<:$&q:(<:,],>:) 15
3
JB
quelle
*/0 p:<:,],>:ist kürzer und eine richtige (Lambda) -Funktion ist([:*/0 p:<:,],>:)
randomra
9

Haskell, 47 Zeichen

f n=any(\k->all((>0).mod k)[2..k-1])[n-1..n+1]
Hammar
quelle
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)

Zum ersten Mal bei Code Golf, daher fehlen mir wahrscheinlich einige Tricks.

Kris Harper
quelle
Sie können die entfernen []. Alle werden mehr als glücklich sein, mit einem Generatorausdruck zu arbeiten. Wenn es Ihnen nichts ausmacht, dass Ihr Code hässlich ist, können Sie auch die Leerzeichen zwischen 0und for, und )und entfernen or.
Stranac
@ Stranac Super. Vielen Dank.
Kris Harper
3
Ein paar einfache Änderungen vorgenommen, hoffentlich funktioniert es immer noch:f=lambda n:any(all(m%i for i in range(2,m))for m in[n,n-1,n+1])
Nabb
@Nabb Sehr schön. Gut gemacht.
Kris Harper
5

Kein wirklicher Konkurrent in Sachen Code-Kürze, aber dennoch unterwerfend, da die Bestimmung der Primzahl durch regulären Ausdruck in vielerlei Hinsicht verdreht ist!

Python (2.x), 85 Zeichen

import re
f=lambda n:any(not re.match(r"^1?$|^(11+?)\1+$","1"*x)for x in[n,n-1,n+1])
ChristopheD
quelle
Sie können die for-Schleife entfernen und in den regulären Ausdruck einbauen, indem Sie "1" * (n + 1) testen, aber mit ^ 1? 1? stattdessen.
Howard
4

Ruby (55 oder 50 als Lambda)

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

oder als lambda (benutze g[23]es um es zu nennen)

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

Kaffeeskript (53)

p=(q)->[q-1..q+1].some (n)->[2..n-1].every (d)->n%d>0
jsvnm
quelle
<pedantic> Es sollte "proc" sein, nicht "lambda" </ pedantic> ;-)
Türklinke
3

Die langweilige Mathematica, 35- Lösung!

PrimeQ[n-1]||PrimeQ[n]||PrimeQ[n+1]
Ry-
quelle
15
Zumindest können Sie es in Golf spielen Or@@PrimeQ/@{n-1,n,n+1}.
Howard
Dies ist keine Funktion.
Martin Ender
@ MartinBüttner: Ich kenne Mathematica nicht, sorry.
Ry
2
Mit Howards Version Or@@PrimeQ@{#-1,#,#+1}&(der Schrägstrich in seinem Code ist nicht erforderlich)
Martin Ender
3

C 112 82 72 Zeichen

Nach dem Kommentar von Ilmari Karonen, der durch das Entfernen 30 Zeichen gespart hat main, wird nun Ptrue / false zurückgegeben. Außerdem wurde die Schleife durch Rekursion und einige weitere Verbesserungen ersetzt.

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

Originalfassung:

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));}
ugoren
quelle
Sie könnten mit 2 Zeichen sparen main(n,m)int**m;.
Ilmari Karonen
... und außerdem lautet die Herausforderung "Code-Golf eine Funktion ".
Ilmari Karonen
3

Mathematica, 24 Bytes

Ich weiß nicht, warum dieser alte Beitrag heute in meiner Liste auftauchte, aber ich erkannte, dass Mathematica hier wettbewerbsfähig ist.

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

Unbenannte Funktion, die ein ganzzahliges Argument verwendet und Trueoder zurückgibt False. Direkte Umsetzung.

Greg Martin
quelle
PrimeQThreads über Listen, so Or@@PrimeQ@{#-1,#,#+1}&(oder Or@@PrimeQ[#+{-1,0,1}]&) funktioniert auch, für -1 Byte. (Obwohl ich glaube, ich weiß nicht, ob 2012 PrimeQüber Listen gefädelt wurde.)
Mischa Lawrow
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: Wechsle for(i=2;i<j;i++)zu for(i=1;++i<j;)(danke @minitech). ifAnweisung in ternär umwandeln . Verschoben r|=pund p=1in äußere for, um innere Zahnspangen zu beseitigen. 7 Zeichen gespeichert.

Edit 2: Kombiniere p=1und j++<=num p=j++<=n, speichere 2 Zeichen (danke @ugoren).

mellamokb
quelle
Sie können for(i=1;++i<j;)anstelle von for(i=2;i<j;i++)1 weiteres Zeichen speichern.
Ry
1
@minitech: Funktioniert aus Gründen !j%ider Rangfolge nicht. Eine funktionierende Alternative ist j%i<1.
Nabb
@Nabb: Wow, du hast recht. Das ist dumm.
Ry
Wie wäre es p=j++<=n? Wenn Javascript hier wie C ist, sollte es funktionieren.
Ugoren
@ugoren: Sieht so aus, als hätte es funktioniert, danke!
Mellamokb
2

Regex (ECMAScript), 20 Bytes

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

Probieren Sie es online!

Die obige Version behandelt Null nicht richtig, aber das benötigt nur 1 zusätzliches Byte:

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

Als zusätzlichen Bonus gibt es hier eine Version, die eine Rendite von 1eins weniger als einer Primzahl, 2für eine Primzahl und 3für eine mehr als eine Primzahl ergibt :

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

Probieren Sie es online!

Deadcode
quelle
Der Bereich, über den die Frage spricht, ist "zwischen 2 ^ 0 und 2 ^ 20", also 1..2 ^ 20, also 0 gibt es nicht ...
RosLuP
@RosLuP Genau deshalb ist meine primäre Antwort 20 Bytes und behandelt 0 nicht richtig. Ich finde es wertvoll, über die genauen Spezifikationen der Frage hinauszugehen und robustere Antworten zu geben, zusammen mit der Antwort, die der Spezifikation der Frage minimal entspricht.
Deadcode
Manchmal mache ich das Gleiche (schreibe "unnötigen" Test), aber dies scheint gegen die Codegolf-Denkweise zu verstoßen, und Leute, die sie schreiben, werden nicht als "ernst" angesehen ...
RosLuP
1
@RosLuP Aber was ist der Schaden, solange ich die minimale Antwort als meine primäre Antwort gebe? Und können Sie Beispiele für Menschen nennen, die tatsächlich so denken? Ich könnte es verstehen, wenn ich meine einzige Antwort als die robuste geben würde, aber das tue ich nicht.
Deadcode
1

C # 96

Es gibt -1,0,1 für wahr zurück, alles andere ist falsch.

Vorschläge, um es kürzer zu machen, wären wunderbar!

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

Erweiterte Form:

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;     
}
Müsli
quelle
Ich bin nicht ganz sicher, aber ich denke, Sie könnten die entfernen if(i==r-1)break;und die Mitte der forSchleife von i<rauf ändern i<r-1. Es würde Sie auf 82 bringen.
Ciaran_McCarthy
1

GolfScript: 26

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

Erläuterung: Der innerste Block {.:i,{i\%!},,2=@|\(}bestimmt, ob die Oberseite des Stapels prim ist, indem überprüft wird, ob genau zwei Faktoren kleiner als die Oberseite des Stapels sind. Dies wird dann mit dem zweiten Gegenstand auf dem Stapel getrennt, der den Zustand enthält, ob ein Prime noch gesehen wurde. Schließlich wird die Zahl oben auf dem Stapel dekrementiert.

Beginnen Sie, indem Sie den Eingang inkrementieren, den primären Status initialisieren und den Block dreimal wiederholen. Da diese zweimal verringern, aber wir begannen durch Erhöhen, wird diese Abdeckung n+1und n-1.

Ben Reich
quelle
1

C #, 87 97 Zeichen

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));}
Steve Clanton
quelle
Ich glaube nicht, dass dies mit 1 oder 2 als Eingabe funktioniert
Ben Reich
@BenReich Hat es nicht. Ich musste zehn Zeichen hinzufügen, um das Problem zu beheben :(
Steve Clanton
1

CJam, 12 Bytes

CJam ist viel jünger als diese Herausforderung, daher ist diese Antwort nicht für das grüne Häkchen geeignet (das ohnehin auf die zufällige Antwort aktualisiert werden sollte). Das Golfen hat Spaß gemacht - ich habe mit 17 Bytes angefangen und dann meine Herangehensweise dreimal komplett geändert, wobei ich jeweils ein oder zwei Bytes gespart habe.

{(3,f+:mp:|}

Dies ist ein Block, der einer Funktion in CJam am nächsten kommt, die die Eingabe auf dem Stapel erwartet und eine 1 (wahr) oder 0 (falsch) auf dem Stapel hinterlässt.

Teste es hier.

So funktioniert es:

(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.";
Martin Ender
quelle
1

F #, 68 Bytes (nicht konkurrierend)

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

Probieren Sie es online!

Deshalb liebe ich Codegolf. Ich bin immer noch sehr grün mit F #, aber ich lerne so viel darüber, wie die Sprache funktioniert und was sie aus solchen Herausforderungen machen kann.

Ciaran_McCarthy
quelle
Warum ist es nicht konkurrierend?
Nit
1
Weil ich nicht sicher bin, ob ich heute etwas in F # verwende, das es nicht gab, als die Frage 2012 gestellt wurde. Ich gebe zu, es ist pedantisch - sogar paranoid. Aber ich schreibe pharmazeutische Software für den Lebensunterhalt. Paranoia ist gesund. ;)
Ciaran_McCarthy
1
Schauen Sie sich die Versionstabelle von F # in Wikipedia an . Je nachdem, welche Version Sie benötigen, ist sie möglicherweise älter als die Frage.
1

Java 8, 83 Bytes

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

Gibt true/ falseals wahrheitsgemäße / falsche Werte zurück.

Probieren Sie es online aus.

Erläuterung: "

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

So int p(int n)führt in -1für n=0und nicht-Primzahlen und wird in Folge n-1für n=1oder Primzahlen. Da p(0)+p(1)+p(2)wird -1+0+1 = 0und würde falsch (auch wenn 2es sich um eine Primzahl handelt), n=1ist das ein Randfall mit diesem Ansatz.


Eine einzelne Schleife ohne getrennte Methode wäre 85 Bytes :

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

Gibt 1/ 0als wahrheitsgemäße / falsche Werte zurück.

Probieren Sie es online aus.

Erläuterung:

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)
Kevin Cruijssen
quelle
1

Japt , 7 Bytes

´Uô2 dj
´Uô2    // Given the range [U-1..U+1],
     dj // sing "Daddy DJ", uh, I mean, check if any are a prime.

Probieren Sie es online!

Nit
quelle
0

R 68 Zeichen

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

Verwendung (1 für WAHR, 0 für FALSCH):

f(7)
[1] 1
f(8)
[1] 1
f(15)
[1] 0
Paolo
quelle
1
Ich weiß nicht wirklich, wie R funktioniert, aber könntest du es einfach tun i(n-1)|i(n)|i(n+1)anstatt ifelse(i(n-1)|i(n)|i(n+1),1,0)?
Ry-
Sie haben Recht: g = function (n) {library (gmp); i = isprime; i (n-1) | i (n) | i (n + 1)} - bis zu 56 Zeichen! ;-)
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";
ajobdesh
quelle
Willkommen bei CodeGold.SE. Wenn Sie sich die anderen Antworten ansehen, werden Sie feststellen, dass ein allgemeines Format für die Beantwortung von [Code-Golf] -Fragen verwendet wird. Vielleicht möchten Sie es auch auf Ihre Antworten anwenden.
dmckee
0

Q, 43 Zeichen 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}
tmartin
quelle
0

J, 16 Zeichen

   (_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
randomra
quelle
0

Python, 69 67 Zeichen

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

8**7 > 2**20 während etwas kürzer zu schreiben

Valentin CLEMENT
quelle
0

Ruby, 47 Zeichen, aber sehr gut lesbar

require'Prime'
f=->x{[x-1,x,x+1].any? &:prime?}
Türknauf
quelle
0

C ++ 97

ugoren scheint mich auf die clevere lösung geschlagen zu haben. Er ist also eine kürzere Version des dreifachen Ansatzes:

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);}
Nathan Cooper
quelle
0

Viertens (gviertens) , 104 Bytes

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

Probieren Sie es online!

Erläuterung

Prime Check (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

Hauptfunktion (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)
reffu
quelle
0

Gelee , 5 Bytes

‘r’ẒẸ

Probieren Sie es online!

Wie es funktioniert

‘r’ẒẸ    Monadic main link. Input: integer n
‘r’      Generate range n-1..n+1
   ẒẸ    Is any of them a prime?
Bubbler
quelle