Role o alfabeto em uma espiral

22

Escreva um programa ou função que, quando fornecido n, imprima uma espiral de ncaracteres composta há muito tempo pelo alfabeto latino, ABCDEFGHIJKLMNOPQRSTUVWXYZrepetida conforme necessário. Essa espiral deve percorrer o alfabeto apenas para a frente.

Relacionada à Espiral do Alfabeto , embora a espiral percorra o alfabeto para frente e para trás, e a espiral seja constante.

Casos de teste

4   AB
    DC

40   UVWXYZ
     TGHIJA
    NSFABKB
    MREDCLC
    LQPONMD
    KJIHGFE

0

10  GHIJ
    FAB
    EDC

1000    UVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ
        TGHIJKLMNOPQRSTUVWXYZABCDEFGHIJA
        SFABCDEFGHIJKLMNOPQRSTUVWXYZABKB
        REZCDEFGHIJKLMNOPQRSTUVWXYZABCLC
        QDYBMNOPQRSTUVWXYZABCDEFGHIJCDMD
        PCXALEFGHIJKLMNOPQRSTUVWXYZKDENE
        OBWZKDEFGHIJKLMNOPQRSTUVWXALEFOF
        NAVYJCDMNOPQRSTUVWXYZABCDYBMFGPG
        MZUXIBCLCDEFGHIJKLMNOPQREZCNGHQH
        LYTWHABKBABCDEFGHIJKLMNSFADOHIRI
        KXSVGZAJAZGHIJKLMNOPQROTGBEPIJSJ
        JWRUFYZIZYFUVWXYZABCDSPUHCFQJKTK
        IVQTEXYHYXETQRSTUVWXETQVIDGRKLUL
        HUPSDWXGXWDSPUVWXYZYFURWJEHSLMVM
        GTORCVWFWVCROTGHIJAZGVSXKFITMNWN
        FSNQBUVEVUBQNSFABKBAHWTYLGJUNOXO
        ERMPATUDUTAPMREDCLCBIXUZMHKVOPYP
        DQLOZSTCTSZOLQPONMDCJYVANILWPQZQ
        CPKNYRSBSRYNKJIHGFEDKZWBOJMXQRAR
        BOJMXQRARQXMLKJIHGFELAXCPKNYRSBS
        ANILWPQZQPWVUTSRQPONMBYDQLOZSTCT
        ZMHKVOPYPONMLKJIHGFEDCZERMPATUDU
        YLGJUNOXONMLKJIHGFEDCBAFSNQBUVEV
        XKFITMNWVUTSRQPONMLKJIHGTORCVWFW
        WJEHSLMLKJIHGFEDCBAZYXWVUPSDWXGX
        VIDGRKJIHGFEDCBAZYXWVUTSRQTEXYHY
        UHCFQPONMLKJIHGFEDCBAZYXWVUFYZIZ
        TGBEDCBAZYXWVUTSRQPONMLKJIHGZAJA
        SFAZYXWVUTSRQPONMLKJIHGFEDCBABKB
        REDCBAZYXWVUTSRQPONMLKJIHGFEDCLC
        QPONMLKJIHGFEDCBAZYXWVUTSRQPONMD
                                LKJIHGFE

Regras

  • Sua entrada será um número inteiro não negativo 0 <= n <= 1000, mas seu código deve lidar teoricamente com qualquer número inteiro não negativo.
  • Seu formato de saída pode estar em qualquer formato são, com delimitadores, se necessário.
  • Rotações e reflexões são equivalentes.
  • Seu alfabeto pode estar em maiúsculas ou minúsculas.
  • Os espaços vazios em sua espiral podem ser preenchidos com quaisquer nulos não alfabéticos que você achar conveniente.
  • A espiral em si pode ter qualquer forma que você achar melhor. Espirais retangulares funcionam melhor com soluções ASCII, mas soluções gráficas podem ser mais curtas com espirais circulares.
  • Espaços iniciais e finais e novas linhas são permitidos.
  • Isso é código de golfe. A resposta mais curta em bytes (ou equivalente) vence.

Como sempre, se algo não estiver claro ou incorreto, informe-me nos comentários. Boa sorte e bom golfe!

Sherlock9
fonte
a maioria dos editores não permitirá imprimir uma cadeia que longo
t-clausen.dk
@ t-clausen.dk Fui com o número inteiro máximo de 32 bits com sinal padrão. Se você tem uma melhor sugestão para um limite superior, eu ficaria feliz em editá-lo no.
Sherlock9
Nice and :-) complicado
Joffan

Respostas:

12

Logotipo, 129 87 bytes

Solução gráfica, implementada como função

Isso foi construído com o intérprete de logotipo da Calormen.com . A Sfunção pega o número de caracteres como parâmetro e os desenha em espiral. A Tfunção gera letras na vertical para impedir que elas girem com a espiral. . Decidi que parecia melhor (e reduziu em 42 bytes ) omitir a correção da orientação da letra. Também reforcei o espaçamento que não alterava a contagem de bytes. Se você realmente enrolar um alfabeto, seria mais parecido com isso de qualquer maneira.

Versão atualizada (rolo de cartas)

TO S:r
PU IF:r[REPEAT:r[LABEL CHAR((REPCOUNT-1)%26)+65
RT 99/SQRT(REPCOUNT)FD 12]]END

Invocação

Invoque da seguinte maneira: S iterações

Saída de amostra

S 1000

Saída de amostra para 1000 iterações

Versão antiga (letras sempre na vertical)

TO T:l:h
RT:h
LABEL CHAR(:l%26)+65
LT:h
END
TO S:r
PU IF:r[REPEAT:r[T REPCOUNT-1 90-HEADING
RT 95/SQRT(REPCOUNT)FD 15]]END

Saída antiga removida para economizar espaço. Veja aqui .

GuitarPicker
fonte
Não pergunte como eu criei a matemática. Tentei pesquisar fórmulas on-line, mas a maioria resolveu o problema mantendo o ângulo de virada constante e aumentando o comprimento do segmento, enquanto eu queria manter o comprimento do segmento constante e alterar o ângulo. Tentativa e erro parecem ter levado a uma fórmula estável. Ajustar o 95irá alterar a tensão da espiral e alterar o 15espaçamento linear das letras.
GuitarPicker 01/09/16
9

Javascript (ES6), 203 201 bytes

n=>{for(a=[],i=d=k=z=0,p=526,j=1;i<n;){p+=[1,32,-1,-32][d&3];j--||(((z^=1)||k++),j=k,d++);(a[y=p>>5]=(a[y]||Array(32).fill` `))[p&31]=String.fromCharCode(65+(i++%26))}return a.map(r=>r.join``).join`
`}

Demo

A demonstração abaixo deve ser executada preferencialmente em página inteira.

Arnauld
fonte
7

R, 46 ou 51 bytes, dependendo do espaçamento

s=1:scan();plot(s*sin(s),s*cos(s),pch=letters)

insira a descrição da imagem aqui

(versão atualizada do plot: a espiral cinza não é plotada por padrão, mas eu a adicionei depois para mostrar que as letras realmente estão em uma espiral.)

A espiral não tem espaçamento constante, então espero que esteja tudo bem. Se for necessário um espaçamento constante, comece com s=(1:scan())^.5e adicione 5 bytes ao total. Então a saída é a seguinte (n = 150):

insira a descrição da imagem aqui

JDL
fonte
3
A maneira como você espaça sua espiral depende inteiramente de você. Mas tenho duas sugestões: 1) Mantenha a segunda espiral. Acrescenta à sua resposta mesmo que seja menos golfe; 2) Você pode desenhar uma linha espiral passando pelas letras na imagem da sua primeira espiral? Apenas para tornar o alfabeto em espiral mais claro.
Sherlock9
6

Python 3.5, 180 157 152 147 147 bytes

-6 devido a Sherlock9

r=[[]]
for x in range(int(input())):
 r=len(r[-1])<len(r[0])and r or[*zip(*r[::-1]),[]];r[-1]+=[chr(x%26+65)]
print(*map(''.join,r),sep='\n')

-5 devido a Kap.

R=range
def g(n):
 r=[[]]
 for x in R(n):
  if len(r[-1])==len(r[0]):r=[*zip(*r[::-1]),[]]
  r[-1]+=[chr(x%26+65)]
 print(*map(''.join,r),sep='\n')

Solução revisada, python 3.x:

R=range
def g(n):
 r=[[]]
 for x in R(n):
  if len(r[-1])==len(r[0]):r=list(zip(*r[::-1]))+[[]]
  r[-1]+=[chr(x%26+65)]
 print(*map(''.join,r),sep='\n')

Solução anterior:

R=range
def g(n):
 r=[]
 for x,f in zip(R(n),(j<1for i in R(n)for j in R(i//2+1))):
  if f:r=list(zip(*r[::-1]))+[[]]
  r[-1].append(chr(x%26+65))
 print(*map(''.join,r),sep='\n')

Explicação

ré uma lista de listas que contém a espiral. A idéia básica é que novas letras sejam adicionadas à linha inferior da espiral ( r[-1].append(chr(x%26+65))). Quando a linha inferior é preenchida, a espiral é girada 90 no sentido horário e uma nova linha vazia é adicionada à parte inferior ( r = list(zip(*r[::-1]))+[[]]).

O truque é descobrir quando girar a espiral. Na primeira solução, o gerador (j<1for i in R(n)for j in R(i//2+1))produz uma sequência de valores Verdadeiro / Falso que informam quando girar a espiral. Na solução revisada, mudei a maneira como ré inicializado. Agora, quando o comprimento da linha inferior for igual ao comprimento da linha superior, a espiral precisará ser girada.

RootTwo
fonte
Você pode substituir if len(r[-1])==len(r[0]):r=list(zip(*r[::-1]))+[[]]por if len(r[-1])==len(r[0]):r=[*zip(*r[::-1]),[]]para salvar 5 bytes.
R. Kap
Como você usa apenas rangeuma vez, é possível remover Rpara salvar bytes. Você também pode salvar bytes convertendo sua resposta em um programa completo, mas para preservar o uso de [*zip(*r[::-1]),[]], precisará usá-lo range(int(input())).
Sherlock9
Além disso, for x in range(int(input())):r=len(r[-1])<len(r[0])and r or[*zip(*r[::-1]),[]];r[-1]+=[chr(x%26+65)]desde que você verifique quando a última linha é igual ou superior à primeira linha.
Sherlock9
Duas coisas: 1) Você pode fazer o loop for uma linha separando as instruções com ponto e vírgula; e 2) você não definiu nnesta versão. Você precisa usar int(input())ou agrupar o backup em uma função.
Sherlock9
2 bytes da condensação do forloop: #for x in range(int(input())):r=len(r[-1])<len(r[0])and r or[*zip(*r[::-1]),[]];r[-1]+=[chr(x%26+65)]
Sherlock9/
5

MATL , 21 18 bytes

X^Xk1YL1Y2y)wG>~*c

A entrada 0sai com um erro (que é permitido por padrão ).

Experimente online!

Explicação

X^Xk   % Input n implicitly. Take square root and round up
1YL    % Square matrix of that size containing a spiral of numbers
1Y2    % Predefined literal: string "AB···YZ"
y      % Duplicate the spiral matrix onto the top
)      % Apply as an index inth the string. Gives 2D array of chars
w      % Swap: move copy of the spiral matrix to top
G>~    % Set entries that exceed the input to 0, and the rest to 1 
*      % Multiply. This makes unwanted entries equal to 0
c      % Convert to char. 0 is shown as a space. Display implicitly
Luis Mendo
fonte
5

Python 2, 84 82 bytes

Estou usando a tartaruga novamente. É tão divertido! : D

from turtle import*
up()
for i in range(input()):write(chr(i%26+65));rt(9);fd(9+i)

Experimente online

Infelizmente, o Trinket.io possui uma tela horrivelmente pequena. Eu mudei 9+ipara 9+i/9e ajustado o ponto de partida da tartaruga com a finalidade de tela de captura esta imagem, de modo que mais da saída caberia:

saída

mbomb007
fonte
Um byte de se remover um espaço a partir da importação: from turtle import*e outro de mudar de whileparafor i in range(input())
Sherlock9
4

Pitão, 32 bytes

JS@Q2ju+.t_G)Hc<*GQQ.u+NY.iJJZ]Y

Um programa que imprime uma espiral ASCII retangular em minúsculas. Dependendo da entrada, uma linha ou coluna de espaço em branco à esquerda ou à direita pode estar presente.

Experimente online

Como funciona

JS@Q2ju+.t_G)Hc<*GQQ.u+NY.iJJZ]Y  Program. Input: Q
  @Q2                             Yield sqrt(Q)
JS                                Unary range, J=[1, 2, 3, ..., floor(sqrt(q))]
                         .iJJ     Interleave J with itself, yielding [1, 1, 2, 2, 3, 3, ...
                                  floor(sqrt(Q)), floor(sqrt(Q))]
                    .u+NY    Z    Cumulatively reduce by addition with base case 0,
                                  yielding [0, 1, 2, 4, 6, 9, 12, 16, 20...]
                *GQ               Repeat the lower-case alphabet Q times
               <   Q              Truncate to legth Q
              c                   Split the above at the indices in the above list
      u                       ]Y  Reduce the above, with base case [[]]:
          _G                       Reverse
        .t  )                      Transpose
       +     H                     Add the next arm of the spiral
     j                            Join on newlines and implicitly print
TheBikingViking
fonte
3

TSQL, 386 362 358 306 bytes

Observe que o TSQL não tem como rotacionar texto. Este script começa em A e calcula em qual direção a próxima letra deve ser colocada. (direita, baixo, esquerda, esquerda, esquerda, cima, cima, direita ...)

O script pode lidar com um máximo de 7744 letras.

Golfe:

DECLARE @z INT = 7744

DECLARE @ INT=2+SQRT(@z-1)DECLARE @o varchar(max)=REPLICATE(SPACE(@-1)+char(10),@-1);WITH C as(SELECT 0i,@/2a,@/2b UNION ALL SELECT i+1,a+z/2,b+z%2FROM(SELECT*,IIF(a>@/2*2-b,IIF(a<b,2,-1),IIF(a>b,-2,1))z FROM C)t WHERE i<@z-1)SELECT @o=STUFF(@o,@*a-@+b,1,char(i%26+65))FROM c OPTION(maxrecursion 0)PRINT @o

Ungolfed:

DECLARE @z INT = 7744

DECLARE @ INT=2+SQRT(@z-1)
DECLARE @o varchar(max)=REPLICATE(SPACE(@-1)+char(10),@-1)

;WITH C as
(
  SELECT
    0i,@/2a,@/2b
  UNION ALL
  SELECT
    i+1,a+z/2,b+z%2
    FROM 
      (SELECT*,
         IIF(a>@/2*2-b,
           IIF(a<b,2,-1),
             IIF(a>b,-2,1))z FROM C)t
  WHERE
    i<@z-1
)
SELECT 
  @o=STUFF(@o,@*a-@+b,1,char(i%26+65))
FROM c  
OPTION(maxrecursion 0)

PRINT @o

Violino

t-clausen.dk
fonte
2

Python 2, 243 bytes

r=range(input())
a=[1j**int((4*i+1)**.5)for i in r]
b=[map(int,(-sum(a[:i]).real,sum(a[:i]).imag))for i in r]
c,d=zip(*b)
for i in range(min(c),max(c)+1):print''.join([i,j]in b and chr(b.index([i,j])%26+65)or' 'for j in range(min(d),max(d)+1))

Ideone it!

Freira Furada
fonte
0

PHP , 219 bytes

for($q=ceil(sqrt($a=$argn))**2,$d=1,$x=$y=$w=0;$i<$q;$i++,${yx[$w%2]}+=[-1,1][$d&1],$i%$d?:$d+=$w++&1)$e[$c[]=$x-!($a&1)][$l[]=$y]=$i<$a?chr(65+$i%26):" ";for($k=min($c);$e[$k];print join($e[+$k++])."\n")ksort($e[+$k]);

Experimente online!

PHP, 260 bytes

Versão antiga

for($y=$x=$d=$i=0;$i<$m=ceil(sqrt($n=$argv[1]))**2;$i++){$a[$y][$x]=$i<$n?chr($i%26+65):" ";$d=$y==$x&$y<1?0:(1-$y==$x&$x>0?1:($y==$x&$y>0?2:($y==-$x&$x<0?3:$d)));$d>2?$y--:($d>1?$x--:($d>0?$y++:$x++));}ksort($a);foreach($a as$r){ksort($r);echo join($r)."\n";}
Jörg Hülsermann
fonte