pssssssssssssst

31

pengantar

Ini sangat mudah. Kami akan menggambar ular di ascii. Ini terinspirasi oleh permainan ular tua di mana Anda harus mengumpulkan buah dan Anda terus tumbuh.

Definisi

Dengan bilangan bulat N positif yang mewakili panjang ular, gambarkan ular sehingga memiliki tubuh n plus kepala dan ekor.

Bagian:

  • kepala: <, >, ^, v
  • ekor: @
  • vertikal: |
  • horizonal: -

Semua sudut harus dipenuhi dengan \atau /masing - masing. Kecuali jika kepala berakhir di sudut dimana kepala <, >, ^, vmengambil prioritas ke arah ular melengkung. yaitu untuk contoh panjang 1, itu diputar berlawanan arah jarum jam dan jadi kepala diputar seperti itu. Untuk solusi searah jarum jam itu akan ke kanan >.

Ular harus mulai di tengah dengan ekornya, tetapi ia bisa keluar ke arah mana pun yang Anda pilih searah atau berlawanan arah jarum jam. Itu juga harus membungkus dirinya sendiri dengan kuat saat mengembang ke arah luar secara melingkar.

Contoh

/--\
|/\|
||@|
|\-/
\--->

Di mana @ekor dan posisi awal. Seperti yang terlihat di atas, ekor dimulai di tengah, naik ke kiri dalam putaran berlawanan arah jarum jam ke arah luar.

Di sini panjangnya 19ditambah ekor dan kepala.

Sebagai contoh lain, ini panjangnya 1:

<\
 @

Kemenangan

Ini adalah kode-golf sehingga jawaban yang dikirimkan dengan jumlah byte terkecil menang, dengan waktu untuk digunakan sebagai tie breaker.

Selamat bersenang-senang!

jacksonecac
sumber
2
Tidak terlalu jelas bahwa saya tidak hanya diizinkan menggambar seperti ular lurus @---->. Anda mungkin menginginkan kondisi yang lebih ketat tentang bentuk ular. Juga jelaskan seberapa banyak ruang putih diizinkan atau tidak diizinkan
Ton Hospel
1
"Ular itu harus mulai di tengah dengan ekornya, tetapi ia mungkin bergerak ke luar ke arah mana pun yang Anda pilih dan searah jarum jam atau berlawanan arah jarum jam"
jacksonecac
1
Jadi yang saya katakan @adalah tengah (mungkin tambahkan beberapa spasi untuk membuatnya jadi), nyatakan "ke kanan" sebagai arah dan buat kepala mengarah ke bawah dan nyatakan searah jarum jam. Istilah Anda mungkin tampak jelas bagi Anda, tetapi sebenarnya tidak jelas. Saya menyadari bahwa Anda mungkin memaksudkan ular melingkar
sekencang
1
Jangan khawatir. Yang itu jauh lebih sulit karena offset dalam tantangan itu.
Martin Ender
2
Tantangan pertama yang bagus! Selamat datang di situs ini!
Luis Mendo

Jawaban:

10

MATL , 85 83 byte

Dan saya berpikir bahwa memiliki spiralbuiltin akan membuat kode pendek ...

Oli2+XH:UQXItH:+XJh(YsXKoQ3I(4J(5l(H:)0HX^XkU(6H(3M1YL3X!P)'|-\/@' '<v>^'KHq))h0hw)

Cobalah online!

Penjelasan

Biarkan N menunjukkan input. Kami akan membuat vektor panjang ceil(sqrt(N+2))^2, yaitu, kuadrat sempurna terkecil yang sama dengan atau melebihi N +2. Vektor ini akan diisi dengan nilai numerik, digulung menjadi spiral (itu sebabnya panjangnya harus persegi sempurna), dan kemudian nilai numerik akan diganti oleh karakter.

Biarkan n menunjukkan setiap langkah mulai dari 1 di pusat spiral. Langkah-langkah di mana ular berbelok diberikan oleh n 2 +1 (yaitu: 2, 5, 10, ...) untuk \simbol dan n 2 + n +1 (yaitu: 3, 7, 13, ...) untuk /. Langkah-langkah antara a \dan a /harus -, dan antara a /dan a \harus |.

Vektor dibuat sedemikian rupa sehingga berisi 1pada titik belokan (2,3,5,7,10,13 ...) dan 0sisanya. Paritas dari jumlah kumulatif memberi tahu jika setiap entri harus a -atau a |. Menambahkan 1 ke hasil ini kita mendapatkan vektor yang berisi 1(untuk |) atau 2(untuk -). Tetapi ini membuat titik balik itu menjadi 1atau 2terlalu. Jadi titik balik, yang posisinya kita ketahui, ditimpa: posisi n 2 +1 diisi 3dan posisi n 2 + n +1 diisi 4. Ekor dan kepala juga merupakan kasus khusus: elemen pertama dari vektor (ekor) diatur ke 5, dan elemen dengan indeks N+2 (head) diatur ke 6. Akhirnya, elemen dengan indeks melebihi N +2 diatur ke 0.

Mengambil input N = 19 sebagai contoh, kita sekarang memiliki vektor dengan panjang 25:

5 3 4 1 3 2 4 1 1 3 2 2 4 1 1 1 3 2 2 2 6 0 0 0 0

Kita perlu menggulung vektor ini menjadi spiral. Untuk ini kami menggunakan fungsi builtin yang menghasilkan matriks spiral, diikuti oleh refleksi dan transposisi untuk menghasilkan:

13 12 11 10 25
14  3  2  9 24
15  4  1  8 23
16  5  6  7 22
17 18 19 20 21 

Mengindeks vektor dengan memberikan matriks

4 2 2 3 0
1 4 3 1 0
1 1 5 1 0
1 3 2 4 0
3 2 2 2 6

mana 0bersesuaian dengan ruang, 1dapat disamakan dengan |, 2untuk -, 3untuk \, 4untuk /, 5untuk @, dan 6kepala.

Untuk mengetahui mana dari empat karakter ^, <, v, atau >kepala harus memiliki, kita menggunakan jumlah kumulatif gilirannya poin yang kami sebelumnya dihitung. Secara khusus, nilai kedua-terakhir dari jumlah kumulatif ini (yaitu nilai N + 1-th) modulo 4 memberi tahu kita karakter mana yang harus digunakan untuk kepala. Kami mengambil nilai kedua terakhir dari jumlah kumulatif, bukan yang terakhir, karena kebutuhan "jika kepala ujung di sudut kepala <, >, ^, vmenjadi prioritas dalam arah ular meringkuk". Untuk contoh N = 19 kepalanya adalah >.

Sekarang kita dapat membangun sebuah string yang berisi semua karakter ular, termasuk karakter yang sesuai untuk kepala di posisi keenam: '|-\/@> '. Kami kemudian mengindeks string ini dengan matriks di atas (pengindeksan adalah berbasis 1 dan modular, jadi ruang berjalan terakhir), yang memberikan

/--\ 
|/\| 
||@| 
|\-/ 
\--->
Luis Mendo
sumber
1
pekerjaan yang luar biasa! terima kasih telah berpartisipasi!
jacksonecac
8

Python 2, 250 233 191 byte

n=input()
l=[''],
a=x=0
b='@'
while a<=n:x+=1;l+=b,;l=zip(*l[::-1]);m=x%2;b='\/'[m]+x/2*'-|'[m];k=len(b);a+=k
l+=b[:n-a]+'>v'[m]+' '*(k-n+a-1),
if m:l=zip(*l[::-1])
for i in l:print''.join(i)
  • Disimpan 39 byte berkat @JonathanAllan

repl.it

Gambarkan ular dengan memutar seluruh ular 90º searah jarum jam dan menambahkan segmen bawah, dengan cara ini ular akan selalu berlawanan arah jarum jam.
Segmen baru akan selalu dimulai dengan \dan memiliki -tubuh untuk sisi yang rata dan / -sisi yang aneh. Segmen ukuran (tanpa sudut) adalah 0, 1, 1, 2, 2, 3... yang floor(side/2).
Jika segmen adalah yang terakhir, itu menghapus karakter berlebih, tambahkan kepala dan lengkapi dengan spasi.

desired_size=input()
snake=[['']]
snake_size=side=0
new_segment='@'
while snake_size<=desired_size:
    side+=1
    snake+=[new_segment]
    snake=zip(*snake[::-1])
    odd_side=side%2
    new_segment='\/'[odd_side]+side/2*'-|'[odd_side]
    snake_size+=len(new_segment)
diff=desired_size-snake_size
snake+=[new_segment[:diff]+'>v'[odd_side]+' '*(len(new_segment)-diff-1)]
if odd_side:
    snake=zip(*snake[::-1])

for line in snake:print ''.join(line)
tongkat
sumber
Pekerjaan yang baik! Anda memiliki kemenangan tiebreak. Mari kita lihat apa lagi yang orang pikirkan.
jacksonecac
2
Tentunya ini adalah bahasa yang ideal untuk menyelesaikan tantangan ini.
Neil
+1. Satu-satunya kesalahan adalah bahwa ketika kepala berada di sudut itu dimaksudkan untuk menunjuk lurus, bukan di sudut.
Jonathan Allan
1
Hemat 16 byte oleh pengindeksan menjadi string seperti: '\/'[m], '-|'[m]dan'>v'[m]
Jonathan Allan
1
Hemat 1 lebih banyak dengan menghapus spasi di antara printdan''.join
Jonathan Allan
7

JavaScript (ES6), 193 201 203 215 220 224 224

Edit disimpan 4 byte thx @Arnauld
Edit2 mengubah logika, tidak menyimpan kenaikan saat ini untuk x dan y, hanya mendapatkannya dari arah saat ini
Edit3 setelah menyimpan beberapa byte, saya memutuskan untuk menggunakannya untuk pengelolaan ruang kosong yang lebih baik
Edit4 8 byte yang disimpan tidak mengikuti persis contoh tentang arah kepala - seperti jawaban lainnya

Versi saat ini berfungsi dengan Chrome, Firefox dan MS Edge

Jawaban ini memberikan beberapa spasi tambahan dan garis depan (dan garis kosong).

n=>(t=>{for(x=y=-~Math.sqrt(++n)>>1,g=[i=t];(g[y]=g[y]||Array(x).fill` `)[x]='^<v>|-/\\@'[t?n?i-t?4+t%2:x-y?7:6:t%4:8],n--;i=i>1?i-2:++t)d=t&2,t&1?x+=d-1:y+=d-1})(0)||g.map(x=>x.join``).join`
`

Sedikit kurang golf

n=>
{
  g = [],
  // to save a few bytes, change line below (adds a lot of spaces)
  // w = ++n,
  w = -~Math.sqrt(++n)
  x = y = w>>1,
  s=c=>(g[y] = g[y] || Array(x).fill(' '))[x] = c, // function to set char in position
  s('@'); // place tail
  for (
     i = t = 0; // t increases at each turn, t%4 is the current direction
     n--;
     i = i > 0 ? i - 2 : t++ // side length increases every 2 turns
  )
     d = t & 2,
     t & 1 ? x += d-1: y += d-1
     s(!n ? '^<v>' [t % 4] // head
          : '|-/\\' [i > 0 ? t % 2 : x-y ? 3 : 2]) // body
  return g.map(x=>x.join``).join`\n`
}

f=
n=>(t=>{for(x=y=-~Math.sqrt(++n)>>1,g=[i=t];(g[y]=g[y]||Array(x).fill` `)[x]='^<v>|-/\\@'[t?n?i-t?4+t%2:x-y?7:6:t%4:8],n--;i=i>1?i-2:++t)d=t&2,t&1?x+=d-1:y+=d-1})(0)||g.map(x=>x.join``).join`
`

function update() {
  O.textContent=f(+I.value);
}

update()
<input type=number id=I value=19 oninput='update()' 
 onkeyup='update() /* stupid MS browser, no oninput for up/down keys */'>
<pre id=O>

edc65
sumber
Anda dapat menyimpan beberapa byte dengan mengganti (' ')dengan ` ` dan ('@')dengan`@`
Arnauld
@Arnauld Array (2) .fill` `==> [ Array[1], Array[1] ], sementara Array(2).fill(' ')==>[' ',' ']
usandfriends
@ usandfriends - Benar. Tapi itu tidak akan membuat perbedaan setelah bergabung.
Arnauld
@Arnauld pada awalnya saya setuju dengan kami dan teman-teman, tetapi ternyata berhasil. Terima kasih
edc65
@ TravisJ Tidak berfungsi di Chrome, tetapi Firefox tampaknya berfungsi.
Adnan
3

JavaScript (ES7), 200 byte

(n,s=(n*4+1)**.5|0,i=+`1201`[s%4],d=i=>`-`.repeat(i))=>[...Array(s-2>>2)].reduce(s=>`/-${d(i)}\\
${s.replace(/^|$/gm,`|`)}
|\\${d(i,i+=2)}/`,[`/\\
|@`,`/-\\
|@/`,`@`,`/@`][s%4])+`
\\${d(n-(s*s>>2))}>`

Versi ES6 untuk kemudahan pengujian:

f=(n,s=Math.sqrt((n*4+1))|0,i=+`1201`[s%4],d=i=>`-`.repeat(i))=>[...Array(s-2>>2)].reduce(s=>`/-${d(i)}\\
${s.replace(/^|$/gm,`|`)}
|\\${d(i,i+=2)}/`,[`/\\
|@`,`/-\\
|@/`,`@`,`/@`][s%4])+`
\\${d(n-(s*s>>2))}>`;
<input type=number min=1 oninput=o.textContent=f(this.value)><pre id=o>

Neil
sumber
Implementasi yang menarik. Saya tidak berpikir untuk melakukan itu. Terima kasih atas kontribusi dan kerja bagusnya !!
jacksonecac
3

Perl, 111 110 byte

Termasuk +1 untuk -p

Berikan ukuran pada STDIN

snake.pl:

#!/usr/bin/perl -p
s%> %->%+s%\^ %/>%||s/
/  
/g+s%.%!s/.$//mg<//&&join"",//g,$/%seg+s/ /^/+y%/\\|>-%\\/\-|%for($\="/
\@
")x$_}{
Ton Hospel
sumber
Luar biasa! Pekerjaan yang baik! Terima kasih telah berkontribusi!
jacksonecac
0

Batch, 563 byte

@echo off
if %1==1 echo /@&echo v&exit/b
set w=1
:l
set/ah=w,a=w*w+w
if %a% gtr %1 goto g
set/aw+=1,a=w*w
if %a% leq %1 goto l
:g
call:d
set r=/%r%\
set/ae=h%%2,w=%1-h*w+2
for /l %%i in (1,1,%h%)do call:r
call:d
echo \%r%^>
exit/b
:d
set r=
for /l %%i in (3,1,%w%)do call set r=%%r%%-
exit/b
:r
echo %r:!=^|%
if %e%==0 set r=%r:@!=\/%
set r=%r:@/=\/%
set r=%r:!\=\-%
set r=%r:/@=\/%
set r=%r:/!=-/%
set r=%r:@!=\/%
set r=%r:/\=!@%
set r=%r:/-=!/%
if %e%==1 set r=%r:/\=@!%
set r=%r:/\=@/%
set r=%r:-\=\!%
if %e%==1 set r=%r:/\=/@%

Penjelasan: Kasus khusus 1 sebagai sisa kode membutuhkan lebar ular setidaknya dua. Selanjutnya, hitung kuartal kuadrat terbesar (baik kuadrat tepat atau persegi panjang 1 lebih luas dari tinggi) yang luasnya kurang dari panjang ular. Ular akan digulung ke dalam persegi panjang ini mulai dari sudut kiri bawah dan berakhir dengan ekor di tengah, dan panjang yang tersisa akan berjalan di bawah bagian bawah persegi panjang. Persegi panjang sebenarnya dihasilkan dari penggantian string sederhana; sebagian besar waktu setiap garis dihasilkan dari garis sebelumnya dengan menggerakkan diagonal langkah 1, tetapi jelas ekornya juga harus ditangani, dan ada sedikit perbedaan tergantung pada apakah ketinggian persegi panjang itu genap atau ganjil.

Neil
sumber
Luar biasa! Terima kasih telah berkontribusi!
jacksonecac
-1

Python 2.7, A BERHASIL 1230 byte

Saya baru mengenal python dan golf kode, tetapi saya merasa harus menjawab pertanyaan saya sendiri dan merajuk karena malu. Sangat menyenangkan mengerjakannya!

def s(n):
x = []
l = 0
if n % 2 == 1:
    l = n
else:
    l = n + 1
if l < 3:
    l = 3
y = []
matrix = [[' ' for x in range(l)] for y in range(l)] 
slash = '\\'
newx = l/2
newy = l/2
matrix[l/2][l/2] = '@'
newx = newx-1
matrix[newx][newy] = slash
#newx = newx-1
dir = 'West'

for i in range(0, n-1):    
    newx = xloc(newx, dir)
    newy = yloc(newy, dir)
    sdir = dir
    dir = cd(matrix, newx, newy, dir)
    edir = dir

    if (sdir == 'West' or sdir == 'East') and sdir != edir:
        matrix[newx][newy] = '/'
    else:
        if (sdir == 'North' or sdir == 'South') and sdir != edir:
            matrix[newx][newy] = '\\'
        else:
            if dir == 'East' or dir == 'West':
                matrix[newx][newy] = '-'
            else:
                matrix[newx][newy] = '|'
newx = xloc(newx, dir)
newy = yloc(newy, dir)
sdir = dir
dir = cd(matrix, newx, newy, dir)
edir = dir
print 'eDir: ' + dir
if dir == 'North':
    matrix[newx][newy] = '^'
if dir == 'South':
     matrix[newx][newy] = 'v'
if dir == 'East':
     matrix[newx][newy] = '>'
if dir == 'West':
     matrix[newx][newy] = '<'    


p(matrix, l)

def cd(matrix, x, y, dir):    
if dir == 'North':
    if matrix[x][y-1] == ' ':
        return 'West'
if dir == 'West':
    if matrix[x+1][y] == ' ':
        return 'South'
if dir == 'South':
    if matrix[x][y+1] == ' ':    
        return 'East'
if dir == 'East':
    if matrix[x-1][y] == ' ':        
        return 'North'
return dir

def p(a, n):
for i in range(0, n):
    for k in range(0, n):
        print a[i][k],
    print ' '

def xloc(x, dir):
if dir == 'North':
    return x -1
if dir == 'West':
    return x
if dir == 'East':
    return x 
if dir == 'South':
    return x + 1
 def yloc(y, dir):
if dir == 'North':
    return y
if dir == 'West':
    return y - 1
if dir == 'East':
    return y + 1
if dir == 'South':
    return y

s(25)

https://repl.it/Dpoy

jacksonecac
sumber
5
Ini dapat dikurangi secara besar-besaran hanya dengan menghapus spasi yang tidak perlu, baris baru, komentar, fungsi, dll.
Addison Crump