Asterisco em espiral

29

Dada a espiral de tamanho Se o degrau N, produza a S*Sespiral "quadrada" com Nasteriscos, construída do raio externo para o interno no sentido horário.

Casos de teste (exemplos) abaixo.

  1. Entrada: 4 3

    Saída:

    ***
    
  2. Entrada: 4 6

    Saída:

    ****
       *
       *
    
  3. Entrada: 4 11

    Saída:

    ****
       *
    *  *
    ****
    
  4. Entrada: 6 18

    Saída:

    ******
         *
         *
    *    *
    *    *
    ******
    
  5. Entrada: 6 22

    Saída:

    ******
    ***  *
    *    *
    *    *
    *    *
    ******
    
  6. Entrada: 6 27

    Saída:

    ******
    ******
    *   **
    *   **
    *   **
    ******
    
  7. Entrada: 1 1

    Saída:

    *
    

Não é necessário lidar com os casos quando:

  • desde que Nasteriscos não possam "encaixar" na espiral de determinadas S*Sdimensões.

  • um Nou Sé zero.

O desafio é o código-golfe, os bytes mais curtos respondem a vitórias, qualquer idioma pode ser usado.

Sua saída pode ter quantos espaços / linhas à direita (mas não à esquerda) desejados.

nicael
fonte
Podemos ter espaços à direita / novas linhas?
usar o seguinte comando
2
Eu chamaria S o tamanho (ou pelo menos de diâmetro ) em vez de raio
Luis Mendo
@Luis fair point!
Nicael 01/04
3
Caros amigos , vote também nas respostas, não apenas na pergunta. É fácil fazer esse desafio. Fornecer uma resposta para isso é (acho) definitivamente mais difícil.
Nicael 01/04
2
Só você pensa assim. Escrever um desafio bem recebido e claro é muito difícil. (basta olhar para o segmento comentário aqui, há algumas sugestões após o desafio tinha sido publicada)
user202729

Respostas:

16

MATL , 17 16 bytes

UGlYLGoQ&P->42*c

Experimente online!

Explicação (com exemplo)

Considere entradas 4e 11como um exemplo.

U       % Implicit input: S. Push S^2
        % STACK: 16
G       % Push S again
        % STACK: 16, 4
lYL     % Outward, clockwise, east-first spiral of that size
        % STACK: 16,
                 [ 7  8  9 10;
                   6  1  2 11;
                   5  4  3 12;
                  16 15 14 13]
GoQ     % Push S, compute parity, add 1. Gives 1 for even S, 2 for odd
        % STACK: 16,
                 [ 7  8  9 10;
                   6  1  2 11;
                   5  4  3 12;
                  16 15 14 13],
                 1
&P      % Flip along that dimension (1 is vertical, 2 is horizontal).
        % This corrects for the orientation of the spiral
        % STACK: 16,
                 [16 15 14 13;
                   5  4  3 12;
                   6  1  2 11;
                   7  8  9 10]
-       % Subtract, element-wise. The upper-left corner becomes 0
        % STACK: [ 0  1  2  3
                  11 12 13  4
                  10 15 14  5
                   9  8  7  6]
>       % Implicit input (below): N. Greater than?, element-wise.
        % This transforms the first N entries, starting from
        % upper-left, inward, east-first, into 1, and the rest
        % into 0
        % STACK: [1 1 1 1;
                  0 0 0 1;
                  1 0 0 1;
                  1 1 1 1]
42*     % Multiply each entry by 42
        % STACK: [42 42 42 42;
                   0  0  0 42;
                  42  0  0 42;
                  42 42 42 42]
c       % Convert to char. Char 0 will be displayed as space.
        % Implicit display
        % STACK: ['****';
                  '   *';
                  '*  *';
                  '****']
Luis Mendo
fonte
11
Uau, eu nunca fui bom em jogar golfe, mas resolva-o com 17 bytes ... Isso parece mágico :) (eu sei que possivelmente as respostas mais curtas estão chegando, mas você é a primeira e aqui estão as minhas impressões :)
nicael
11
Parte do trabalho é realizada por uma função espiral incorporada. Acabei de adicionar uma explicação
Luis Mendo
Bem-vindo ao mundo das línguas de golfe destinadas a fins específicos. :)
Erik the Outgolfer
3
+1 para o pleno exemplo ao lado a explicação
IanF1
6

Stax , 19 bytes

±♪☺ÿzMæ¡♠à╣♂7☼V♀§9↓

Execute e depure

Começa construindo uma string que possui todos os caracteres no resultado com todos os asteriscos alinhados à esquerda. Em seguida, ele pega fatias cada vez maiores do final da corda e as "envolve" em uma grade à medida que gira a grade.

Aqui está o mesmo programa, descompactado, não destruído e comentado.

'**     repeat "*" specified number of times
,J(     square the top of the input stack, and right-pad string to that length
z       push an empty array - this is the result grid built up in the loop
{       begin a block to loop
  ~     push grid to the input stack
  ihNv  push -(i / 2) - 1 where i is the 0-based iteration index using integer division
  :/]   split the string at that index and wrap the second half in a singleton array
  ,     pop the grid from the input stack
  rM+   rotate the grid clockwise, then prepend the split string as the new first row
  n     copy what's left of the original string to top of stack for the loop condition
w       while; execute block until condition is truthy
m       display resulting grid

Execute e depure

recursivo
fonte
2
Me diverte extraordinariamente que no android essa resposta contenha um smiley de bolhas alaranjadas.
StarWeaver 01/04/19
@ StarWeaver Há muitas respostas no Stax que o fazem.
Weijun Zhou
Fiquei realmente confuso quando li a explicação e não a vi. Eu apenas pensei que Stax tinha uma página de código realmente estranha!
Ndm13 2/04
@ ndm13: suponho que ele tenha uma página de código estranha. É derivado do CP437, que é uma codificação "real" que possui o mesmo caractere. Você verá o mesmo rosto sorridente se seguir esse link no seu telefone.
recursivo
5

Python 2 , 117 bytes

n,k=input()
i=0;d=1
l=(' '*n+'\n')*n
exec"l=l[:i]+'*'+l[i+1:];d=[~n/d*cmp(d*d,2),d][' '<l[i+d:]<'*'];i+=d;"*k
print l

Experimente online!

xnor
fonte
4

APL (Dyalog) , 65 bytes

' *'[1+⎕>⊖∘⌽⍣o(⊖×⍨-,⍨⍴∘(⍋+\)×⍨↑(⌈2÷⍨×⍨),(+⍨⍴1,⊢,¯1,-)(/⍨)2/⍳)o←⎕]

Experimente online!

O código para a matriz espiral é retirado de outra resposta minha .

Uriel
fonte
Seu código desenha a espiral na direção errada, se o Né estranho :)
nicael
@nicael corrigido (mais como remendado). graças
Uriel
Talvez eu esteja usando a entrada da maneira errada?
Nicael 01/04
@nicael arghh. OK, acho que está tudo bem agora.
Uriel
4

Python 2 , 150 bytes

S,N=input()
X=y=n=0
Y=x=c=-1
s=eval(`[[' ']*S]*S`)
exec"if n%S<1:S-=c%2<1;X,Y=-Y,X;c+=1;n=0\nx+=X;y+=Y;s[y][x]='*';n+=1\n"*N
for i in s:print`i`[2::5]

Experimente online!

Erik, o Outgolfer
fonte
3

Carvão , 34 bytes

NθFE⮌E⊗N∨ι¹÷⁺鬬겫F‹θι≔θι×ι*≧⁻ιθ↷

Experimente online! Link é a versão detalhada do código. Explicação:

Nθ

Entrada N.

FE⮌E⊗N∨ι¹÷⁺鬬겫

Os comprimentos dos braços espirais (excluindo os cantos) são S-1, S-1, S-1, S-2, S-2, S-3, ..., 3, 2, 2, 1, 1, 1. Isso é formado começando pelo intervalo de 0até, mas excluindo 2S, alterando o 0 para 1, revertendo-o, adicionando 1 a cada elemento após o primeiro e, finalmente, inteiro, dividindo todos os elementos por 2. Essa lista é repetida.

F‹θι≔θι

Se houver menos estrelas para desenhar do que o comprimento do próximo braço, reduza o braço para esse comprimento.

×ι*

Desenhe o número apropriado de estrelas.

≧⁻ιθ

Subtraia o número de estrelas restantes.

Gire a direção do desenho 90 ° no sentido horário.

Neil
fonte
3

J, 60 56 bytes

-4 bytes, modificando o processo de construção da espiral, de modo que subtraí-la de y ^ 2 era desnecessária

4 :'''* ''{~x<|."1|.(|:@|.,<:@{:@{:-i.@#)^:(+:<:y),.*:y'

Experimente online!

Explicação em breve agora.

Explicação:

4 :'''* ''{~x<|."1|.(|:@|.,<:@{:@{:-i.@#)^:(+:<:y),.*:y'  | Explicit dyad definition
                    (|:@|.,<:@{:@{:-i.@#)^:(+:<:y),.*:y   | Generate a y by y inward spiral
                                                  ,.*:y   | The matrix [[y^2]]
                    (                   )^:(+:<:y)        | 2*(y-1) times...
                     |:@|.                                | Rotate
                          ,                               | Append
                                    i.@#                  | [0..len(n)-1]
                           <:@{:@{:-                      | Subtracted from the previous value and decremented
              |."1|.                                      | Flip around antidiagonal
            x>                                            | Test if each entry is less than x
    '' *''{~                                              | ' ' for 0, '*' for 1

Exemplos:

   3 :'(|:@|.,<:@{:@{:-i.@#)^:(+:<:y),.*:y' 4
7  8  9 10
6 15 16 11
5 14 13 12
4  3  2  1
   3 :'|."1|.(|:@|.,<:@{:@{:-i.@#)^:(+:<:y),.*:y' 4
1  2  3 4
12 13 14 5
11 16 15 6
10  9  8 7
   11(4 :'x<|."1|.(|:@|.,<:@{:@{:-i.@#)^:(+:<:y),.*:y') 4
0 0 0 0
1 1 1 0
0 1 1 0
0 0 0 0
   11(4 :'''* ''{~x<|."1|.(|:@|.,<:@{:@{:-i.@#)^:(+:<:y),.*:y') 4
****
   *
*  *
****
Bolce Bussiere
fonte
Você também pode adicionar um link ao exemplo executável?
Nicael 01/04
@nicael Added :)
Bolce Bussiere
2

Kotlin , 361 355 353 334 bytes

6 bytes salvos graças a Jonathan
2 bytes salvos mudando para quando
19 bytes salvos mudando para lambda e rastreando bordas externas

{s:Int,n:Int->var a=Array(s,{_->Array(s,{_->' '})})
var r=0
var c=0
var d=0
var e=0
var f=1
var g=s-1
var h=g
for(i in 1..n){a[r][c]='*'
when(d){0->if(c<g)c++
else{d=1
r++
g--}
1->if(r<h)r++
else{d=2
c--
h--}
2->if(c>e)c--
else{d=3
r--
e++}
3->if(r>f)r--
else{d=0
c++
f++}}}
for(i in 0..s-1){for(j in 0..s-1)print(a[i][j])
println()}}

Experimente online!

JohnWells
fonte
11
Não tenho muita certeza de como experimentá-lo, pois o campo de entrada está vazio.
Nicael 1/04
11
@nicael É uma função. isso pode ser mais fácil de usar - a chamada é feita no rodapé.
Jonathan Allan
11
Não conheço muito Kotlin, mas acredito que ==' 'possa ser substituído por <'*'. Também d==0com d<1e d==3com d>2. Parece golfe bastante fundamental, então provavelmente existem outros também!
Jonathan Allan
@nicael você pode colocar dois números inteiros no campo de entrada, tamanho na primeira linha, número na segunda.
JohnWells
11
@JohnWells, de fato, funciona. De alguma forma, é muito lento, mas não importa.
Nicael 01/04
2

Java 10, 284 282 281 263 bytes

s->n->{var c=new char[s][s];for(var d:c)java.util.Arrays.fill(d,' ');for(int i=0,j=0,y=0,x=1,u=s-1,l=0;n-->0;c[j][i]=42,i+=x,j+=y,l+=i==l&x==0?1:0,u-=i==l&j==l&y<1?1:0)if(x!=0){var b=x>0?i<u:i>l;y=b?0:x;x=b?x:0;}else{var b=y>0?j<u:j>l;x=b?0:-y;y=b?y:0;}return c;}

Um desafio divertido!

Experimente online aqui .

Agradecimentos a Kevin Cruijssen por jogar 18 bytes.

Versão não destruída:

s -> n -> { // lambda taking two integer arguments in currying syntax
    var c = new char[s][s]; // the matrix containing the spiral
    for(var d : c) // for every row
        java.util.Arrays.fill(d, ' '); // fill it with spaces
    for(int i = 0, j = 0, // the coordinates of the next '*'
            y = 0, x = 1, // the direction to move in
            u = s-1, l = 0; // the upper and lower bounds
        n-- > 0; // decrecement the length of the spiral and repeat as many times
        c[j][i] = 42, // draw the '*', 42 is ASCII code
        i += x, j += y, // move to the next cell
        l += i == l & x == 0 ? 1 : 0, // adjust lower bound if necessary
        u -= i == l & j == l & y < 1 ? 1 : 0) // adjust upper bound if necessary
        if(x != 0) { // if moving in x direction
            var b = x > 0 ? i < u : i > l; // if we hit the bounds
            y = b ? 0 : x; // flip directions,
            x = b ? x : 0; // turning around
        } else { // if moving in y direction
            var b = y > 0 ? j < u : j > l; // if we hit the bounds
            x = b ? 0 : -y; // flip directions,
            y = b ? y : 0;  // turning around
        }
    return c; // return the matrix
}
OOBalance
fonte
263 bytes últimos dois loops são alterados principalmente, e var bé adicionado para que você só tem que fazer o x>0?i<u:i>le y>0?j<u:j>luma vez cada, em vez de duas vezes cada um.
Kevin Cruijssen 03/04/19
@KevinCruijssen great golf, obrigado!
OOBalance
2

JavaScript (Node.js) , 167 164 163 bytes

  • graças a @Erik the Outgolfer e @nicael por espaços (3 bytes)
  • obrigado a @micha por juntar-se a `` divisão em ,vez de mapa (1 byte)
(l,s)=>{a=(b=[...Array(l)]).map(x=>b.map(_=>" "))
for(d=1,x=y=D=0;s--;x+=d,y+=D)a[y][x]="*",(a[y+D]||[])[x+d]!=" "?[d,D]=[-D,d]:0
return a.join`
`.split`,`.join``}

Experimente online!

DanielIndie
fonte
11
Bom, funciona! Você pode remover espaços / novas linhas para torná-lo ainda mais curto?
Nicael 1/04
11
@nicael Parece que sim.
Erik the Outgolfer
11
Lindo! Se a versão Kotlin e Java usasse o mesmo método, elas seriam muito menores! Uma maneira tão elegante de detectar quando você bate na espiral ou na borda e depois vira a "tartaruga". Muito esperto! Um byte a menos: altere o retorno para return a.join` `.split`,`.join``.
Mica
@micha em primeiro lugar obrigado :). segunda a.join` .split, `saída doesnt .join`` a espiral "bem"(com novas linhas), então eu acho que é um problema
DanielIndie
@DanielIndie, a nova linha foi formatada, a primeira associação deve ter uma nova linha. Veja como
micha