Uma espiral ASCII bem espaçada

13

Considere esta espiral

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

Começando no centro:

  • A primeira linha (para cima) possui 3 caracteres.
  • A segunda linha tem o mesmo número de caracteres (3)
  • Em seguida, adicionamos dois caracteres (5) para os próximos dois lados.
  • Esse padrão continua, dois lados do mesmo comprimento e depois aumentam o comprimento em 2.

Eu quero gerar essa espiral para N linhas.

  • Escreva em qualquer idioma.
  • A entrada / argumento etc. é o número de linhas em sua espiral.
  • Cada linha começa com o caractere final da linha anterior na direção 90 graus no sentido horário da linha anterior.
  • Não ligo quanto espaço em branco é anterior ou posterior a cada linha, desde que os elementos da espiral se alinhem.
  • Saída de texto para desenhar a espiral com qualquer caractere que não seja de espaço em branco que você escolher.
  • Tente fazer isso no menor número de bytes.

Casos de teste (usando um hash como saída):

N = 1

#
#
#

N = 2

###
#
#

N = 3

###
# #
# #
  #
  #

N = 10

###########
#
# #######
# #     #
# # ### #
# # # # #
# # # # #
# #   # #
# ##### #
#       #
#########
AJFaraday
fonte
@Shaggy "Texto de saída para desenhar a espiral com qualquer caractere que não seja um espaço em branco que você escolher." Sim, o que você quiser.
AJFaraday
3
1 relacionado ; Relacionado 2 .
Kevin Cruijssen 26/06
3
A imagem inicial tem um em *vez de #. Esperado?
Wernisch 26/06/19
@Wernisch Pretendia-se ser um ponto de partida útil, mas suponho que seja enganoso. Você pode usar qualquer personagem que desejar.
AJFaraday

Respostas:

11

05AB1E , 13 11 bytes

Código:

Agradecimentos a Emigna por salvar dois bytes!

LDÈ-Ì'#3Ý·Λ

Usa a codificação 05AB1E . Experimente online!

Explicação

Os comprimentos de cada aresta individual na espiral começam com o comprimento 3 e aumentam gradualmente a cada dois passos em dois:

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

nn

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

Isso basicamente nos dá a lista desejada de comprimentos.

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

A tela funciona como uma função que exibe três parâmetros (onde o parâmetro mais à direita é exibido primeiro): <length (s)> , <char (s)> , <direction (s)> . O parâmetro direções é, neste caso, uma lista de números. Os números que correspondem às instruções são:

[70 0162543]

Nesse caso, [0, 2, 4, 6] corresponde à lista de instruções [↑, →, ↓, ←]. A tela itera sobre cada comprimento recuperado da lista de comprimentos, usa o caractere '#' e itera ciclicamente sobre a lista de direções.

Adnan
fonte
0246S=3Ý·
Emigna 27/06
@ Emigna Ah, eu não pensei nisso, obrigado!
27518 Adnan
6

Python 2 , 176 170 165 161 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)

Experimente online!

Repetidamente: Utilizado gpara girar a niteração da espiral para uma posição 'canônica' (semelhante a N = 3 ou N = 7), adiciona um novo segmento adicionando 2 espaços à esquerda de cada linha existente e substituindo a última linha com todos os '#'s (resultando em uma posição comparável a N = 4 ou N = 8) e, finalmente, usando gnovamente para girá-lo de volta à posição correta. Espuma, enxágüe, repita.

Chas Brown
fonte
4

Carvão , 16 15 14 bytes

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

-2 bytes graças a @Neil .

Experimente online (detalhado) ou Experimente online (puro) .

Explicação:

A direção da impressão está à direita, por padrão, e queremos começar para cima; portanto, giramos 45 graus no sentido anti-horário:

PivotLeft();
↶

Em seguida, faça um loop ino intervalo [0, input):

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

Imprima uma nova linha para imitar o efeito de voltar uma posição:

Print("\n");
¶

Imprima "#" a xquantidade de vezes na direção atual:

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

Onde xfica 3 + i // 2 * 2::

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

E gire 45 graus no sentido horário para a próxima iteração do loop:

PivotRight();
↷
Kevin Cruijssen
fonte
Suponho que não haja comando no carvão para retroceder?
Emigna
@ Emigna Não tenho certeza, mas também não consegui encontrar. Na verdade, estava procurando por mim quando estava escrevendo esta resposta. Existe um movimento com uma determinada direção, bem como um salto com determinadas coordenadas, mas infelizmente não um movimento.
Kevin Cruijssen
1
⊗÷ι²é um byte menor que ⁻ι﹪ι². Além disso, você pode obter o efeito de voltar a imprimir imprimindo a \nantes de #s, o que permitirá remover o »#para uma economia geral adicional de bytes.
Neil
@ Neil Obrigado pelo ⊗÷ι², mas quais seriam as alterações para imprimir um \nantes do #s? A espiral está incorreta se eu adicionar oPrint("\n") .
Kevin Cruijssen
Como os braços agora se sobrepõem, você precisa torná-los mais #longos.
28518 Neil
3

Python 2 , 179 178 bytes

graças 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)

Experimente online!


Python 2 , 179 bytes

Nesta abordagem, as fórmulas são usadas para xe ydeltas, em vez de uma lista de pesquisa.

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)

Experimente online!

ovs
fonte
n+1+n%2a n%2-~npara -1 byte. E preciso me lembrar de 0--n/4*2ser 1 menor que -(-n/4*2). Boa resposta, +1 de mim.
Kevin Cruijssen
1

JavaScript (ES6), 185 bytes

Claro que isso pode ser mais praticado, talvez com curry, mas aqui está minha tentativa muito humilde. Quebras de linha adicionadas para facilitar a leitura, exceto o penúltimo caractere

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)retorna uma string conforme o exemplo de desafio N = 10.

Define uma função r(a,n)para girar uma matriz apor nturnos; uma função s(n)para gerar uma matriz bidimensional representando uma espiral de tamanho ngirando recursivamente e adicionando espaçamento e linhas (não girados de volta à posição inicial); e uma função d(n)para desenhar uma espiral de tamanho n, rotacionada consistentemente conforme o desafio e renderizada como uma sequência retornada.

Este foi um desafio muito divertido: ¬)

Chris M
fonte