Cree un cuadrado de tamaño creciente replicando el código inicial

45

Su tarea es escribir un programa de longitud uniforme , que imprima un cuadrado de arte ASCII (descrito a continuación), que aumente su longitud lateral en 1 unidad cada vez que se pegue el código fuente original en el medio del código actual.

Me resulta bastante difícil definir esta tarea muy bien, así que te daré un ejemplo:

  • Digamos que su código inicial fue CODEy que se imprimió:

    0
    
  • Luego, inserte CODEen el medio: su código se convierte COCODEDEy debería imprimir:

    00
    00
    
  • Vuelva a insertar CODEen el medio: su código se convierte COCOCODEDEDE y debe imprimir:

    000
    000
    000
    
  • Y así. Teóricamente, su respuesta debería funcionar después de cualquier número de iteraciones, pero entiendo si, debido a las limitaciones de rendimiento del lenguaje, no puede ejecutarse razonablemente por encima de un cierto umbral.

Algunas reglas:

  • Puedes usar cualquier ASCII imprimible (32-127) como el personaje a usar para tu cuadrado. Su elección debe ser constante (debe usar el mismo carácter para cada iteración).

  • El cuadrado de salida inicial debe tener una longitud lateral 1 .

  • Un cuadrado ascii-art se define como una cadena con N líneas (separadas por saltos de línea N-1 / líneas nuevas) y cada línea contiene N copias del carácter elegido.

  • Su salida no puede contener ningún espacio en blanco extraño, que no sea una nueva línea final.

  • Puede usar los valores predeterminados para entrada y salida (los programas o funciones están permitidos, pero los fragmentos no lo están).

  • La mitad de su código se define como el punto donde el código fuente se puede dividir en dos partes, de modo que las dos sean iguales.

  • Sus respuestas se puntuarán por la duración de su programa original , en bytes. El conteo de bytes más bajo gana. En caso de que haya un empate, la respuesta que se envió anteriormente gana.

  • Puede usar este programa para aplicar las inserciones sin tener que hacerlo manualmente.


fuente
1
Debo admitir que me inspiró esta pregunta de quine publicada anteriormente . Si la gente piensa que está demasiado cerca, felizmente lo eliminaré. También discúlpeme si cometí algún error, todavía no tengo mucha experiencia con las reglas aquí. :)
2
Bienvenido a PPCG! Sugiero usar el Sandbox para tus desafíos futuros.
user202729
77
Bienvenido al sitio! Excelente uso de otro desafío para la inspiración sin caer en la trampa de engaños :)
Shaggy
Su programa auxiliar no funciona para programas con varias líneas. ¿Qué tal esta versión modificada de la otra pregunta?
Jo King
1
@ user77954 Pero mi código de brainfuck es más corto que tu python :( (¿alguien ha dicho eso antes?)
Jo King

Respuestas:

41

Pyth , 2 bytes


5

Pruébalo en línea! También Pruébalo duplicado , triplicado !

¿Cómo funciona?

\nes el comando que imprime su argumento con una nueva línea final, mientras la devuelve simultáneamente. Por lo tanto, cada vez que realiza una inserción, convierte el entero literal 5 en un número que contiene N copias de 5 concatenados, y las nuevas líneas principales básicamente se aseguran de que se imprima el número apropiado de veces, manteniéndolo así cuadrado.

Sr. Xcoder
fuente
66
Frick Santo que es corta ...
ETHproductions
Prueba de optimización (: P): dado que el recuento de bytes debe ser par y no puede ser negativo, el recuento de bytes mínimo posible es de 0 bytes. Hay exactamente 1 programa de 0 bytes, que no cumple la tarea. Por lo tanto, 2 bytes es óptimo.
Sr. Xcoder
10
Todos (especialmente los votantes HNQ), también voten a favor de otras respuestas y eviten el efecto FGITW.
user202729
25

JavaScript (ES6), 42 32 30 bytes

s=[this.s]+0;  console.log(s);

Segunda iteración:

s=[this.s]+0;  s=[this.s]+0;  console.log(s);console.log(s);

Esto funciona agregando 0a scada vez que se ejecuta la primera mitad del código, e imprimiéndose scada vez que se ejecuta la segunda mitad. Aprovecha cuatro peculiaridades de JavaScript:

  1. Se puede hacer referencia al entorno actual con this. Esto nos permite hacer this.sen lugar de s.
  2. Al acceder a una propiedad que no se ha definido en un objeto, en lugar de arrojar un error, JavaScript regresa undefined.
  3. Una matriz más un número devuelve una cadena. [1,2,3] + 4 === "1,2,34"
  4. Al encadenar una matriz, undefinedse convierte en la cadena vacía, lo que significa que [undefined] + 0 === "0".

En conjunto, esto significa que podemos expresar la primera mitad (generando una cadena de ceros) en solo 13 bytes. Si se permite el uso en alertlugar de console.log, podemos ahorrar 4 bytes más acortando la segunda mitad.

ETHproducciones
fuente
Felicidades, pasa las pruebas que he hecho!
1
... ¡Ingenioso! :)
Shaggy
13

Python 2 , 22 bytes

i=0;i+=1; i
print'*'*i

Pruébalo en línea!

Doblado:

i=0;i+=1; ii=0;i+=1; i
print'*'*i
print'*'*i

Tenga en cuenta que la segunda mitad comienza con un carácter de nueva línea.

xnor
fuente
9

C (gcc) , 170 168 96 80 72 70 bytes

Versión mucho más corta. Todavía deseo poder encontrar una solución sin el preprocesador.

i;main(n){for(;i++<n;)printf
#if 0

#endif
(" %*c",n=__LINE__/4, 10);}

Pruébalo en línea!

Antigua versión de 168 bytes:

#ifndef A
#define A p(c){putchar(c);}j,n;main(i){for(
#else
#define A n++,
#endif
A



#ifndef B
#define B i=++n;i--;p(10))for(j=n;j--;)p(64);}
#else
#define B
#endif
B

Pruébalo en línea!

gastropner
fuente
¿No parece funcionar ?
user202729
@ user202729 ah, sí. Pensé que arreglé un error tipográfico pero introduje un error. Revertir
Gastropner
8

Python 2 , 30 bytes

False+=1      ;print'*'*False;

Pruébalo en línea! , 2da y 3ra iteración

Esto hace uso del hecho de que los bools en Python son básicamente ints y los nombres Falsey Truefueron reasignables en Python 2.

Python 1 , 32 bytes

exit=exit+'*'  ;print exit[30:];

Pruébalo en línea! , 2da y 3ra iteración

En Python 1 las cadenas incorporadas exity quitexistido para informar al usuario de la consola interactiva cómo salir de ella. El valor por defecto es "Use Ctrl-D (i.e. EOF) to exit.".

ovs
fuente
1
Iba a sugerir n=False+=1;print'*'*n;, pero sigo olvidando que esa no es una característica de Python ...
ETHproductions
6

Carbón de leña , 6 bytes

⊞υωLυ⸿

Pruébalo en línea! Explicación:

  ω     Predefined empty string (any variable would do here)
 υ      Predefined initially empty list
⊞       Push

υ termina con una longitud del número de repeticiones.

    υ   List
   L    Length
        Implicitly print as a row of `-`s
     ⸿  Move to start of next line
Neil
fuente
6

Haskell , 68 bytes

let s@(z:n)="0\n"in case lines<$>[]of(h:t):_->(h:h:t)>>(z:h++n);_->s

Pruébelo en línea una , dos o tres veces .

Debido a la pereza de Haskell, una expresión como la anterior cuenta como una función que no tiene argumentos, según esta pregunta Meta .

Laikoni
fuente
5

Brain-Flak , 74 bytes

(((((()()()){}){}){}){})((()()()()()<>){})<>([]){({}[()]<(({})<>)<>>)}{}<>

Pruébalo en línea!

Pruébalo doblado y triplicado .

Explicación

(((((()()()){}){}){}){}) # push 48 ("0") onto first stack
((()()()()()<>){})       # push 10 (\n) onto second stack
<>([]){({}[()]<          # a number of times equal to the height of the first stack:
  (({})<>)<>             #   copy the top of the first stack to the second stack
>)}{}<>                  # cleanup and return to second stack

El punto de ruptura está en el medio de la <>sección "empuje 10". Romper esto dejará un 5 en la tercera pila hasta que lleguemos a la segunda mitad correspondiente, momento en el que presionar 10 se reanudará justo donde lo dejó.

Si bien es posible empujar un valor ASCII imprimible (espacio) en 22 bytes, esto haría que la central <>se ejecute después de presionar 5. Al agregar dos bytes más, pude mover el <>para que todo el progreso hacia el empuje 10estuviera en la tercera pila. Como beneficio adicional, esto también hizo que el cuadrado resultante fuera más estéticamente agradable.

Nitrodon
fuente
4

tinylisp , 112 bytes

(load library) (d N((q((x)(i x(inc x)1)))(v(h(t(t(h(t(q())))))))))(join(repeat-val(string(repeat-val 42 N))N)nl)

Pruébalo en línea! También duplicado y quíntuple .

El enfoque de "construir una cadena en la primera mitad, imprimirlo en la segunda mitad" que toman muchos idiomas no funcionará en tinylisp, ya que no hay variables mutables. En cambio, hacemos un anidamiento de código serio.

Cuando se inserta una segunda copia del código, se coloca dentro del (q()), que lo envuelve en una lista. Luego se (h(t(t(h(t(...))))))profundiza en esa lista para la parte posterior (d N. (v(...))lo evalúa luego lo pasamos a la función sin nombre (q((x)(i x(inc x)1))), que incrementa el valor resultante si es un número y devuelve 1 si es la lista vacía. Se asigna el resultado final en la versión anidada más externa del código N. En esencia, hemos establecido un tipo extraño de recursión que cuenta el número de niveles de anidación.

La segunda mitad del código crea una cadena de Nasteriscos, luego una lista de Ntales cadenas, luego se une a la lista en las nuevas líneas. El resultado se muestra con una nueva línea final.

DLosc
fuente
3

R , 44 bytes

F=F+1;T=TRUE*TRUE+12;
write(strrep(1,F),"");

Pruébalo en línea!

Imprime con una nueva línea final. El T=TRUE*TRUE+12es solo para rellenar la longitud.

Inténtalo doblado e Inténtalo triplicado .

Giuseppe
fuente
Puede eliminar 2 bytes eliminando los puntos y comas. Supongo que hay un espacio al final de la primera línea, que puede reemplazar con un #: F=F+1;T=TRUE*TRUE+12#<nueva línea>write(strrep(1,F),"")
Andreï Kostyrka
@ AndreïKostyrka sería de 43 bytes, lo cual, lamentablemente, ni siquiera es.
Giuseppe
3

Julia 0.6 , 29 bytes

Todas mis ideas fueron más largas que adaptar la solución inteligente de Python de xnor.

i=0;i+=1;    i
println("0"^i)

Se convierte

i=0;i+=1;    ii=0;i+=1;    i
println("0"^i)
println("0"^i)

Pruébalo en línea!

gggg
fuente
3

SNOBOL4 (CSNOBOL4) , 130 68 bytes

Ahora sin comentarios! Consulte el historial de edición para obtener una explicación del antiguo algoritmo.

	X =X + 1
	A =ARRAY(X,DUPL(1,X));
I	I =I + 1
	OUTPUT =A<I>	:S(I)
END

Pruébalo en línea!

Pruébalo doblado y triplicado

Explicación:

	X =X + 1		;* increment X
	A =ARRAY(X,DUPL(1,X));	;* create an x-length array with 1 repeated x times for each element
I	I =I + 1		;* for i < x
	OUTPUT =A<I>	:S(I)	;* output a[i]
END

Como ENDse requiere una etiqueta y ENDse ignora cualquier cosa después de la primera etiqueta, obtenemos dos ventajas para este desafío:

  • las operaciones en la primera mitad del programa se repiten Xveces para las Xrepeticiones
  • (para el intérprete) solo existirá una copia de la segunda mitad, incluidas las etiquetas .

Esto sugiere que usemos la repetición para la primera mitad, y luego podemos usar un enfoque de etiquetado más "convencional" para repetir los Xtiempos de salida .

La primera mitad es

	X =X + 1
	A =ARRAY(X,DUPL(1,X));

que, cuando se repite, incrementa Xel número apropiado de veces, y crea una ARRAY Acon índices de 1a Xy donde cada elemento de Aes la cadena 1repetida Xveces.

Entonces, no importa cuántas veces se repita el programa, el intérprete solo ve:

I	I =I + 1
	OUTPUT =A<I>	:S(I)
END

que es un programa SNOBOL típico que imprime los elementos de Auno en uno hasta que el índice se sale de los límites, luego termina el programa.

;es un terminador de línea opcional generalmente reservado para una línea EVALo CODEdeclaraciones que lleva el recuento de bytes a 68 y marca el punto medio, permitiendo que el código se agregue allí.

Giuseppe
fuente
1

Zsh , 10 bytes

s+=0
<<<$s

¡Pruebe una suite de prueba completa en línea!

... sí, esto es un poco mejor. Agregue a la cadena N veces, luego imprima N veces. Resulta que <<<foo<<<foofunciona bien.


Zsh , 64 bytes

Carácter utilizado: (espacio).

f(){printf '%*s\n' $1}
:<<'E'

E
repeat $[i=LINENO/3];f $i
exit

¡Pruebe una suite de prueba completa en línea!

El punto medio está entre el segundo Ey la nueva línea que lo sigue. Un heredoc terminará cuando haya un Een una línea por sí mismo, lo que ocurre justo en el medio del código.

Función Gamma
fuente
lol @ "leve" mejora. también podría expresarlo comos+=0;<<<$s
roblogic