Auto-acortador Prime Tester

8

Vamos directo a ello. Su desafío es hacer un programa que haga estas cosas dependiendo de su entrada:

  1. Si la entrada es un número, envíe "Prime" si el número es un número primo y "Not prime" si el número no es un número primo. Puede suponer que el número es> 1.

  2. Si la entrada es dos números, envíe cada número primo entre el primer número (inclusive) y el segundo número (exclusivo). Puede suponer que el primer número es más pequeño que el segundo.

  3. Aquí viene el verdadero desafío: si no hay entrada, el programa debería generar una versión más corta de sí mismo que haga exactamente las mismas cosas que el programa original. El programa no tiene permitido leer desde ningún archivo o desde la web. El nuevo programa también debería poder hacer esto. Debería funcionar durante al menos 5 generaciones. El nuevo programa no tiene que estar en el mismo idioma que el primero.

Puntuación:

Su puntaje es igual a la suma del número de bytes en las primeras cinco generaciones de su envío (el envío en sí es la generación uno). Si el nuevo código está codificado en el primer programa, multiplique el puntaje por 1.5. La puntuación más baja gana. (Si encuentra algún tipo de falla en el sistema de puntuación, hágamelo saber en los comentarios)

Loovjo
fuente
1
Debe especificar las condiciones para la parte quine: si el programa tiene permiso para leer su propio código fuente, etc. Consulte esta pregunta de hace 5 días en nuestro sitio meta: meta.codegolf.stackexchange.com/q/4877/15599
Level River San
Creo que mis ediciones abordan todos los comentarios anteriores, excepto uno. El único problema pendiente: ¿qué cuenta como codificación rígida?
Rainbolt
Creo que este es un [código de golf] ("el código más corto gana" en algunas métricas), no es necesario que sea un [código de desafío].
kennytm
¿Qué tal "Generador de programas Prime" , "Producir cinco generaciones de primos" o "Generador de pseudo quinas Prime" ?
Rainbolt

Respuestas:

10

CJam, 66 + 65 + 64 + 63 + 62 = 320 325 355 bytes

Las siguientes 5 líneas son las primeras 5 generaciones:

{     `(\1>+q~](\_,["_~"a{~mp'P"Not p"?"rime"@;}{~,>{mp},p;}]=~}_~
{    `(\1>+q~](\_,["_~"a{~mp'P"Not p"?"rime"@;}{~,>{mp},p;}]=~}_~
{   `(\1>+q~](\_,["_~"a{~mp'P"Not p"?"rime"@;}{~,>{mp},p;}]=~}_~
{  `(\1>+q~](\_,["_~"a{~mp'P"Not p"?"rime"@;}{~,>{mp},p;}]=~}_~
{ `(\1>+q~](\_,["_~"a{~mp'P"Not p"?"rime"@;}{~,>{mp},p;}]=~}_~

El último produce

{`(\1>+q~](\_,["_~"a{~mp'P"Not p"?"rime"@;}{~,>{mp},p;}]=~}_~

que aún realiza las tareas principales correctamente.

Pruébalo aquí.

Explicación

La quine básica de CJam es

{"_~"}_~

que puede extenderse muy fácilmente a una quina generalizada. Para una explicación de esto, vea mi respuesta aquí .

Las ideas básicas para esta respuesta son:

  • Comience la quine con un montón de espacios y elimine uno de estos al quining.
  • Obtenga una matriz con todos los números de entrada (0, 1 o 2) y elija un código para ejecutar según la longitud (usándolo para indexar en una matriz).

Aquí hay un desglose del código dentro de la quine:

"Remove a space from the block's string representation:";
`(\1>+
`      "Get the string representation of the block.";
 (\    "Slice off the leading '{' and pull the remaining string back up.";
   1>  "Remove the first character, i.e. a space.";
     + "Prepend the '{' to the string again.";

"Get the array of inputs and choose the code:";
q~](\_,[...]=~
q~             "Read and eval the input.";
  ]            "Wrap everything (including the string for the block) in an array.";
   (\          "Shift off the string and swap it with the rest of the array.";
     _,        "Duplicate the input array and get its length.";
       [...]=  "Use it to index into this array.";
             ~ "If there are no inputs there will now be an array on the top of the
                stack, which ~ will unwrap. Otherwise there will be a block which ~
                will evaluate.";

"If there is no input, push the string needed for the quine and put it in
 an array for ~ to unwrap:";
"_~"a

"If there is one input, test for primality:";
~mp'P"Not p"?"rime"@;
~mp                   "Unwrap the input array and test for primality.";
   'P"Not p"?         "Choose either 'P' or 'Not p' depending on the result.";
             "rime"   "Push the common part of the string.";
                   @; "Pull up the quine string and discard it.";

"If there are two inputs, print an array with all the primes in the range:";
~,>{mp},p;
~          "Unwrap the array leaving N and M on the stack.";
 ,         "Get a range [0 1 .. N-1].";
  >        "Drop the first M elements, giving [M M+1 .. N-1].";
   {mp},   "Filter to keep only the primes.";
        p  "Pretty-print the array.";
         ; "Discard the quine string.";
Martin Ender
fuente
¿Podría por favor agregar una explicación?
Loovjo
1
@Loovjo Sí, lo haré, pero no antes de que termine de jugar al golf. ;)
Martin Ender
¿Podría por favor poner los programas en diferentes bloques de código? Me confundió un poco cuando lo leí por primera vez.
Loovjo
@Loovjo aclaró que son 5 programas y agregó una explicación completa
Martin Ender
6

C, Puntuación: 553 + 552 + 551 + 550 + 549 = 2755,

Longitud original: 553, promedio: 551

EDITAR: ¡solo 5 generaciones, no 6!

Parece que Martin me ganó tanto en tiempo como en puntuación (¡en casi un orden de magnitud!). Ah bueno.

El programa original es el siguiente:

char*c="char*c=%c%s%c;k=%d,a;p(c,v,d){for(v=2;v<c;v++)d+=!(c%cv);return!d;}int main(int C,char**V){if(C==1){printf(c,34,c,34,k/10,37,34,34,34,34,34,37,34);return 0;}a=atoi(V[1]);if(C==2)printf(p(a,0,0)?%cPrime%c:%cNot prime%c);if(C==3)for(;a<atoi(V[2]);a++)if(p(a,0,0))printf(%c%cd %c,a);}";k=10000,a;p(c,v,d){for(v=2;v<c;v++)d+=!(c%v);return!d;}int main(int C,char**V){if(C==1){printf(c,34,c,34,k/10,37,34,34,34,34,34,37,34);return 0;}a=atoi(V[1]);if(C==2)printf(p(a,0,0)?"Prime":"Not prime");if(C==3)for(;a<atoi(V[2]);a++)if(p(a,0,0))printf("%d ",a);}

Lo desentrañaré un poco para comprenderlo mejor, pero para que funcione correctamente, las nuevas líneas NO son parte del programa.

char*c="char*c=%c%s%c;k=%d,a;p(c,v,d){for(v=2;v<c;v++)d+=!(c%cv);return!d;}int main(int C,char**V){if(C==1){printf(c,34,c,34,k/10,37,34,34,34,34,34,37,34);return 0;}a=atoi(V[1]);if(C==2)printf(p(a,0,0)?%cPrime%c:%cNot prime%c);if(C==3)for(;a<atoi(V[2]);a++)if(p(a,0,0))printf(%c%cd %c,a);}";
k=10000,a;
p(c,v,d){
    for(v=2;v<c;v++)
        d+=!(c%v);
    return!d;
}
int main(int C,char**V){
    if(C==1){
        printf(c,34,c,34,k/10,37,34,34,34,34,34,37,34);
        return 0;
    }
    a=atoi(V[1]);
    if(C==2)
        printf(p(a,0,0)?"Prime":"Not prime");
    if(C==3)
        for(;a<atoi(V[2]);a++)
            if(p(a,0,0))
                printf("%d ",a);
}

Lo único que cambia de un programa a otro es el valor de k, que pierde exactamente un dígito en cada iteración. Curiosamente, después de la quinta generación, k se convierte en cero y permanece allí, por lo que puede iterar hasta el infinito y siempre tener una salida válida.

BrainSteel
fuente
2

Tcl 253 + 252 + 251 + 250 + 249 = 1255 bytes

eval [set x {     proc q a\ b {incr b;expr $a%$b?\[q $a $b]:$a==$b}
proc 1 a {if [q $a 1] puts\ Prime {puts Not\ Prime}}
proc 2 a\ b {while $b-\$a {if [q $a 1] puts\ $a;incr a}}
proc 0 {} {puts "eval \[set x {[string ra $::x 1 end]}]"}
$argc {*}$argv}]

El código debe terminar con una nueva línea. Explicación:

eval [set x {...}]

Escriba el código en x, luego ejecútelo.

$argc {*}$argv

Ejecute el comando cuyo nombre es la longitud del argumento, pasando los argumentos.

proc q a\ b {incr b;expr $a%$b?\[q $a $b]:$a==$b}

Devuelve 1 cuando a es primo, 0 más. Utiliza recursividad; la segunda barra diagonal inversa evita la sustitución de comandos del intérprete y habilita el de expr(que es vago).

proc 1 a {if [q $a 1] puts\ Prime {puts Not\ Prime}}
proc 2 a\ b {while $b-\$a {if [q $a 1] puts\ $a;incr a}}

Implementación directa de los requisitos.

proc 0 {} {puts "eval \[set x {[string ra $::x 1 end]}]"}

Esta es la quine, quitando un espacio desde el principio cada vez.

Philipp
fuente
"Su puntaje es igual a la suma del número de bytes en las primeras cinco generaciones de su envío (el envío en sí es la generación uno)".
Martin Ender