Espiral fuera del alfabeto!

13

Mira la siguiente cadena. ¿Ves un patrón?

ABEFNOPEFGH
DC GQI
MHRJ
LKJI SK
DTL
SEMEN
BAZYXWV N
EO
DP
CQ
BAZYXWVUTSR

Como algunos habrán notado, es básicamente una espiral del alfabeto, donde las distancias entre filas / columnas aumentan gradualmente en 1 espacio / nueva línea.

Definición rigurosa

  • Tengamos un contador c , que inicialmente es 0.
  • Escribimos la primera c + 1 letras del alfabeto, de izquierda a derecha: A.
  • Entonces, de arriba a abajo la siguiente (c + 1) (c + 2) / 2 cartas (ADD B): AB.

  • De izquierda a derecha, el siguiente (c + 1) (c + 2) / 2 (agregar C):

    AB
     C
    
  • Y de abajo hacia arriba, las siguientes letras c + 1 (agregar D):

    AB
    DC
    
  • Alcanzado el final del ciclo. Por lo tanto, incrementemos c (que se convierte en 1). Luego, comienza desde el primer paso, la única diferencia es que en lugar de usar las primeras letras c + 1 del alfabeto, usamos las siguientes c + 1 letras , comenzando desde el último elemento de este ciclo ( Den este caso, entonces continuamos con EFG...). Cuando Zse alcanza, retrocede desde A.

Tarea

Dado un número entero N (que es positivo para la indexación 1 o no negativo para la indexación 0), genera los primeros N ciclos de la espiral.

Reglas

  • Puede usar el alfabeto en minúsculas o mayúsculas, pero su elección debe ser coherente (solo use uno de ellos, no se permite mezclar).

  • Puede tomar entradas y proporcionar salidas a través de cualquiera de los métodos estándar , en cualquier lenguaje de programación , mientras observa que estas lagunas están prohibidas de manera predeterminada.

  • Formatos de salida aceptables: cadena multilínea, una lista de cadenas que representan líneas, una lista que contiene múltiples listas de caracteres, cada una representando una línea, o cualquier otra cosa que considere adecuada. En caso de que no elija el primer formato, sería bueno incluir una versión bonita de su código.

  • Este es el , por lo que gana el código más corto en bytes (en cada idioma) que cumpla con los requisitos.


Casos de prueba

El entero de entrada se separará por su salida correspondiente a través de una nueva línea, y las pruebas se separarán con guiones. Tenga en cuenta que estos están indexados en 1.

1

AB
corriente continua

--------

2

ABEF
DC G
MH
LKJI 

--------

3

ABEFNOP
DC GQ
MHR
LKJI S
DT
CU
BAZYXWV

-------

4 4

ABEFNOPEFGH
DC GQI
MHRJ
LKJI SK
DTL
SEMEN
BAZYXWV N
EO
DP
CQ
BAZYXWVUTSR

-------
5 5

ABEFNOPEFGHFGHIJ
DC GQIK
MHRJL
LKJI SKM
DTLN
CUMO
BAZYXWV NP
EOQ
DPR
CQS
BAZYXWVUTSR T
RU
QV
PW
BUEY
NMLKJIHGFEDCBAZY

------

6 6

ABEFNOPEFGHFGHIJSTUVWX
DC GQIKY
MHRJLZ
LKJI SKMA
DTLNB
CUMOC
BAZYXWV NPD
EOQE
DPRF
CQSG
BAZYXWVUTSR TH
RUI
QVJ
PWK
OXL
NMLKJIHGFEDCBAZY M
SN
RO
QP
PQ
O 
NMLKJIHGFEDCBAZYXWVUTS
Sr. Xcoder
fuente
Los casos de prueba deberían ser n = 1,2,3,5,6, creo.
TFeld

Respuestas:

9

Carbón , 31 bytes

F⮌…⁰NB⁺²⊘×ι⁺³ι⭆α§α⁺λ÷×ι⊕×ι⁺⁹⊗ι⁶

Pruébalo en línea! El enlace es a la versión detallada del código. Nota: El desverbosificador genera un separador final por alguna razón. Explicación:

F⮌…⁰NB

Dibuje cuadros en orden inverso de tamaño (de mayor a menor).

⁺²⊘×ι⁺³ι

Calcule el tamaño de la caja.

⭆α§α⁺λ

Dibuja el borde de la caja usando un alfabeto rotado.

÷×ι⊕×ι⁺⁹⊗ι⁶

Calcule la letra que aparecería en la esquina superior izquierda del cuadro (indexada en 0).

Neil
fuente
6

Python 2 , 176 bytes

n=input()
k=n*-~n/2+1
a=eval(`[[' ']*k]*k`)
x=y=z=0
for s in range(4*n+4):exec s/4*(s/4+1)/2*"if'!'>a[y][x]:a[y][x]=chr(z%26+65);z+=1\nx+=abs(2-s%4)-1;y+=s%2-s%4/3*2\n"
print a

Pruébalo en línea!

Explicación

Construimos un conjunto vacío de espacios del tamaño correcto, luego lo movemos así, comenzando en la esquina superior izquierda:

  • 1 paso →, 1 paso ↓, 1 paso ←, 1 paso ↑

  • 3 pasos →, 3 pasos ↓, 3 pasos ←, 3 pasos ↑

  • 6 pasos →, 6 pasos ↓, 6 pasos ←, 6 pasos ↑

  • 10 pasos →, 10 pasos ↓, 10 pasos ←, 10 pasos ↑

  • ...

Cada vez que encontramos una celda en blanco, ponemos una letra y pasamos a la siguiente letra del alfabeto.

En el código, s%4es la dirección (→ ↓ ← ↑), y lo hacemos varias veces:

TriangularNumber(s/4) = s/4*(s/4+1)/2.

Oportunidades de golf

  • ¿Hay un camino más corto para mapear s%4a 1,0,-1,0que abs(2-s%4)-1?

  • ¿Hay un camino más corto para mapear s%4a 0,1,0,-1que s%2-s%4/3*2?

Créditos

  • El Sr. Xcoder guardó un byte.
Lynn
fuente
2
+1 Wow, esto es simplemente genial. Me llevó un tiempo descubrir cómo funciona. Encontré una taquigrafía para 21/(s%4+3)%3-1: s%2-2*(s%4>2)( 179 bytes ). Aún podría ser golfable aunque
Sr. Xcoder
4

C,  305  281 bytes

Gracias a @Mr. Xcoder para guardar cuatro bytes!

#define L(x,y)l[x][y]=a++%26+65;
#define F for(
c,i,j,a,p;f(n){char**l=calloc(8,i=a=n*n*4);F;i--;memset(l[i],32,a))l[i]=malloc(a);F c=a=p=i=0;c<n;++c){F i=p;i<c+p+!c;)L(j=0,c+i++)F p=i;j<=-~c*(c+2)/2;)L(j++,c+i)F;c+i-1;)L(j-1,c+--i)F i=0;i<=c;)L(j+~i++,0)}F i=0;i<j;)puts(l[i++]);}

Pruébalo en línea!

Steadybox
fuente
1
La primera vez que veo un #definefor for((que en realidad ahorra bytes). +1 de mi parte :)
Kevin Cruijssen
2

Python 2 , 262 260 254 245 bytes

lambda n:[[[' ',chr(65+(4*(i<j)+sum((i<j)*8+2+I*[5,9][i<j]+sum(2*R(I))for I in R(S(i,j)-1))+[i+j,-i-j][i<j])%26)][max(i,j)==S(i,j)*-~S(i,j)/2or i*j<1]for i in R(1+n*-~n/2)]for j in R(1+n*-~n/2)]
R=range
S=lambda x,y:int((8*max(x,y)+1)**.5+.99)/2

Pruébalo en línea!

¡Nuevo método con más matemáticas!

Devuelve una lista de listas de caracteres.


Versión antigua:

Python 2 , 322 321 308 298 bytes

R=range
n=input()
w=1+n*-~n/2;r=[w*[' ']for _ in R(w)];r[0][0]='A';l=R(1,w*w*9);c=lambda:chr(65+l.pop(0)%26)
for i in R(n+1):
 w=1+i*-~i/2;W=w-i
 for x in R(W,w):r[0][x]=c()
 for y in R(1,w):r[y][w-1]=c()
 for x in R(1,w):r[w-1][w+~x]=c()
 for x in R(1,w-W):r[w+~x][0]=c()
for l in r:print`l`[2::5]

Pruébalo en línea!

TFeld
fuente
@ Mr.Xcoder ¿No es .49suficiente en ese caso, o falla para entradas muy grandes?
Kevin Cruijssen
1
@KevinCruijssen No estoy seguro, pero esto funciona con seguridad, 260 bytes .
Sr. Xcoder
No conozco Python tan bien, pero ¿es posible hacer una variable en línea i<j, ya que la está usando cuatro veces?
Kevin Cruijssen
1
245 bytes jugando al golf +1==1+con mi método anterior
Sr. Xcoder,
1

Perl 5, 177 +2 (-nl) = 179 bytes

2 bytes guardados gracias a Xcali

sub n{chr 65+$c++%26}@O=(n);while($,++<$_){$_.=$"x$,for@O;push@O,($"x length$O[0])x$,;$O[0]=~s/ /n/eg;s/ $/n/e for@O;1while$O[-1]=~s/.*\K /n/e;s/^ /n/e for reverse@O}print for@O

Pruébalo en línea

Nahuel Fouilleul
fuente
Puede guardar un byte utilizando en -1lugar de $#O. También usando $,en lugar de $nle permitirá quitar el espacio antes forde$_.=$"x$n for@O
Xcali
gracias, estaba buscando otras mejoras pero no pude encontrar por el momento
Nahuel Fouilleul
guardó 2 bytes más cambiando la expresión regular s/ (?=\S)/n/eas/.*\K /n/e
Nahuel Fouilleul