Espiral de asterisco

29

Dada la espiral de tamaño Sy el escalón N, genera la S*Sespiral "cuadrada" que tiene Nasteriscos, construidos desde el radio exterior al interior en el sentido de las agujas del reloj.

Casos de prueba (ejemplos) a continuación.

  1. Entrada: 4 3

    Salida:

    ***
    
  2. Entrada: 4 6

    Salida:

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

    Salida:

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

    Salida:

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

    Salida:

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

    Salida:

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

    Salida:

    *
    

No es necesario manejar los casos cuando:

  • los Nasteriscos proporcionados no pueden "encajar" en la espiral de S*Sdimensiones dadas .

  • ya sea No Ses cero.

El desafío es el código de golf, gana la respuesta de bytes más cortos, se puede usar cualquier idioma.

Su salida puede tener tantos espacios finales (pero no iniciales) / líneas nuevas como desee.

nicael
fuente
¿Podemos tener espacios finales / líneas nuevas?
user202729
2
Llamaría S tamaño (o al menos diámetro ) en lugar de radio
Luis Mendo
@Luis punto justo!
nicael 01 de
3
Queridos amigos , voten también las respuestas, no solo las preguntas. Es fácil hacer este desafío. Proporcionar una respuesta es (creo) definitivamente más difícil.
nicael 01 de
2
Solo tú piensas eso. Escribir un desafío bien recibido y claro es muy difícil. (solo mire el hilo de comentarios aquí, hay algunas sugerencias después de que se haya publicado el desafío)
user202729

Respuestas:

16

MATL , 17 16 bytes

UGlYLGoQ&P->42*c

Pruébalo en línea!

Explicación (con ejemplo)

Considere las entradas 4y 11como ejemplo.

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
fuente
1
Wow, nunca fui bueno jugando al golf, pero resuélvelo con 17 bytes ... Eso parece mágico :) (Sé que posiblemente las respuestas más cortas están llegando, pero tú eres el primero y aquí están mis impresiones :)
nicael
1
Parte del trabajo se realiza mediante una función espiral incorporada. Acabo de agregar una explicación
Luis Mendo
@nicael Bienvenido al mundo de los idiomas de golf para fines específicos. :)
Erik the Outgolfer
3
+1 para un ejemplo completo junto con la explicación
IanF1
6

Stax , 19 bytes

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

Ejecutar y depurarlo

Comienza construyendo una cadena que tiene todos los caracteres en el resultado con todos los asteriscos alineados a la izquierda. Luego, toma cortes cada vez más grandes del extremo de la cadena y los "envuelve" alrededor de una cuadrícula a medida que gira la cuadrícula.

Aquí está el mismo programa, desempaquetado, sin golf y 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

Ejecutar y depurarlo

recursivo
fuente
2
Me divierte desmesuradamente que en Android esta respuesta contenga una carita sonriente naranja.
StarWeaver
@StarWeaver Hay muchas respuestas en Stax que lo hacen.
Weijun Zhou
Estaba realmente confundido cuando leí la explicación y no vi ninguna. ¡Solo pensé que Stax tenía una página de códigos realmente extraña!
ndm13
@ ndm13: supongo que tiene una página de códigos extraña. Se deriva de CP437, que es una codificación "real" que tiene el mismo carácter. Debería ver la misma cara sonriente si sigue ese enlace en su teléfono.
recursivo el
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

Pruébalo en línea!

xnor
fuente
4

APL (Dyalog) , 65 bytes

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

Pruébalo en línea!

El código para la matriz espiral se toma de otra respuesta mía .

Uriel
fuente
Su código dibuja la espiral en la dirección incorrecta si Nes extraño :)
nicael
@nicael fijo (más bien parcheado). gracias
Uriel
Pero ... i.stack.imgur.com/gGJsS.png
nicael
¿Tal vez estoy usando la entrada de manera incorrecta?
nicael 01 de
@nicael arghh. OK, creo que está bien ahora.
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]

Pruébalo en línea!

Erik el Outgolfer
fuente
3

Carbón , 34 bytes

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

Pruébalo en línea! El enlace es a la versión detallada del código. Explicación:

Nθ

Entrada N.

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

Las longitudes de los brazos espirales (con exclusión de las esquinas) son S-1, S-1, S-1, S-2, S-2, S-3, ..., 3, 2, 2, 1, 1, 1. Esto se forma comenzando con el rango de 0hasta, pero excluyendo 2S, cambiando el 0 a 1, invirtiéndolo, agregando 1 a cada elemento después del primero, y finalmente enteros dividiendo todos los elementos por 2. Esta lista luego se repite.

F‹θι≔θι

Si quedan menos estrellas para dibujar que la longitud del siguiente brazo, reduzca el brazo a esa longitud.

×ι*

Dibuja el número apropiado de estrellas.

≧⁻ιθ

Resta del número de estrellas restantes.

Gire la dirección del dibujo 90 ° en sentido horario.

Neil
fuente
3

J, 60 56 bytes

-4 Bytes modificando el proceso de construcción para la espiral para que no sea necesario restarlo de y ^ 2

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

Pruébalo en línea!

Explicación próximamente ahora.

Explicación:

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

Ejemplos:

   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
fuente
¿También puede agregar un enlace al ejemplo ejecutable?
nicael 01 de
@nicael Added :)
Bolce Bussiere
2

Kotlin , 361 355 353 334 bytes

6 bytes guardados gracias a Jonathan
2 bytes guardados cambiando a cuando se
guardaron 19 bytes cambiando a lambda y siguiendo los bordes exteriores

{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()}}

Pruébalo en línea!

JohnWells
fuente
1
No estoy realmente seguro de cómo probarlo ya que el campo de entrada está vacío.
nicael 01 de
1
@nicael Es una función. Esto puede ser más fácil de usar: la llamada se realiza en el pie de página.
Jonathan Allan
1
No conozco mucho a Kotlin, pero creo que ==' 'puede ser reemplazado por <'*'. También d==0con d<1y d==3con d>2. Parecen campos de golf bastante fundamentales, por lo que probablemente también haya otros.
Jonathan Allan
@nicael puede poner dos enteros en el campo de entrada, tamaño en la primera línea, número en la segunda.
JohnWells
1
@ JohnWells de hecho, funciona. De alguna manera es demasiado lento, pero no importa.
nicael 01 de
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;}

Un reto divertido!

Pruébelo en línea aquí .

Gracias a Kevin Cruijssen por jugar al golf 18 bytes.

Versión sin golf:

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
fuente
263 bytes Los últimos dos bucles se cambian principalmente, y var bse agrega a para que solo tenga que hacer el x>0?i<u:i>ly y>0?j<u:j>luna vez cada uno, en lugar de dos veces cada uno.
Kevin Cruijssen
@KevinCruijssen gran golf, gracias!
OOBalance
2

JavaScript (Node.js) , 167 164 163 bytes

  • gracias a @Erik the Outgolfer y @nicael por espacios (3 bytes)
  • gracias a @micha por unirse `` dividir en ,lugar 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``}

Pruébalo en línea!

DanielIndie
fuente
1
Bien, funciona! ¿Puedes eliminar espacios / líneas nuevas para hacerlo aún más corto?
nicael 01 de
1
@nicael Parece que sí.
Erik the Outgolfer
1
¡Hermosa! Si las versiones de Kotlin y Java usaran el mismo método, ¡serían mucho más cortas! Una manera tan elegante de detectar cuando golpeas la espiral o el borde y luego giras la "tortuga". ¡Muy inteligente! Un byte menos: cambie el retorno a return a.join` `.split`,`.join``.
micha
@micha en primer lugar gracias :). segundo a.join` .split, `.join`` no muestra la espiral" muy bien "(con nuevas líneas), así que creo que es un problema
DanielIndie
@DanielIndie, la nueva línea se formateó, la primera unión debería tener una nueva línea. Verlo
micha