Loch 2 - Prime Quine

9

Finden Loch 1 hier .

Erstellen Sie eine Quine, die beim Ausführen mehrmals einen eigenen Quellcodeblock ausgibt. Tatsächlich muss es n-mal ausgegeben werden, wobei n in der nächsten Primzahl steht.

Ich denke, ein Beispiel zeigt es am besten.

[MY QUINE][MY QUINE]
[MY QUINE][MY QUINE][MY QUINE]
[MY QUINE][MY QUINE][MY QUINE][MY QUINE][MY QUINE]
[MY QUINE][MY QUINE][MY QUINE][MY QUINE][MY QUINE][MY QUINE][MY QUINE]
[MY QUINE][MY QUINE][MY QUINE][MY QUINE][MY QUINE][MY QUINE][MY QUINE][MY QUINE][MY QUINE][MY QUINE][MY QUINE]

Jedes Programm gibt seinen Basis- "Block" (also [MEIN QUINE]) die nächste Primzahl aus .

Eingebaute Funktionen zum Berechnen, ob eine Zahl eine Primzahl ist (wie eine isPrime-Funktion) oder zum Bestimmen der nächsten Primzahl (wie eine nextPrime () -Funktion) sind nicht zulässig.

  • Dies bedeutet, dass Funktionen zum Auflisten der Anzahl der Teiler nicht zulässig sind
  • Funktionen, die die Primfaktorisierung zurückgeben, sind ebenfalls nicht zulässig

Dies sollte eine echte Quine sein (mit Ausnahme eines gewissen Spielraums, siehe nächster Punkt), daher sollten Sie Ihren eigenen Quellcode nicht lesen.

Da Sprachen wie Java und C # bereits im Nachteil sind, müssen Sie keinen vollständig funktionierenden Code ausgeben. Wenn es in eine Funktion (die aufgerufen wird) eingefügt und das nächste Quine ausgegeben werden könnte, sind Sie gut.

Dies ist Code-Golf, also gewinnt der kürzeste Code!

Stretch Maniac
quelle
Niemand hat auf Loch 1 geantwortet. Welche Punktzahl erhält jeder, der dieses beantwortet, für das erste Loch?
Optimierer
1
Könnten Sie den Teil mit den Hauptfunktionen klären? Können wir sie benutzen oder können wir sie nicht benutzen?
Martin Ender
3
Was wird als Prime Checking angesehen und was nicht? In Anbetracht der Tatsache, dass die
Hauptprüfung
@Optimizer: Jeder hat eine Punktzahl von 0 für das erste Loch, bis jemand darauf antwortet.
Stretch Maniac
2
@StretchManiac Sie sollten in der Frage klar erwähnen, dass sowohl die Liste der Primfaktorisierungsmethoden als auch die Liste der Teilermethoden nicht zulässig sind. Bitte posten Sie die Frage beim nächsten Mal in der Sandbox.
Optimierer

Antworten:

5

CJam, 31 Bytes

{'_'~]-3>U):U{)__,1>:*)\%}g*}_~

Probieren Sie es online im CJam-Interpreter aus .

Idee

Um die Primalität zu überprüfen, verwenden wir den Satz von Wilson , der besagt, dass eine ganze Zahl n> 1 genau dann eine Primzahl ist, wenn (n - 1)! ≡ -1 (mod n) , was genau dann zutrifft, wenn (n - 1)! + 1% n == 0 .

Code

{                           }_~ e# Define a block and execute a copy.
                                e# The original block will be on top of the stack.
 '_'~]                          e# Push those characters and wrap the stack in an array.
      -3>                       e# Keep only the last three elements (QUINE).
         U):U                   e# Increment U (initially 0).
             {           }g     e# Do-while loop:
              )__               e# Increment the integer I on the stack (initially U).
                 ,1>            e#   Push [1 ... I-1].
                    :*          e#   Multiply all to push factorial(I-1).
                      )\%       e#   Push factorial(I-1) + 1 % I.
                                e# While the result is non-zero, repeat.
                                e# This pushes the next prime after U.
                           *    e# Repeat QUINE that many times.
Dennis
quelle
Wie haben Sie diese Methode zur Überprüfung von Prime OO
Optimizer
3
Erinnert wäre genauer. Es ist als Wilsons Satz bekannt.
Dennis
mp(ist Prime?) existiert jetzt, also könnte man in der neuesten Version von CJam dies ein bisschen mehr Golf spielen.
Lynn
1
@ Mauris Es existierte in der ersten öffentlichen Version, IIRC. Die Frage verbietet jedoch eingebaute Prim- und Faktorisierungsoperatoren.
Dennis
1

CJam, 36 35 Bytes

{]W="_~"]U):U{)_,{)1$\%!},,2>}g*}_~

Dies kann definitiv weiter Golf gespielt werden.

Wie es funktioniert:

{                               }_~   "Copy this code block and execute the copy";
 ]W=                                  "Take just the last element from the stack";
                                      "The other thing on stack is the block from above";
    "_~"]                             "Put "_~" on stack and wrap the 2 things in an array";
                                      "At this point, the string representation of stack"
                                      "elements is identical to the source code";
         U):U                         "Increment U and update U's value. This  variable"
                                      "actually counts the number of [Quine] blocks";
             {)_,{)1$\%!},,2>}g       "Find the next prime number"
                               *      "Repeat the array that many times, thus repeat the"
                                      "[Quine] block, the next prime times";

Danke an Martin, der mich an den ]W=Trick erinnert hat :)

Probieren Sie es hier online aus

Optimierer
quelle
1

Mathematica, 248 222 Bytes

Bearbeiten: Die Verwendung einer prim-bezogenen Funktion wurde korrigiert, aber auch das Quining etwas verbessert.

Edit: Danke an Dennis, der mich mit Wilsons Theorem bekannt gemacht hat.

1;n=If[ValueQ@n,n+1,1];StringJoin@Array[#<>ToString[1##,InputForm]<>#2&@@\("1;n=If[ValueQ@n,n+1,1];StringJoin@Array[#<>ToString[1##,InputForm]<>#\2&@@("*"&,For[i=n,Mod[++i!/i+1,i]>0,0];i]")&,For[i=n,Mod[++i!/i+1,i]>0,0];i]

Dies setzt voraus, dass der Kernel zwischen nachfolgenden Durchläufen des Quines beendet wird (oder zumindest nzurückgesetzt wird), da er nnicht definiert werden muss, bevor die erste Instanz von ausgeführt [MyQuine]wird.

Dies kann wahrscheinlich stark verkürzt werden, aber ich habe nicht viel Erfahrung mit Quines, insbesondere in Mathematica.

Hier ist eine Erklärung:

1;

Dies macht nichts, aber wenn es am Ende des vorherigen Quines verkettet wird, multipliziert es das Ergebnis des letzten Ausdrucks mit 1(was ein No-Op ist) und das Semikolon unterdrückt die Ausgabe. Dies stellt sicher, dass nur die letzte Kopie [MyQuine]etwas druckt.

n=If[ValueQ@n,n+1,1];

Diese initialisiert , num 1in der ersten Kopie [MyQuine]und erhöht sie dann 1in jeder weiteren Kopie - also diese nur zählt , wie viele Kopien gibt es in n.

Springe jetzt bis zum Ende:

For[i=n,Mod[++i!/i+1,i]>0,0];i

Dies findet die nächste Primzahl unter Verwendung des Wilsonschen Theorems .

StringJoin@Array[#<>ToString[1##,InputForm]<>#2&@@\("QUINE_PREFIX"*"QUINE_SUFFIX")&,NEXTPRIME[n]]

Dies ist die eigentliche Quine. Es werden NextPrime@nKopien des Codes selbst erstellt. Es ist auch ein bisschen komisch. Ja, ich multipliziere dort zwei Zeichenfolgen, und nein, das hat kein aussagekräftiges Ergebnis. QUINE_PREFIXenthält den gesamten Code vor den beiden Zeichenfolgen und den QUINE_SUFFIXgesamten Code nach den beiden Zeichenfolgen. Normalerweise verwenden Sie Apply(oder @@), um eine Liste in eine Reihe von Argumenten umzuwandeln. Sie können jedoch jede Headdurch Apply- z. B. Multiplikation - ersetzen . Obwohl dies ein Produkt ist, kann ich es dennoch in zwei Argumente für meine Funktion umwandeln. Diese Funktion hat:

#<>ToString[1##,InputForm]<>#2

Wo #ist das erste Argument (die Präfixzeichenfolge), #2ist das zweite Argument (die Suffixzeichenfolge), ##ist eine Folge beider Argumente. Ich muss voranstellen 1, um die Multiplikation ##beizubehalten - sonst würde in die Argumentliste zu splat ToString. Wie auch immer, ToString[1##,InputForm]&@@("abc"*"def")kehrt zurück "abc"*"def"... genau das, was ich brauche!

Ich denke, mit all dem Zeug, das ich rund um das Quine brauche, wäre ein evalQuine auf Basis hier angemessener. Ich werde das später oder morgen untersuchen.

Martin Ender
quelle
@ MartinBüttner die Frage sollte bearbeitet werden
stolzer Haskeller
Heh, ich kann auch Wilsons Theorem verwenden, um meinen Eintrag mit Denis gleichzusetzen;)
Optimizer
@Optimizer Aber in meinem Fall bestand keine Gefahr, jemanden zu beleidigen, da ich immer noch 7-mal so viele Bytes wie Sie beide verwende;)
Martin Ender
@ MartinBüttner Ich weiß: D Deshalb habe ich es nicht benutzt :)
Optimizer
0

J - 60 char

Verwendet die Next-Prime-Methode wie die anderen Antworten. (Das ist das 4 p:bisschen.)

((58&$,2#{:)@;$~60*4 p:#) :;'((58&$,2#{:)@;$~60*4 p:#) :;'''

Ein süßer kleiner J-Trick ist, dass er sich so f :gverhält, fals würde er ein Argument und gwenn zwei gegeben. Wenn Sie also schreiben, sagen Sie, f :;'a'f :;'a'f :;'a'dass sich das so verhält f'a';'a';'a', was großartig ist, da es sich um eine Box-Liste handelt, deren Elemente 'a'und deren Länge die Anzahl der Vorkommen ist.

Also können wir das in eine quiney Art von Dingen heben. Das, was fwir verwenden, sieht so aus (foo $~ bar), als würde fooder String-Teil, den wir immer wieder wiederholen , konstruiert, bardie nächste Primzahl gefunden und mit 60 multipliziert, der Länge des Strings in foo.

   ((58&$,2#{:)@;$~60*4 p:#) :;'((58&$,2#{:)@;$~60*4 p:#) :;'''((58&$,2#{:)@;$~60*4 p:#) :;'((58&$,2#{:)@;$~60*4 p:#) :;'''
((58&$,2#{:)@;$~60*4 p:#) :;'((58&$,2#{:)@;$~60*4 p:#) :;'''((58&$,2#{:)@;$~60*4 p:#) :;'((58&$,2#{:)@;$~60*4 p:#) :;'''((58&$,2#{:)@;$~60*4 p:#) :;'((58&$,2#{:)@;$~60*4 p:#) :;'''
   # ((58&$,2#{:)@;$~60*4 p:#) :;'((58&$,2#{:)@;$~60*4 p:#) :;'''((58&$,2#{:)@;$~60*4 p:#) :;'((58&$,2#{:)@;$~60*4 p:#) :;'''
180
   ((58&$,2#{:)@;$~60*4 p:#) :;'((58&$,2#{:)@;$~60*4 p:#) :;'''((58&$,2#{:)@;$~60*4 p:#) :;'((58&$,2#{:)@;$~60*4 p:#) :;'''((58&$,2#{:)@;$~60*4 p:#) :;'((58&$,2#{:)@;$~60*4 p:#) :;'''
((58&$,2#{:)@;$~60*4 p:#) :;'((58&$,2#{:)@;$~60*4 p:#) :;'''((58&$,2#{:)@;$~60*4 p:#) :;'((58&$,2#{:)@;$~60*4 p:#) :;'''((58&$,2#{:)@;$~60*4 p:#) :;'((58&$,2#{:)@;$~60*4 p:#) :;'''((58&$,2#{:)@;$~60*4 p:#) :;'((58&$,2#{:)@;$~60*4 p:#) :;'''((58&$,2#{:)@;$~60*4 p:#) :;'((58&$,2#{:)@;$~60*4 p:#) :;'''
   # ((58&$,2#{:)@;$~60*4 p:#) :;'((58&$,2#{:)@;$~60*4 p:#) :;'''((58&$,2#{:)@;$~60*4 p:#) :;'((58&$,2#{:)@;$~60*4 p:#) :;'''((58&$,2#{:)@;$~60*4 p:#) :;'((58&$,2#{:)@;$~60*4 p:#) :;'''
300
Algorithmushai
quelle
Könnten Sie Ihren Code ändern, um die neuen Spezifikationen zu erfüllen? Methoden, die die nächste Primzahl ausgeben, sind nicht zulässig. Vielen Dank.
Stretch Maniac
0

Python 2.7, 214

from sys import*;R,s=range,chr(35)
def N(n):
 if n<3:return n+1
 for p in R(n+1,n+n):
    for i in R(2, p):
     if p%i==0:break
     else:return p
P=file(argv[0]).read();print(P.split(s)[0]+s)*N(P.count(chr(37)));exit(0)
#
Dieter
quelle