Hoyo 2 - Prime Quine

9

Encuentra el hoyo 1 aquí .

Haga una quine que, cuando se ejecuta, genera su propio bloque de código fuente varias veces. De hecho, debe generarlo n veces, donde n en el siguiente número primo.

Creo que un ejemplo lo muestra mejor.

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

Cada programa generará su "bloque" base (por lo tanto, [MI QUINE]) las siguientes veces de números primos .

Las funciones integradas para calcular si un número es primo (como una función isPrime) o para determinar el próximo primo (como una función nextPrime ()) no están permitidas.

  • Esto significa que las funciones para enumerar el número de divisores no están permitidas
  • Las funciones que devuelven la factorización prima tampoco están permitidas.

Esto debería ser una verdadera quine (excepto por algún margen de maniobra, vea el siguiente punto), por lo que no debe leer su propio código fuente.

Debido a que los lenguajes como Java y C # ya están en desventaja, no necesita generar un código totalmente funcional. Si se puede poner en una función (que se llama) y generar la próxima quine, está bien.

Este es el código de golf, ¡así que el código más corto gana!

Estiramiento Maniaco
fuente
Nadie respondió el hoyo 1, entonces, ¿qué puntaje obtienen todos los que responden a este para el primer hoyo?
Optimizador
1
¿Podría aclarar la parte con las funciones principales? ¿Podemos usarlos o no podemos usarlos?
Martin Ender
3
¿Qué se considera comprobación principal y qué no? Teniendo en cuenta que la verificación principal se puede construir utilizando cualquier quine si este tipo, las reglas no son lo suficientemente claras
orgulloso Haskeller
@Optimizer: Todos tienen un puntaje de 0 para el primer hoyo hasta que alguien lo responda.
Stretch Maniac
2
@StretchManiac Debe mencionar claramente en la pregunta que tanto la lista de métodos de factorización prima como la lista de métodos de divisores tampoco están permitidos. Por favor, publique la pregunta en el Sandbox la próxima vez.
Optimizador

Respuestas:

5

CJam, 31 bytes

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

Pruébelo en línea en el intérprete de CJam .

Idea

Para verificar la originalidad, usaremos el teorema de Wilson , que establece que un número entero n> 1 es primo si y solo si (n - 1). ≡ -1 (mod n) , que es cierto si y solo si (n - 1)! + 1% n == 0 .

Código

{                           }_~ 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
fuente
¿Cómo encontró ese método de comprobación de prime oO
Optimizer
3
Recordada sería más precisa. Es conocido como el teorema de Wilson.
Dennis
mp(¿es prime?) existe ahora, por lo que en la última versión de CJam, uno podría jugar golf un poco más.
Lynn
1
@Mauris Existió en la primera versión pública, IIRC. Sin embargo, la pregunta prohíbe los operadores integrados y de factorización.
Dennis
1

CJam, 36 35 bytes

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

Esto definitivamente se puede jugar más golf.

Cómo funciona:

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

Gracias a Martin por recordarme el ]W=truco :)

Pruébalo en línea aquí

Optimizador
fuente
1

Mathematica, 248 222 bytes

Editar: se corrigió el uso de una función relacionada con Prime, pero también se mejoró un poco la combinación.

Editar: Gracias a Dennis por presentarme el teorema 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]

Esto supone que el kernel se cierra entre ejecuciones posteriores de la quine (o al menos nse restablece), porque se basa en nestar indefinido antes de la primera instancia de[MyQuine] se ejecute .

Esto probablemente se puede acortar mucho, pero no tengo mucha experiencia con quines, especialmente en Mathematica.

Aquí hay una explicación:

1;

Esto no hace nada, pero si se concatena al final de la línea anterior, multiplica el resultado de la última expresión por 1(que es un no-op) y el punto y coma suprime la salida. Esto asegura que solo la última copia de [MyQuine]copias imprima algo.

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

Inicializa na 1la primera copia de [MyQuine]y luego lo incrementa por 1cada copia adicional - es decir, este recuento sólo cuántas copias existen en n.

Avanza hasta el final ahora:

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

Esto encuentra el próximo primo usando el teorema de Wilson .

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

Esta es la quine real. Crea NextPrime@ncopias del código en sí. También es un poco raro. Sí, estoy multiplicando dos cadenas allí, y no, eso no tiene un resultado significativo. QUINE_PREFIXcontiene todo el código antes de las dos cadenas y QUINE_SUFFIXcontiene todo el código después de las dos cadenas. Ahora usualmente usa Apply(o @@) para convertir una lista en una serie de argumentos. Pero puede reemplazar cualquiera Headcon Apply, por ejemplo, multiplicación. Entonces, a pesar de ser un producto, todavía puedo convertirlo en dos argumentos para mi función. Esa función hace:

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

Donde #está el primer argumento (la cadena de prefijo), #2es el segundo argumento (la cadena de sufijo), ##es una secuencia de ambos argumentos. Necesito anteponer 1para preservar la multiplicación; de lo contrario, ##saldría a la lista de argumentos para ToString. De todos modos, ToString[1##,InputForm]&@@("abc"*"def")vuelve "abc"*"def"... justo lo que necesito!

Creo que con todas las cosas que necesito alrededor de la quine, una evalquine a base sería más apropiada aquí. Lo investigaré más tarde o mañana.

Martin Ender
fuente
@ MartinBüttner, la pregunta debería ser editada
orgulloso Haskeller
Je, también puedo usar el Teorema de Wilson para poner mi entrada a la par con Denis ';)
Optimizer
@Optimizer Pero en mi caso no había peligro de ofender a nadie porque todavía estoy usando 7 veces más bytes que ustedes dos;)
Martin Ender
@ MartinBüttner Lo sé: D Por eso no lo usé :)
Optimizer
0

J - 60 char

Utiliza el método next-prime como las otras respuestas. (Ese es el 4 p:bit.)

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

Un pequeño y lindo truco de J es que f :gactúa como fcuando se le da un argumento y gcuando se le dan dos. Entonces, si escribe, diga f :;'a'f :;'a'f :;'a'entonces que actúa como f'a';'a';'a', lo cual es genial porque esa es una lista encuadrada cuyos elementos son 'a'y cuya longitud es el número de ocurrencias.

Entonces podemos convertir eso en una especie de quiney. El faspecto que usamos es (foo $~ bar), donde fooconstruye la parte de la cuerda que repetimos una y otra vez, barbusca el siguiente número primo y lo multiplica por 60, la longitud de la cadena 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
Algoritmo de tiburón
fuente
¿Podría modificar su código para cumplir con las nuevas especificaciones? Los métodos que generan el próximo primo no están permitidos. Gracias.
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
fuente