Espiral para fora o alfabeto!

13

Veja a seguinte string. Observe um padrão?

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

Como alguns devem ter notado, é basicamente uma espiral do alfabeto, onde as distâncias entre linhas / colunas aumentam gradualmente em 1 espaço / nova linha.

Definição rigorosa

  • Vamos ter um contador c , que é inicialmente 0.
  • Nós escrevemos a primeira c + 1 letras do alfabeto da esquerda para a direita: A.
  • Em seguida, de cima para baixo a próxima (c + 1) (c + 2) / 2 letras (ADD B): AB.

  • Da esquerda para a direita, o próximo (c + 1) (c + 2) / 2 (adicionar C):

    AB
     C
    
  • E de baixo para cima, as próximas c + 1 letras (adicionar D):

    AB
    DC
    
  • Atingiu o final do ciclo. Portanto, vamos incrementar c (que se torna 1). Em seguida, ele começa a partir do primeiro passo, a única diferença é que, em vez de usar as primeiras letras c + 1 do alfabeto, usamos as próximas letras c + 1 , começando no último elemento desse ciclo ( Dneste caso, então continuamos com EFG...). Quando Zé atingido, volta a partir de A.

Tarefa

Dado um número inteiro N (que é positivo para indexação 1 ou não negativo para indexação 0), produz os primeiros N ciclos da espiral.

Regras

  • Você pode usar o alfabeto minúsculo ou maiúsculo, mas sua escolha deve ser consistente (use apenas um deles, a mistura não é permitida).

  • Você pode obter entrada e fornecer saída através de qualquer um dos métodos padrão , em qualquer linguagem de programação , observando que essas brechas são proibidas por padrão.

  • Formatos de saída aceitáveis: sequência multilinha, uma lista de sequências representando linhas, uma lista contendo várias listas de caracteres, cada uma representando uma linha ou qualquer outra coisa que você achar adequado. Caso você não escolha o primeiro formato, seria bom incluir uma versão bonita do seu código.

  • Isso é , portanto o código mais curto em bytes (em cada idioma) que atende aos requisitos vence!


Casos de teste

O número inteiro de entrada será separado por sua saída correspondente por meio de uma nova linha e os testes serão separados usando traços. Observe que estes são indexados em 1.

1

AB
DC

--------

2

ABEF
DC G
MH
LKJI 

--------

3

ABEFNOP
DC GQ
MHR
LKJI S
DT
CU
BAZYXWV

-------

4

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

-------
5

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

------

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
OU 
NMLKJIHGFEDCBAZYXWVUTS
Mr. Xcoder
fonte
As caixas de teste devem ser n = 1,2,3,5,6, eu acho.
perfil completo de TFeld

Respostas:

9

Carvão , 31 bytes

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

Experimente online! Link é a versão detalhada do código. Nota: O deverbosifier gera um separador à direita por algum motivo. Explicação:

F⮌…⁰NB

Desenhe caixas na ordem inversa de tamanho (maior para o menor).

⁺²⊘×ι⁺³ι

Calcule o tamanho da caixa.

⭆α§α⁺λ

Desenhe a borda da caixa usando um alfabeto girado.

÷×ι⊕×ι⁺⁹⊗ι⁶

Calcule a letra que apareceria no canto superior esquerdo da caixa (indexado 0).

Neil
fonte
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

Experimente online!

Explicação

Construímos uma matriz vazia de espaços do tamanho certo, depois movemos sobre ela assim, começando no canto superior esquerdo:

  • 1 passo →, 1 passo ↓, 1 passo ←, 1 passo ↑

  • 3 passos →, 3 passos ↓, 3 passos ←, 3 passos ↑

  • 6 passos →, 6 passos ↓, 6 passos ←, 6 passos ↑

  • 10 passos →, 10 passos ↓, 10 passos ←, 10 passos ↑

  • ...

Sempre que encontramos uma célula em branco, colocamos uma letra lá e alternamos para a próxima letra do alfabeto.

No código, s%4é a direção (→ ↓ ← ↑), e pisamos isso várias vezes:

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

Oportunidades de golfe

  • Existe um caminho mais curto para mapear s%4a 1,0,-1,0que abs(2-s%4)-1?

  • Existe um caminho mais curto para mapear s%4a 0,1,0,-1que s%2-s%4/3*2?

Créditos

  • O Sr. Xcoder salvou um byte.
Lynn
fonte
2
+1 Uau, isso é simplesmente brilhante. Demorei um pouco para descobrir como funciona. Encontrei uma abreviação para 21/(s%4+3)%3-1: s%2-2*(s%4>2)( 179 bytes ). Ainda pode ser jogável
Mr. Xcoder
4

C,  305  281 bytes

Graças a @Mr. Xcoder para salvar quatro 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++]);}

Experimente online!

Steadybox
fonte
1
Primeira vez que vejo um #definefor for((que realmente salva bytes). +1 de mim. :)
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

Experimente online!

Novo método com mais matemática!

Retorna uma lista de listas de caracteres.


Versão antiga:

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]

Experimente online!

TFeld
fonte
@ Mr.Xcoder Não é .49suficiente o suficiente nesse caso, ou falha em entradas muito grandes?
Kevin Cruijssen
1
@KevinCruijssen Não tenho certeza, mas isso funciona com certeza, 260 bytes .
Mr. Xcoder
Eu não conheço Python tão bem, mas é possível criar uma variável embutida para i<j, já que você a usa quatro vezes?
Kevin Cruijssen
1
245 bytes por golfe +1==1+do meu método anterior
Mr. Xcoder
1

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

2 bytes salvos graças ao 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

Experimente online

Nahuel Fouilleul
fonte
Você pode salvar um byte usando em -1vez de $#O. Também usando $,em vez de $nvai deixar você remover o espaço antes forem$_.=$"x$n for@O
Xcali
obrigado, eu estava procurando por outras melhorias, mas não consegui encontrar por enquanto
Nahuel Fouilleul / 01/17
salvo mais 2 bytes mudança expressão regular s/ (?=\S)/n/eas/.*\K /n/e
Nahuel FOUILLEUL