Asterisk spiral

29

Mengingat ukuran Sdan langkah spiral N, output S*Sspiral "persegi" memiliki Ntanda bintang, dibangun dari jari-jari luar ke dalam searah jarum jam.

Uji kasus (contoh) di bawah ini.

  1. Memasukkan: 4 3

    Keluaran:

    ***
    
  2. Memasukkan: 4 6

    Keluaran:

    ****
       *
       *
    
  3. Memasukkan: 4 11

    Keluaran:

    ****
       *
    *  *
    ****
    
  4. Memasukkan: 6 18

    Keluaran:

    ******
         *
         *
    *    *
    *    *
    ******
    
  5. Memasukkan: 6 22

    Keluaran:

    ******
    ***  *
    *    *
    *    *
    *    *
    ******
    
  6. Memasukkan: 6 27

    Keluaran:

    ******
    ******
    *   **
    *   **
    *   **
    ******
    
  7. Memasukkan: 1 1

    Keluaran:

    *
    

Tidak perlu menangani kasus ketika:

  • asalkan Ntanda bintang tidak dapat "cocok" dalam spiral S*Sdimensi yang diberikan .

  • salah satu Natau Snol.

Tantangannya adalah kode-golf, byte tersingkat menang, semua bahasa dapat digunakan.

Output Anda mungkin memiliki banyak spasi / baris baru yang mengikuti (tetapi tidak memimpin) seperti yang Anda inginkan.

nicael
sumber
Bisakah kita memiliki spasi tambahan / baris baru?
user202729
2
Saya akan memanggil S ukuran (atau setidaknya diameter ) daripada radius
Luis Mendo
@Luis point yang adil!
nicael
3
Teman-teman yang terhormat , tolong beri suara pada jawaban juga, bukan hanya pertanyaan. Mudah untuk membuat tantangan ini. Memberikan jawaban untuk itu (saya pikir) jelas lebih sulit.
nicael
2
Hanya Anda yang berpikir demikian. Menulis tantangan yang diterima dengan baik dan jelas sangat sulit. (lihat saja utas komentar di sini, ada beberapa saran setelah tantangan diposting)
user202729

Jawaban:

16

MATL , 17 16 byte

UGlYLGoQ&P->42*c

Cobalah online!

Penjelasan (dengan contoh)

Pertimbangkan input 4dan 11sebagai contoh.

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
sumber
1
Wow, saya tidak pernah pandai bermain golf, tetapi menyelesaikannya dengan 17 byte ... Itu terlihat seperti sihir :) (Saya tahu bahwa mungkin jawaban yang lebih pendek datang, tetapi Anda pertama dan di sini adalah kesan saya :)
nicael
1
Bagian dari pekerjaan dilakukan oleh fungsi spiral bawaan. Saya baru saja menambahkan penjelasan
Luis Mendo
@nicael Selamat datang di dunia bahasa golf yang ditujukan untuk tujuan tertentu. :)
Erik the Outgolfer
3
+1 untuk contoh lengkap di samping penjelasannya
IanF1
6

Stax , 19 byte

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

Jalankan dan debug itu

Itu dimulai dengan membangun string yang memiliki semua karakter dalam hasil dengan semua tanda bintang kiri selaras. Kemudian dibutuhkan irisan yang semakin besar dari ujung tali, dan "membungkus" mereka di sekitar kotak saat memutar kotak.

Inilah program yang sama, dibongkar, tidak diseret, dan dikomentari.

'**     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

Jalankan dan debug itu

rekursif
sumber
2
Ini sangat menghibur saya bahwa di android jawaban ini berisi smiley gumpalan oranye.
StarWeaver
@ StarWeaver Ada banyak jawaban di Stax yang melakukannya.
Weijun Zhou
Saya benar-benar bingung ketika membaca penjelasannya dan tidak melihatnya. Saya hanya berpikir bahwa Stax memiliki halaman kode yang sangat aneh!
ndm13
@ ndm13: Saya kira itu memang memiliki halaman kode yang aneh. Ini berasal dari CP437 yang merupakan pengkodean "nyata" yang memiliki karakter yang sama di dalamnya. Anda akan melihat wajah tersenyum yang sama jika Anda mengikuti tautan itu di ponsel Anda.
rekursif
5

Python 2 , 117 byte

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

Cobalah online!

Tidak
sumber
4

APL (Dyalog) , 65 byte

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

Cobalah online!

Kode untuk matriks spiral diambil dari jawaban saya yang lain .

Uriel
sumber
Kode Anda menggambar spiral ke arah yang salah jika Naneh :)
nicael
@nicael diperbaiki (lebih seperti ditambal). terima kasih
Uriel
Tapi ... i.stack.imgur.com/gGJsS.png
nicael
Mungkin saya menggunakan input dengan cara yang salah?
nicael
@nicael arghh. OK, saya pikir tidak apa-apa sekarang.
Uriel
4

Python 2 , 150 byte

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]

Cobalah online!

Erik the Outgolfer
sumber
3

Arang , 34 byte

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

Cobalah online! Tautan adalah untuk mengucapkan versi kode. Penjelasan:

Nθ

Masukan N.

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

Panjang dari lengan spiral (tidak termasuk sudut) adalah S-1, S-1, S-1, S-2, S-2, S-3, ..., 3, 2, 2, 1, 1, 1. Ini dibentuk dengan memulai dengan rentang dari 0hingga tetapi tidak termasuk 2S, mengubah 0 ke 1, membalikkannya, menambahkan 1 ke setiap elemen setelah yang pertama, dan akhirnya integer membagi semua elemen dengan 2. Daftar ini kemudian diulang.

F‹θι≔θι

Jika ada lebih sedikit bintang yang tersisa untuk menggambar daripada panjang lengan berikutnya, kurangi lengan ke panjang itu.

×ι*

Gambarkan jumlah bintang yang sesuai.

≧⁻ιθ

Kurangi dari jumlah bintang yang tersisa.

Putar arah gambar 90 ° searah jarum jam.

Neil
sumber
3

J, 60 56 Bytes

-4 Bytes dengan memodifikasi proses build untuk spiral sehingga mengurangkannya dari y ^ 2 tidak diperlukan

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

Cobalah online!

Penjelasan segera hadir sekarang.

Penjelasan:

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

Contoh:

   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
sumber
Bolehkah Anda juga menambahkan tautan ke contoh yang dapat dieksekusi?
nicael
@nicael Ditambahkan :)
Bolce Bussiere
2

Kotlin , 361 355 353 334 byte

6 byte disimpan berkat Jonathan
2 byte disimpan berubah ke saat
19 byte disimpan beralih ke lambda & melacak tepi luar

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

Cobalah online!

JohnWells
sumber
1
Saya tidak begitu yakin bagaimana cara mencobanya karena kolom input kosong.
nicael
1
@nicael Ini adalah fungsi. ini mungkin lebih mudah digunakan - panggilan dibuat di footer.
Jonathan Allan
1
Saya tidak tahu banyak tentang Kotlin, tetapi saya yakin ==' 'bisa diganti oleh <'*'. Juga d==0dengan d<1dan d==3dengan d>2. Ini tampak seperti golf yang cukup mendasar sehingga mungkin ada yang lain juga!
Jonathan Allan
@nicael Anda bisa meletakkan dua bilangan bulat di bidang input, ukuran di baris pertama, angka di kedua.
JohnWells
1
@ JohnWells memang, itu berhasil. Entah bagaimana itu terlalu lambat, tetapi itu tidak masalah.
nicael
2

Java 10, 284 282 281 263 byte

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;}

Tantangan yang menyenangkan!

Cobalah online di sini .

Terima kasih kepada Kevin Cruijssen karena bermain golf 18 byte.

Versi tidak disatukan:

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
}
Ketidakseimbangan
sumber
263 byte Dua loop terakhir sebagian besar diubah, dan var bditambahkan sehingga Anda hanya perlu melakukan x>0?i<u:i>ldan y>0?j<u:j>lmasing-masing, bukan masing-masing dua kali.
Kevin Cruijssen
@KevinCruijssen golf yang hebat, terima kasih!
OOBalance
2

JavaScript (Node.js) , 167 164 163 byte

  • terima kasih kepada @Erik the Outgolfer dan @nicael untuk spasi (3 byte)
  • terima kasih kepada @micha untuk bergabung dengan `split ,alih-alih peta (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``}

Cobalah online!

DanielIndie
sumber
1
Bagus, itu berhasil! Bisakah Anda menghapus spasi / baris baru untuk membuatnya lebih pendek?
nicael
1
@nicael Sepertinya ya.
Erik the Outgolfer
1
Indah! Jika versi Kotlin dan Java akan menggunakan metode yang sama mereka akan jauh lebih pendek! Cara deteksi yang elegan ketika Anda menekan spiral atau perbatasan dan kemudian memutar "kura-kura". Sangat pintar! Kurang satu byte: ubah kembali menjadi return a.join` `.split`,`.join``.
micha
@micha pertama-tama terima kasih :). a.join` kedua .split, `.join`` tidak menampilkan spiral" dengan baik "(dengan baris baru) jadi saya pikir ini masalah
DanielIndie
@DanielIndie, baris baru diformat, gabung pertama harus memiliki baris baru. Lihat itu
micha