Ist es eine Primzahl? ohne Mathematik [geschlossen]

14

Schreiben Sie ein Programm oder eine Funktion in einer beliebigen Sprache, die angibt, ob die Eingabe eine Primzahl ist.

  • Die Eingabe ist eine Zeichenfolge, die eine natürliche Zahl in der Basis 10 darstellt.
  • Die Ausgabe ist eine der beiden Zeichenfolgen "Prime" oder "Not !!" die die Eingabe korrekt identifiziert.
  • Arithmetische Operatoren, bitweise Operatoren, numerische Variablen und Konstanten, "math-stuff" im Allgemeinen usw. sind an keiner Stelle in Ihrem Programm zulässig. Sie sollten Zeichenfolgenoperationen verwenden , um alle erforderlichen "Berechnungen" durchzuführen .
  • Sie können Stringlängen (Zahlen) vergleichen, aber -10 mit Ihrer Punktzahl, wenn Sie dies nicht tun.
  • Ihr Programm sollte mit Eingaben beliebiger Länge (bei genügend Arbeitsspeicher und Zeit) arbeiten.
  • Die niedrigste Bytezahl (UTF-8) gewinnt.
Wally
quelle
Was sind die Grenzen der Zahl? Kann es negativ sein? Null? Kann es einen Dezimalpunkt enthalten?
Justin
Wenn es Bonuspunkte hat, ist es kein Code-Golf
Peter Taylor
"Natural" hinzugefügt, um Grenzen für die Eingabe festzulegen.
Wally
Ich hatte gehofft, durch eine verrückte, explizite Manipulation von Zeichenfolgen überrascht zu werden (ich habe persönlich darüber nachgedacht, Code zu schreiben, um eine Zeichenfolge zu "dekrementieren", damit ich eine Schleife ausführen kann - und ich war hin- und hergerissen zwischen langer Teilung der Zeichenfolge und wiederholter Zeichenfolgensubtraktion ...), stattdessen ich war überrascht von diesem coolen kleinen Regex unary Prime Matcher! Vielleicht muss ich die Frage erneut stellen, um zu sehen, ob ich noch mehr wundervolle Sachen bekomme? Aber ich glaube nicht, dass irgendetwas der Kürze dieses Regex nahe kommen wird.
Wally
Um "mehr wundervolle Sachen" zu bekommen, könntest du vielleicht versuchen, es zu einem Beliebtheitswettbewerb zu machen . Das Ändern der Frage selbst wird im Allgemeinen jedoch verpönt. Und ich bin mir nicht sicher, ob Sie eine neue Frage stellen oder etwas ändern sollten, nur weil jemand etwas erfunden hat, an das Sie nicht gedacht haben - ich denke, das passiert hier ziemlich oft. Auch Regelbiegen ist Teil des Sports :)
Daniero

Antworten:

7

Ruby, 64 - 10 = 54

puts ('1
'..gets).map{?1}*''=~/^1?$|^(11+?)\1+$/?'Not!!': :Prime

Dies iteriert von der Zeichenfolge '1' (plus einer neuen Zeile) zur Eingabezeichenfolge, wobei Rubys integrierte Zeichenfolgeniterationsmethode verwendet wird, die einer Addition von 1 sehr ähnlich sieht, aber technisch zu keinem Zeitpunkt eine übergeordnete numerische Variable erstellt . Es verwendet die Tatsache, dass es n Iterationen für eine Eingabe von n gibt, um eine Zeichenfolge mit n Längen zu erstellen, und verwendet dann einen regulären Ausdruck, um zu bestimmen, ob diese Zeichenfolge in identische Teilzeichenfolgen gruppiert werden kann.

Histokrat
quelle
Ist die "1" in der "Map {? 1}" ein Fixnum? - Wenn ja, müssen Sie es möglicherweise in "map ('1')" ändern. Ich kann keine Dokumentation zu dem Ausdruck "? 1" finden, außer einigen Hinweisen, dass in älteren Ruby-Versionen ASCII-Codes zurückgegeben wurden und jetzt eine Zeichenfolge zurückgegeben wird .
Wally
? 1 ist dasselbe wie '1', es ist ein 1-Zeichen-Zeichenkettenliteral. Ich könnte alle Instanzen von 1 bis auf die erste durch ein beliebiges anderes Zeichen ersetzen.
Histokrat
Ok - ich konnte diese Konstruktion nirgendwo gut beschreiben!
Wally
Ich wähle dies als "den Gewinner", da es nicht möglich ist, auch nur einen Hauch von Mathematik zu vermeiden.
Wally
3
Keine Hutspitze zu Abigail? Zum Schämen. Dies ist eine direkte Portierung der Perl-Lösung von 1998: catonmat.net/blog/perl-regex-that-matches-prime-numbers
skibrianski
16

Rubin: 52 - 10 = 42

Verwenden Sie eine Variation dieses berühmten Prime Matching Regex.

puts ?_*gets.to_i=~/^(_|(__+?)\2+)$/?"Not!!":"Prime"

Nur um klar zu sein: ?_*gets.to_iist eine Zeichenfolgeoperation, die angehängt wird"_" die n- mal an sich selbst , wobei n die eingegebene Zahl ist. Aus meiner Sicht werden keine Stringlängen verglichen, so dass das 10 Zeichen Bonuskriterium erfüllt sein sollte.

daniero
quelle
1
Ich bin nicht so vertraut mit Ruby, also korrigiere mich, wenn ich falsch liege, aber konvertiert das "to_i" den String nicht in eine Ganzzahl? Nicht, dass ich den brillanten Prime Checker in Unary nicht mag ...
Wally
1
@Wally Ich glaube nicht, dass "convert" nicht das richtige Wort ist, aber die Methode gibt ein int zurück, yes. Trotzdem verwende ich keine der folgenden Arithmetic operators, bit-wise operators, numeric variables and constantsMethoden und Sie können den Aufruf einer Methode nicht wirklich als ... klassifizieren "math-stuff" in general.
Daniero
@daniero Klingt vernünftig - vielleicht direkt am Rande der Spezifikation.
Wally
3

Perl 52-10 = 42

Implementierung

print((('-'x$ARGV[0])=~/^.$|^(..+?)\1+$/)?Not:Prime)

Demo

$ seq 1 10|xargs -I{} bash -c "echo -n '{} '  && perl Prime.pl {} && echo"
1 Not
2 Prime
3 Prime
4 Not
5 Prime
6 Not
7 Prime
8 Not
9 Not
10 Not
Abhijit
quelle
4
Ich bin nicht wirklich eine Primzahl.
Elixenid
Verwendet einen numerischen Array-Index - also am Rand der Spezifikation.
Wally
Verwenden Sie popstattdessen $ARGV[0], speichern Sie 4 Zeichen, entfernen Sie den numerischen Array-Index
Mob
1

ECMAScript 6, 159-10 = 149

Klingt nach einer Aufgabe für Regex. I / O mit prompt/ alertwie gewohnt.

for(s=prompt(u=""); /[^0]/.test(s); )
  s=s.replace(/(.)(0*)$/,(_,d,t)=>u+="x"," 012345678"[d]+t.replace(/0/g,"9"))
alert(/^((xx+)\2+|x?)$/.test(u)?"Not!!":"Prime")

Die while-Schleife dekrementiert die Dezimalzahl bei jeder Iteration nur durch Regex. Der endgültige reguläre Ausdruck entspricht einer Zeichenfolge, die aus einer zusammengesetzten Anzahl von x besteht, indem zuerst ein Faktor und dann ein weiterer Faktor für den Rest der Zeichenfolge abgeglichen wird.

FireFly
quelle
Ich mag die Funktion zum Dekrementieren von Saiten - klar und prägnant.
Wally
1

Javascript 266

function N(a){function b(a){return P.every(function(b){if(n=b,i=a.length,j=b.length,j>i) return;if(j==i) return 1;while(n.length<i)n+=b;return n.length!=i})}if(q=A,A!=a)for(;q.length.toString()!=a;)b(q)&&P.push(q),q+=A;console.log(b(q)?"Prime":"Not!!")}A="0",P=[A+A]

Erstellt eine Funktion mit dem Namen N, die das gewünschte Ergebnis ausgibt. Die ungekürzte Version sieht so aus. Ich habe eine Handminimierung durchgeführt, um einige Variablen zu bereinigen, und dann habe ich diese durch uglify ausgeführt und dann die Handminimierung erneut durchgeführt.

// A a string of "0" for using to generate long strings
// P is the store for all known primes
A="0", P=[A+A];
function N(val) {
  function _isPrime(str) {
    // go through all the known primes and return true
    // if we don't match on any of them
    return P.every(function(prime) {
      // prime is some known string whose length is a prime number
      tsr = prime, strlen = str.length, primelen = prime.length;
      // if the string we're checking has fewer chars than
      // this then it's not a prime
      if(strlen < primelen) return 0;
      // if the string we're checking has the same number of chars
      // as the the prime we're checking against then it is a prime
      if(primelen == strlen) return 1;
      // Keep incrementing our temporary string with the prime we're
      // checking. we'll break out of the loop once the temporary string
      // is greater than or equal to the string we're testing
      while(tsr.length < strlen) {
        tsr += prime;
      }
      return !(tsr.length == strlen)
    });
  }
  // start with a string of one unit
  nstr = A
  if(A!=val) {
    // keep incrementing the string so that we can compile a list
    // of known primes smaller than this value
    while(nstr.length.toString() !== val) {
      if(_isPrime(nstr)) {
        P.push(nstr);
      }
      nstr += A;
    }
  }
  console.log(_isPrime(nstr) ? "Prime" : "Not!!");
}

Getestet mit diesem Snippet:

for(var X=0;X<10;X++) {
  console.log('checking: ' + X);
  N(X.toString());
}
Sugendran
quelle
1
Ich bin mir nicht sicher, wie das funktioniert, aber ich sehe eine numerische Variable (i) und einen arithmetischen Operator (i ++).
Wally
Oh, ich wusste nicht, dass ich so eine for-Schleife nicht machen kann. Ich werde sie heute Abend umschreiben.
Sugendran
Grundsätzlich produziere ich eine Reihe von Strings, deren Länge Primzahlen sind. Wenn ich also eine Eingabe erhalte, füge ich einer Zeichenfolge solange Zeichen hinzu, bis der Längenwert für die Zeichenfolge mit der Eingabe übereinstimmt. Ich nehme dann diese Zeichenfolge und sehe nach, ob ich sie durch eine der bekannten Primzahlen gleichmäßig teilen kann. Wenn ich nicht kann, muss es eine Primzahl sein. Und mit Teilen meine ich, ich nehme die bekannte Primzahl und addiere sie zu sich selbst, wobei die Länge der Zeichenkette entweder gleich oder größer als die fragliche Zeichenkette ist.
Sugendran
Ich habe den Code aktualisiert, es reduziert tatsächlich die Anzahl der Zeichen leicht :)
Sugendran
Cool. Es sieht aus wie der reguläre Ausdruck, ist aber effizienter und zeigt explizit die tatsächliche Logik.
Wally
0

Bash 66 - 10 = 56

Implementierung

[[ -z `printf %$1s|grep -P "^(..+?)\1+$"` ]]&&echo Prime||echo Not

Demo

$ seq 1 10|xargs -I{} bash -c "echo -n '{} '  && ./Prime.sh {}"
1 Prime
2 Prime
3 Prime
4 Not
5 Prime
6 Not
7 Prime
8 Not
9 Not
10 Not
Abhijit
quelle
Wie oben ist 1 keine Primzahl.
Wally