Trou 2 - Prime Quine


9

Trouvez le trou 1 ici .

Créez une quine qui, lorsqu'elle est exécutée, génère plusieurs fois son propre bloc de code source. En fait, il doit le sortir n fois, où n dans le prochain nombre premier.

Je pense qu'un exemple le montre le mieux.

[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]

Chaque programme sortira son "bloc" de base (donc [MA QUINE]) les prochaines fois en nombre premier .

Les fonctions intégrées pour calculer si un nombre est premier (comme une fonction isPrime) ou pour déterminer le nombre premier suivant (comme une fonction nextPrime ()) ne sont pas autorisées.

  • Cela signifie que les fonctions pour répertorier le nombre de diviseurs ne sont pas autorisées
  • Les fonctions qui renvoient la factorisation principale sont également interdites

Cela devrait être une vraie quine (sauf pour une certaine latitude, voir le point suivant), donc vous ne devriez pas lire votre propre code source.

Parce que les langages comme Java et C # sont déjà désavantagés, vous n'avez pas besoin de sortir du code totalement fonctionnel. Si elle pouvait être placée dans une fonction (qui est appelée) et sortir le quine suivant, vous êtes bon.

C'est le code-golf, donc le code le plus court gagne!


Personne n'a répondu au trou 1, alors quel score tous ceux qui répondent à celui-ci obtiennent-ils pour le premier trou?
Optimiseur

1
Pourriez-vous clarifier la partie avec les fonctions principales? Pouvons-nous les utiliser ou ne pouvons-nous pas les utiliser?
Martin Ender

3
Qu'est-ce qui est considéré comme la vérification principale et ce qui ne l'est pas? Étant donné que la vérification principale peut être construite à l'aide de n'importe quelle quine si ce type, les règles ne sont pas assez claires
fier haskeller

@Optimizer: Tout le monde a un score de 0 pour le premier trou jusqu'à ce que quelqu'un y réponde.
Stretch Maniac

2
@StretchManiac Vous devez clairement mentionner dans la question que la liste des méthodes de factorisation par prime et la liste des méthodes de diviseurs ne sont pas non plus autorisées. Veuillez poster la question dans le bac à sable la prochaine fois.
Optimizer

Réponses:


5

CJam, 31 octets

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

Essayez-le en ligne dans l' interpréteur CJam .

Idée

Pour vérifier la primalité, nous utiliserons le théorème de Wilson , qui stipule qu'un entier n> 1 est premier si et seulement si (n - 1)! ≡ -1 (mod n) , ce qui est vrai si et seulement si (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.

Comment avez-vous trouvé cette méthode de vérification de la prime oO
Optimizer

3
Se souvenir serait plus précis. Il est connu comme le théorème de Wilson.
Dennis

mp(est premier?) existe maintenant, donc dans la dernière version de CJam, on pourrait jouer au golf un peu plus.
Lynn

1
@Mauris Il existait dans la première version publique, IIRC. Cependant, la question interdit les opérateurs de prime et de factorisation intégrés.
Dennis

1

CJam, 36 35 octets

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

Cela peut certainement être joué plus loin.

Comment ça fonctionne:

{                               }_~   "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";

Merci à Martin de m'avoir rappelé le ]W=truc :)

Essayez-le en ligne ici


1

Mathematica, 248 222 octets

Edit: correction de l'utilisation d'une fonction liée à Prime, mais également amélioration un peu du quining.

Edit: Merci à Dennis de m'avoir présenté le théorème de Wilson.

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]

Cela suppose que le noyau est fermé entre les exécutions suivantes du quine (ou au moins nest réinitialisé), car il repose sur le fait qu'il nn'est pas défini avant l' [MyQuine]exécution de la première instance de .

Cela peut probablement être beaucoup raccourci, mais je n'ai pas beaucoup d'expérience avec les quines, surtout en Mathematica.

Voici une explication:

1;

Cela ne fait rien, mais s'il est concaténé à la fin du quine précédent, il multiplie le résultat de la dernière expression par 1(qui est un no-op) et le point-virgule supprime la sortie. Cela garantit que seule la dernière copie de [MyQuine]imprime quoi que ce soit.

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

Initialise nà 1la première copie [MyQuine]et incrémente par 1chaque exemplaire supplémentaire - à savoir ce seulement compte combien de copies il y a en n.

Passez à la fin maintenant:

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

Cela trouve le premier premier en utilisant le théorème de Wilson .

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

C'est le véritable quine. Il crée des NextPrime@ncopies du code lui-même. C'est aussi un peu bizarre. Oui, je multiplie deux chaînes là-bas, et non, cela n'a pas de résultat significatif. QUINE_PREFIXcontient tout le code avant les deux chaînes et QUINE_SUFFIXcontient tout le code après les deux chaînes. Maintenant, vous utilisez généralement Apply(ou @@) pour transformer une liste en une série d'arguments. Mais vous pouvez en remplacer n'importe quel Headavec Apply- par exemple la multiplication. Donc, bien que ce soit un produit, je peux toujours le transformer en deux arguments pour ma fonction. Cette fonction:

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

#est le premier argument (la chaîne de préfixe), #2est le deuxième argument (la chaîne de suffixe), ##est une séquence des deux arguments. Je dois ajouter au début 1pour préserver la multiplication - sinon, ##je serais inséré dans la liste des arguments ToString. Quoi qu'il en soit, ToString[1##,InputForm]&@@("abc"*"def")revient "abc"*"def"... juste ce dont j'ai besoin!

Je pense qu'avec tout ce dont j'ai besoin autour du quine, un evalquine basé serait plus approprié ici. J'examinerai cela plus tard ou demain.


@ MartinBüttner la question devrait être modifiée
fier haskeller

Hé, je peux aussi utiliser le théorème de Wilson pour amener mon entrée au pair avec Denis ';)
Optimizer

@Optimizer Mais dans mon cas, il n'y avait aucun danger d'offenser quelqu'un parce que j'utilise encore 7 fois plus d'octets que vous deux;)
Martin Ender

@ MartinBüttner Je sais: D C'est pourquoi je ne l'ai pas utilisé :)
Optimizer

0

J - 60 car

Utilise la méthode next-prime comme les autres réponses. (C'est le 4 p:peu.)

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

Un petit truc en J mignon, c'est f :gcomme fsi on lui donnait un argument et qu'on gen donnait deux. Donc, si vous écrivez, dites f :;'a'f :;'a'f :;'a'alors que cela agit comme f'a';'a';'a', ce qui est génial parce que c'est une liste encadrée dont les éléments sont 'a'et dont la longueur est le nombre d'occurrences.

Nous pouvons donc transformer cela en une sorte de chose quiney. Le que fnous utilisons ressemble (foo $~ bar), où fooconstruit la partie chaîne que nous répétons encore et encore, bartrouve le nombre premier suivant et le multiplie par 60, la longueur de la chaîne 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

Pourriez-vous modifier votre code pour répondre aux nouvelles spécifications? Les méthodes qui génèrent le premier prime ne sont pas autorisées. Merci.
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)
#
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.