Multiplicación por auto-modificación

33

... al menos para alguna definición de "auto-modificación".

La tarea

En este desafío, su tarea es escribir tres cadenas A, By Cque satisfagan las siguientes propiedades.

  • La cadena Btiene una longitud de al menos 1.

  • Para cada n ≥ 0, la cadena es un programa válido (es decir, definición de función o programa ejecutable completo) en el lenguaje de programación de su elección. La repetición de superíndice denota, por lo que este medio de las cuerdas , , , etc. Cada programa tiene una cadena como entrada y devuelve una cadena que como salida.ABnCACABCABBCABBBC

  • Para cualquiera m, n ≥ 0, si el programa se ejecuta con entrada , vuelve . Para las entradas que no son de esta forma, el programa puede hacer cualquier cosa, incluido el bloqueo.ABmCABnCABm*n+1C

Algunos ejemplos en el formato program(input) -> output:

AC(AC) -> ABC
ABC(AC) -> ABC
ABBBBBC(AC) -> ABC
AC(ABC) -> ABC
AC(ABBBBC) -> ABC
ABC(ABC) -> ABBC
ABBC(ABC) -> ABBBC
ABBBBC(ABBBC) -> ABBBBBBBBBBBBBC
ABBBC(ABBBBBBC) -> ABBBBBBBBBBBBBBBBBBBC

Reglas y puntuación

Su puntaje es la longitud total de AyC , menor puntaje es mejor. Tenga en cuenta que si bien Bno se cuenta para la puntuación, debe producirse por Ay Ccomo en el primer ejemplo.

Las lagunas estándar no están permitidas. Los programas no pueden acceder directa o indirectamente a su propio código fuente (excepto cuando se les da como entrada). Se requiere que identifique las cadenas y A, en su respuesta, de alguna manera, y se le anima a explicar su solución.BC

Zgarb
fuente

Respuestas:

16

CJam, 9 8 bytes

A: 1
B: 0
C:  r,(#0q

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

Cómo funciona

(ABcode) e# Push the integer 10 ** len(Bcode).
<SP>     e# Noop. Separates (AB) and C for input reading.
r        e# Read the first whitespace-separated token from STDIN (ABinput).
,(       e# Push the string length minus 1: len(Binput)
#        e# Power operator: 10 ** len(Bcode) len(Binput) # ->
         e#   (10 ** len(Bcode)) ** len(Binput) = 10 ** (len(Bcode) * len(Binput))
0        e# Push an additional 0 to complete len(Bcode) * len(Binput) + 1 zeroes.
q        e# Read the remaining input (C).
Dennis
fuente
12

CJam, 15 13 11 bytes

A: rl"
B: <SP>
C: <LF>",(*SNq

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

Cómo funciona

e# A

r     e# Read a whitespace-separated token from STDIN.
      e# This reads the input up to the first space, but does not consume it.
l     e# Read the rest of the first line from STDIN.
      e# This reads up to the first linefeed and consumes it.

"     e# Initiate a string.

e# B

<SP>  e# Fill the string with as many spaces as there are copies of B.

e# C

<LF>" e# Terminate the string with a linefeed.
      e# This serves as a delimiter for the `l' command.
,(    e# Compute the length of the string minus 1 (to account for the LF).
*     e# Repeat the string read by `l' that many times.
SN    e# Push a space and a linefeed.
q     e# Read the remaining input (i.e., the second line) from STDIN.

Al final, la pila contiene el token leído por r, el espacio producido por *, el espacio y el avance de línea empujado por SNy la línea leída por q. CJam imprime todo esto automáticamente.

Dennis
fuente
Ah, buen uso de citas allí: D
Optimizer
9

Pyth, 10

A: w*\0hl*w[<newline>
B: 0
C: <empty>

Dividimos la fuente en dos líneas. La primera línea es A, la segunda línea son los Bs. Como A está en la primera línea, la primera wsimplemente imprime A: fácil, listo.

En Pyth, los ceros a la izquierda son tokens separados, así que en [00)realidad lo son [0, 0]. Tenga en cuenta que la primera línea termina en l[, y la segunda línea consiste en 0000.... Entonces, en l[realidad cuenta el número de Bs en este programa. La segunda se wlee en la segunda línea de la entrada: este es el número de Bs de la entrada. Desde aquí es una simple multiplicación, incremento y salida de tantos ceros.

orlp
fuente
9

Retina , 25 19 bytes

A: ]\]<LF>
B: ]]
C: <LF>m`^]*$<LF>]$0]

<LF> stands for newline

ABCCódigo de ejemplo :

]\]
]]
m`^]*$
]$0]

El código tiene dos pasos sustitutos:

  • cambie la entrada AB^mCen AB^(m*n)Ccambiando cada Ba B^n:

    • ]\]coincide con cada Bentrada y nada más gracias al escape en las líneas del patrón
    • ]]...]] es B^n
  • cambiar B^(m*n)a B^(m*n+1)por

    • m`^]*$tomar la línea con sólo ]'s
    • ]$0]agregando un par adicional de ]]manera que esta línea no coincida con la primera expresión regular

He agregado 3 bytes a la puntuación para el -sindicador de varias líneas que se necesita para que todo el código Retina pueda estar en un archivo.

2 bytes guardados gracias a @ MartinBüttner.

randomra
fuente
8

Python 3, 51 bytes

A: lambda s:s[:28]+"x"*(1+len("
B: x
C: ")*(len(s)-51))+s[-23:]

Ejemplo de uso:

>>> f=lambda s:s[:28]+"x"*(1+len("xx")*(len(s)-51))+s[-23:]
>>> f('lambda s:s[:28]+"x"*(1+len("xxx")*(len(s)-51))+s[-23:]')
'lambda s:s[:28]+"x"*(1+len("xxxxxxx")*(len(s)-51))+s[-23:]'

La función calcula n*m+1con (1+len("xxx")*(len(s)-51))dónde hay m x's en la cadena ( xxxparte es el B^m). Multiplicar la cadena "x"con este número da B^(n*m+1)y la función toma Ay Csale de la entrada y concatena todo esto para obtener AB^(n*m+1)C.

El mismo enfoque en J:

J, 35 bytes

A: (19{.]),('x'#~1+(#'
B: x
C: ')*35-~#),_16{.]
randomra
fuente
5

CJam, 22

A:<empty>
B:{])`\,q,K/(*))*"_~"}
C:{])`\,q,K/(*))*"_~"}_~

Ejemplo de ejecución:

ABBC(ABC) -> ABBBC

lo que se traduce en

{])`\,q,K/(*))*"_~"}{])`\,q,K/(*))*"_~"}{])`\,q,K/(*))*"_~"}_~

con entrada como

{])`\,q,K/(*))*"_~"}{])`\,q,K/(*))*"_~"}_~

que da el siguiente resultado:

{])`\,q,K/(*))*"_~"}{])`\,q,K/(*))*"_~"}{])`\,q,K/(*))*"_~"}{])`\,q,K/(*))*"_~"}_~

Cómo funciona :

Veamos qué programas ACy qué ABCaspecto tenemos:

AC :{])`\,q,K/(*))*"_~"}_~
ABC:{])`\,q,K/(*))*"_~"}{])`\,q,K/(*))*"_~"}_~

Notamos que C=B_~

Veamos lo que Bestá haciendo:

{])`\,q,K/(*))*"_~"}

{                  }    e# This is a code block. Alone, this does nothing except
                        e# pushing this block to stack as is
 ]                      e# Wrap everything on stack in an array
  )`                    e# Take out the last part and convert it to its string representation
    \,                  e# Take length of remaining array
      q,K/              e# Read the input, take its length and int divide by K (i.e. 20)
          (*            e# Decrement and multiply by the array length on stack
            ))          e# Add two to the product
              *         e# Repeat the string representation on stack that many times
               "_~"     e# Put this string on stack

Ahora veamos qué AChará sin ninguna entrada:

{])`\,q,K/(*))*"_~"}_~                      e# Copy the block and run it
{])`\,q,K/(*))*"_~"}{])`\,q,K/(*))*"_~"}~   e# Block is copied, run it
{      ...         } ])                     e# Wrapped array has the block in it.
                       `\,                  e# Stringify it and take length of remaining = 0
                          q,K/              e# No input so 0
                              (*))          e# 0 * -1 = 0. 0 + 2 = 2
                                  *         e# Repeat the stringified block 2 times:
                                            e# "{])`\,q,K/(*))*"_~"}{])`\,q,K/(*))*"_~"}"
                                   "_~"     e# Put this string. Program ends, so print stack:
                                            e# {])`\,q,K/(*))*"_~"}{])`\,q,K/(*))*"_~"}_~

Wow, la salida es ABC.

Básicamente contamos cuántos Bexisten en el código. Entonces, ¿cuántos hay en la entrada (usando longitud). Multiplíquelos, incremente dos veces (ya que Ctambién tiene B) y agregue _~para obtenerC

Pruébalo en línea aquí

Optimizador
fuente
3

Haskell , 50 bytes

fes una función que toma y devuelve a String.

La cadena B es solo un espacio único, mientras que C comienza con uno.

A:_:b="
B: 
C: ";f s|a:c<-words s=unwords$a:(drop 50s>>b):c

Pruébalo en línea!

  • _:b=" "asigna todos menos el primero de los espacios en la cadena literal a b, haciendo que sea igual a las copias m B del programa .
  • ses la cadena de entrada. a:c<-words slo divide en palabras separadas por espacios, de modo que se aconvierte en A y se cconvierte en una lista de las palabras que comprenden C. Las copias B se ignoran ya que wordsexprime múltiples espacios (que el resto del programa evita).
  • drop 50ses una cadena con una longitud igual al número n de copias B en la entrada. drop 50s>>bconcatena esa cantidad de copias b, dando mn espacios.
  • unwords$a:(drop 50s>>b):cune todas las cadenas nuevamente con espacios. Como hay una "palabra" adicional (drop 50s>>b)insertada en la lista, también hay un espacio de unión adicional, que agrega automáticamente el +1 a la multiplicación.
Ørjan Johansen
fuente
2

Matlab, 85

La primera vez que hice un desafío tan abstracto, ¡para mí fue más un desafío de codificación que un desafío de código de golf!

Las tres cadenas son, sin las comillas:

A:    "X=strsplit(input('','s'));m=0 "
B:    "+1 "
C:    ";[X{1},32,repmat(['+1',32],1,m*(length(X)-2)+1),X{end}]"

Cómo funciona: divido el argumento de entrada en el espacio en blanco, por lo que nse puede determinar a partir del número de partes de la cadena. B funciona como una especie de contador para obtener m. Para reconstruir la respuesta, uso A y C de la división, repito B m * n + 1 veces e inserto los espacios usando su valor ASCII, para que no se produzcan divisiones no deseadas en C.

EDITAR: whoops, accidentalmente contado A + B

Oebele
fuente
1

C (gcc) , 81 bytes

El requisito de identificar las cadenas parece estar en desacuerdo con que se nos permita un comportamiento arbitrario para la entrada ilegal, a menos que tengamos estándares bastante laxos de lo que implica la identificación. Naturalmente, tomé la interpretación que arroja la mayor cantidad de bytes.

Pruébalo en línea!

A: m;f(char*s){m=strrchr(s+66,32)-s-65;printf("%.66s%*s",s,m*strlen("
B: <SPACE>
C: ")+16,s+m+66);}
gastropner
fuente
Por la identificación Sólo quería decir que debe quedar claro a partir de su respuesta, que son fragmentos de código A , B y C . No es un requisito para el programa.
Zgarb
1

TI-Basic (serie 83), 65 bytes

Segmento A (33 bytes):

Input Str1:sub(Str1,1,27:For(I,0,(length(Str1)-55)(length("

Segmento B:

X

Segmento C (32 bytes):

Y")-1:Ans+"X":End:Ans+sub(Str1,length(Str1)-27,28

¡Estoy realmente emocionado de encontrar este desafío parecido a una quine! La mayoría de las quines no funcionan en TI-Basic sin al menos un poco de trampa, porque no hay forma de escapar del "símbolo. (En ambos sentidos de la palabra "escape".) Pero aquí, obtenemos una cadena de entrada a través del Inputcomando, y al escribir a "está perfectamente bien.

Todavía hay una cierta cantidad de tonterías de TI-Basic para trabajar por aquí: una cadena vacía no es válida, por lo que la solución ingenua de insertar la cadena "XXX...XX"en un bucle no funcionará cuando n = 0. En cambio, calculamos manualmente el valor de mn + 1 e insertamos la cadena "X"muchas veces.

Las constantes de magia 27y 28en el programa son un poco fuera de la cantidad de bytes 33 y 32, porque Str1, sub(y length(son tokens de dos bytes que sólo contribuyen 1 a la longitud de una cadena.

Si usamos nuevas líneas en lugar de :, parece que podemos ahorrar algunos bytes al dejar las comillas finales, pero esto en realidad no funciona. En primer lugar, necesita un editor hexadecimal antes de poder agregar el carácter de nueva línea en una cadena: no puede simplemente escribirlo, porque si presiona ENTRAR durante un Inputcomando, envía la entrada. Cuando probé el enfoque del editor hexadecimal, terminé obteniendo un extraño error de desbordamiento del búfer que modificó el contenido de mi programa, así que no intentes esto en casa con tu costosa calculadora.

Misha Lavrov
fuente
0

Java 11, 135 65 + 26 = 91 bytes

UNA

s->{var p=s.split("\\(\"|\"\\.");return p[0]+"(\"B"+p[1].repeat("

si

B

do

".length())+'"'+'.'+p[2];}

Pruébelo en línea aquí (TIO todavía no tiene Java 11, por lo que se basa en un método auxiliar en lugar de String::repeat()).

Sin golf:

s -> { // lambda taking and returning a String
    var p = s.split("\\(\"|\"\\."); // split input into parts A, B^n, C (where n may be 0) at the "(\"" and "\"."
    return p[0] + "(\"B" + // put it back together: A plus the part the split shaved off, plus an extra B ...
    p[1].repeat("BBB".length()) + // ... plus B^(n*m)
    '"' + '.' + p[2]; // plus C, with the part the split shaved off reattached
}
OOBalance
fuente