Una espiral ASCII bien espaciada

13

Considera esta espiral

###########
#
# #######
# #     #
# # ### #
# # # # #
# # # # #
# #   # #
# ##### #
#       #
#########

Comenzando en el centro:

  • La primera línea (hacia arriba) tiene 3 caracteres.
  • La segunda línea tiene el mismo número de caracteres (3)
  • A continuación, agregamos dos caracteres (5) para los siguientes dos lados.
  • Este patrón continúa, dos lados de la misma longitud y luego aumentan la longitud en 2.

Quiero generar esta espiral para N líneas.

  • Escribe en cualquier idioma.
  • La entrada / argumento, etc. es el número de líneas en su espiral.
  • Cada línea comienza con el carácter final de la línea anterior en la dirección de 90 grados en el sentido de las agujas del reloj de la línea anterior.
  • No me importa cuánto espacio en blanco hay antes o después de cada línea, siempre que los elementos de la espiral se alineen.
  • Imprima texto para dibujar la espiral con cualquier carácter que no sea un espacio en blanco que elija.
  • Intente hacer esto en el menor número de bytes.

Casos de prueba (usando un hash como salida):

N = 1

#
#
#

N = 2

###
#
#

N = 3

###
# #
# #
  #
  #

N = 10

###########
#
# #######
# #     #
# # ### #
# # # # #
# # # # #
# #   # #
# ##### #
#       #
#########
AJFaraday
fuente
@Shaggy "Texto de salida para dibujar la espiral con cualquier carácter que no sea un espacio en blanco que elija". Sí, lo que quieras.
AJFaraday
3
Relacionado 1 ; Relacionado 2 .
Kevin Cruijssen
3
La imagen inicial tiene un en *lugar de #. ¿Esperado?
Wernisch
@Wernisch Fue un punto de partida útil, pero supongo que es engañoso. Puedes usar cualquier personaje que quieras.
AJFaraday

Respuestas:

11

05AB1E , 13 11 bytes

Código:

Gracias a Emigna por guardar dos bytes!

LDÈ-Ì'#3Ý·Λ

Utiliza la codificación 05AB1E . Pruébalo en línea!

Explicación

La longitud de cada borde individual en la espiral comienza con la longitud 3 y aumenta gradualmente cada dos pasos en dos:

3,3,5 5,5 5,7 7,7 7,9 9,...

nortenorte

L                # Create a list from [1 .. input]
 DÈ              # Duplicate and check for each number if even
   -             # Subtract that from the first list
    Ì            # Add 2

Esto básicamente nos da la lista deseada de longitudes.

     '#          # Push the '#' character
       0246S     # Push the array [0, 2, 4, 6]
            Λ    # Write to canvas

El lienzo funciona como una función que muestra tres parámetros (donde el parámetro más a la derecha aparece primero): <longitud (s)> , <char (s)> , <dirección (s)> . El parámetro de direcciones es en este caso una lista de números. Los números que corresponden a las direcciones son:

[7 70 016 625 54 43]

En este caso, [0, 2, 4, 6] corresponde a la lista de instrucciones [↑, →, ↓, ←]. El lienzo itera sobre cada longitud recuperada de la lista de longitudes, usa el carácter '#' e itera cíclicamente sobre la lista de direcciones.

Adnan
fuente
0246S=3Ý·
Emigna
@Emigna Ah, no pensé en eso, ¡gracias!
Adnan
6

Python 2 , 176 170 165 161 157 bytes

g=lambda a,r:r and g(map(''.join,zip(*a))[::-1],r-1)or a
R=['#']
n=1
exec"R=g(['  '+l for l in g(R,n)][:-1]+[(n+2)*'#'],3*n);n+=1;"*input()
print'\n'.join(R)

Pruébalo en línea!

Repetidamente: utiliza gpara rotar la niteración de la espiral en una posición 'canónica' (similar a N = 3 o N = 7), agrega un nuevo segmento agregando 2 espacios a la izquierda de cada fila existente, y luego reemplaza la última fila con todos los '#'s (lo que da como resultado una posición comparable a N = 4 o N = 8), y finalmente usar gnuevamente para rotarlo de nuevo a la posición correcta. Enjabonar, enjuagar, repetir.

Chas Brown
fuente
4

Carbón , 16 15 14 bytes

↶FN«¶×#⁺³⊗÷ι²↷

-2 bytes gracias a @Neil .

Pruébelo en línea (detallado) o Pruébelo en línea (puro) .

Explicación:

La dirección de impresión está a la derecha por defecto, y queremos comenzar hacia arriba, por lo que comenzamos girando 45 grados en sentido antihorario:

PivotLeft();
↶

Luego haga un bucle ien el rango [0, input):

For(InputNumber()){ ... }
FN« ...

Imprima una nueva línea para imitar el efecto de retroceder una posición:

Print("\n");
¶

Imprimir "#" xcantidad de veces en la dirección actual:

Print(Times("#", ... ));
×# ...

Donde xes 3 + i // 2 * 2:

Add(3,Doubled(IntegerDivide(i,2))
⁺³⊗÷ι²

Y luego gire 45 grados en el sentido de las agujas del reloj para la siguiente iteración del bucle:

PivotRight();
↷
Kevin Cruijssen
fuente
¿Supongo que no hay comando en Charcoal para moverse hacia atrás?
Emigna
@Emigna No estoy seguro, pero tampoco pude encontrarlo. Estaba buscando uno yo mismo cuando estaba escribiendo esta respuesta. Hay un movimiento con una dirección dada, así como un salto con coordenadas dadas, pero desafortunadamente no es un MoveBack.
Kevin Cruijssen
1
⊗÷ι²es un byte más corto que ⁻ι﹪ι². Además, puede obtener el efecto de retroceder imprimiendo un \nantes del #s, lo que le permitirá eliminar el »#para guardar un byte general adicional.
Neil
@Neil Gracias por el ⊗÷ι², pero ¿cuáles serían los cambios para imprimir un \nantes del #s? La espiral es incorrecta si agrego elPrint("\n") .
Kevin Cruijssen
Debido a que los brazos ahora se superponen, debes hacerlos más #largos.
Neil
3

Pitón 2 , 179 178 bytes

gracias a Kevin Cruijssen por -1 byte.

n=input()
S,H=' #'
m=[S*n]*(n%2-~n)
x=n/4*2
y=0--n/4*2
k=2
m[y]=S*x+H+S*n
M=[1,0,-1,0]*n
exec'exec k/2*2*"x+=M[~k];y+=M[k];m[y]=m[y][:x]+H+m[y][x+1:];";k+=1;'*n
print'\n'.join(m)

Pruébalo en línea!


Python 2 , 179 bytes

En este enfoque, se usan fórmulas para xy ydeltas en lugar de una lista de búsqueda.

n=input()
S,H=' #'
m=[S*n]*(n%2-~n)
x=n/4*2
y=0--n/4*2
k=2
m[y]=S*x+H+S*n
exec'exec k/2*2*"x+=k%-2+k%4/3*2;y-=(k%2or k%4)-1;m[y]=m[y][:x]+H+m[y][x+1:];";k+=1;'*n
print'\n'.join(m)

Pruébalo en línea!

ovs
fuente
n+1+n%2a n%2-~npara -1 byte. Y necesito recordar 0--n/4*2ser 1 más bajo que -(-n/4*2). Buena respuesta, +1 de mi parte.
Kevin Cruijssen
1

JavaScript (ES6), 185 bytes

Claro que esto se puede jugar más, tal vez con curry, pero aquí está mi intento muy humilde. Se agregaron saltos de línea para facilitar la lectura, excepto el penúltimo carácter.

r=(a,n=1)=>n?r(a.reduce((_,c)=>c).map((_,i)=>a.map(e=>e[i])).reverse(),n-1):a,
s=n=>n?r(s(n-1)).map((r,i)=>[...r,w,w].map(x=>i?x:'#')):[[w=' ']],
d=n=>r(s(n),1-i).map(r=>r.join``).join`
`

Uso: d(10)devuelve una cadena según el ejemplo de desafío N = 10.

Define una función r(a,n)para rotar una matriza por nturnos; una función s(n)para generar una matriz bidimensional que representa una espiral de tamaño nmediante la rotación recursiva y la adición de espacios y líneas (no girado de nuevo a la posición inicial); y una función d(n)para dibujar una espiral de tamaño n, rotar consistentemente según el desafío, y representar como una cadena devuelta.

Este fue un desafío muy divertido: ¬)

Chris M
fuente