pssssssssssssst


31

Giriş

Bu oldukça basit. Ascii'de bir yılan çizeceğiz. Bu, meyve toplamak zorunda olduğunuz ve sürekli büyüdüğünüz eski yılan oyunundan esinlenmiştir.

Tanım

Yılanın uzunluğunu temsil eden pozitif bir tamsayı N verildiğinde, bir yılanı, n artı bir baş ve kuyruğa sahip olacak şekilde çizin.

Parçalar:

  • kafa: <, >, ^, v
  • kuyruk: @
  • dikey: |
  • horizonal: -

Tüm köşeler sırasıyla \veya ile /sağlanmalıdır. Kafa bir köşede sona ermezse, bu durumda kafa <, >, ^, vyılan kıvrılır. yani uzunluk 1 örneği için saat yönünün tersine döndürülür ve böylece kafa bu şekilde döndürülür. Saat yönünde bir çözüm için sağa olurdu >.

Yılan kuyruğu ile ortada başlamalıdır, ancak saat yönünde veya saat yönünün tersine seçtiğiniz herhangi bir yönde dışarı doğru gidebilir. Dairesel bir şekilde dışarı doğru genişlediğinden, etrafına sıkıca sarılması gerekir.

Örnek

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

@Kuyruk ve başlangıç ​​pozisyonu nerede . Yukarıda görüldüğü gibi kuyruk ortada başlıyor, saat yönünün tersine doğru dönerek sola gidiyor.

Burada uzunluk 19artı bir kuyruk ve bir kafa.

Başka bir örnek olarak, işte uzunluk 1:

<\
 @

Kazanan

Bu kod-golf'dür, bu nedenle en az sayıda baytla gönderilen cevap, beraberinde kırıcı olarak kullanılmak üzere zaman kazanır.

İyi eğlenceler!


2
Sadece düz bir yılan gibi çizmeme izin verilmediği çok açık değil @---->. Muhtemelen yılan şekli ile ilgili daha katı koşullar kastediyorsunuz. Ayrıca, boşluk
miktarının

1
"Yılan kuyruğuyla ortasından başlamalı, ancak seçtiğiniz herhangi bir yöne ve saat yönünün tersine veya saatin tersi yönünde dışarı doğru gidebilir"
jacksonecac 4:16 'de

1
Bu yüzden @orta diyorum (mümkün kılmak için bazı boşluklar ekleyiniz), yön olarak "sağa" bildirin ve sadece kafayı aşağı çevirin ve bunu saat yönünde ilan edin. Terimleriniz size açık görünebilir, ancak aslında belirsizdir. Muhtemelen mümkün olduğu kadar sıkıca sarılmış bir yılan demek istediğinizi anlıyorum, ancak bunu açıkça belirtmelisiniz
Ton Hospel

1
Endişelenme. Bu, bu zorluktaki ofsetlerden dolayı çok daha zor.
Martin Ender

2
Güzel ilk meydan okuma! Siteye Hoşgeldiniz!
Luis Mendo

Yanıtlar:


10

MATL , 85 83 bayt

Ve bir spiralyerleşik yapıya sahip olmanın kısa kod getireceğini düşündüm ...

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

Çevrimiçi deneyin!

açıklama

Let , N giriş belirtmektedir. Uzunluğun bir vektörünü ceil(sqrt(N+2))^2, yani N + 2'ye eşit veya bu değeri geçen en küçük mükemmel kareyi yaratacağız . Bu vektör sayısal değerlerle doldurulacak, bir spiral (yuvarlamasının mükemmel bir kare olması gerekiyor) ve ardından sayısal değerler karakterlerle değiştirilecektir.

Let , n spiralin merkezine 1'den başlayarak her adımı ifade etmektedir. Yılan döner tarafından verilen adımları n 2 için: (2, 5, 10, ... olan) +1 \semboller ve n, 2 + n + 1 (olup: 3, 7, 13, ...) için /. Bir arasına adımlar \ve /olmalı -ve aralarında olanlar /ve \olması gerektiği |.

Vektör, 1dönüş noktalarında (2,3,5,7,10,13 ...) ve 0diğerlerinde içerecek şekilde oluşturulur . Birikimli toplamın paritesi, her girişin bir mi -yoksa bir mi olması gerektiğini söyler |. Bu sonuca 1 ekleyerek 1(for |) veya 2(for -) içeren bir vektör elde ederiz . Ama bu kendilerini haline dönüş puan yapar 1veya 2çok. Bu yüzden konumlarını bildiğimiz dönüş noktalarının üzerine yazılır: n 2 +1 3pozisyonları ve n 2 + n + 1 pozisyonları ile doldurulur 4. Kuyruk ve kafa da özel durumlar: vektörün ilk elemanı (kuyruğu) 5ve N endeksi olan eleman+2 (kafa) olarak ayarlanmış 6. Son olarak, N + 2'yi aşan endekslere sahip elemanlar olarak ayarlanır 0.

Örnek olarak N = 19 girişini alırsak , artık uzunluğu 25 olan bir vektörümüz var:

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

Bu vektörü bir spiral halinde yuvarlamamız gerekiyor. Bunun için, bir spiral matris üreten yerleşik bir fonksiyon kullanıyoruz, bunu üretmek için yansıma ve transpozisyon izliyoruz:

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 

Vektörün matris ile indekslenmesi

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

burada 0boşluğa karşılık gelir, 1karşılık gelir |, 2için -, 3için \, 4için /, 5için @, ve 6baş.

Dört karakter olduğunu bilmek ^, <, vveya >baş olmalıdır, biz daha önce hesaplanan bu dönüş noktalarının kümülatif toplamını kullanır. Spesifik olarak, bu kümülatif toplamın ikinci-son değeri (yani N + 1-inci değer) modulo 4, kafa için hangi karakterin kullanılması gerektiğini söyler. Biz çünkü "bir köşede baş uçları kafa eğer ihtiyacının, kümülatif toplamı, son değil ikinci son değer alır <, >, ^, vyılan kıvrılmış yönde önceliği". İçin N 19 örnek = başıdır >.

Şimdi altıncı pozisyonda kafa için uygun karakteri dahil tüm yılan karakterleri içeren bir dize inşa edebilirsiniz: '|-\/@> '. Daha sonra bu dizeyi yukarıdaki matrisle indeksledik (indeksleme 1 tabanlı ve modüler, yani alan son oluyor),

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

1
harika iş! Katıldığınız için teşekkürler!
jacksonecac

8

Python 2, 250 233 191 bayt

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)
  • @JonathanAllan sayesinde 39 bayt kaydedildi

repl.it

Yılanın tamamını saat yönünde 90 rota döndürerek ve alt parçayı ekleyerek yılanı çizin, böylece yılan her zaman saat yönünün tersine döner.
Yeni bir segment hep birlikte başlayacak \ve sahip -hatta taraf için organ olarak ve / -tek taraf için. (Köşesiz) parçaları boyutları 0, 1, 1, 2, 2, 3... olan floor(side/2).
Segment en sonuncuysa, fazla karakterleri kaldırır, başlığı ekler ve boşluklarla tamamlar.

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)

İyi iş! Tiebreaker kazanırsın. İnsanların başka nelerle geldiğini görelim.
jacksonecac

2
Elbette bu, bu zorluğun çözüleceği ideal dildir.
Neil

+1. Sadece bir aksaklık, kafa bir köşede olduğunda, köşeyi değil düz bir noktaya gelmesi gerektiğidir.
Jonathan Allan,

1
: 16 şöyle dizeleri içine endeksleme tarafından bayt kaydet '\/'[m], '-|'[m]ve'>v'[m]
Jonathan Allan

1
printVe''.join
Jonathan Allan

7

JavaScript (ES6), 193 201 203 215 220 224

Düzenleme 4 thx @Arnauld bayt kurtardı
Edit2 mantık, sadece şimdiki yönden onları almak, x ve y cari artışlarını saklamak değil değişti
Edit3 , birkaç byte kurtarılışına ben boş yerin daha iyi yönetimi için bunları kullanmaya karar
Edit4 8 bayt, baş yönüyle ilgili örnekleri tam olarak takip etmeden kaydedildi - diğer cevaplar gibi

Geçerli sürüm Chrome, Firefox ve MS Edge ile çalışır

Bu cevap bazı izler ve başlıklar (ve boşluklar) verir.

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`
`

Biraz daha az golf oynadı

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>


Sen değiştirerek birkaç byte kaydedebilirsiniz (' ')ile ` ` ve ('@')ile`@`
Arnauld

@Arnauld Array (2) .fill` `==> [ Array[1], Array[1] ], Array(2).fill(' ')==>[' ',' ']
usandfriends

@ binfriends - Doğru. Fakat bu bir kez katıldığında herhangi bir fark yaratmamalı.
Arnauld,

@En önce ben ve arkadaşlarımla aynı fikirdeyim, ama gerçekten işe yarıyor. Thanks
edc65 5:16

@TravisJ Chrome'da çalışmıyor, ancak Firefox çalışıyor gibi görünüyor.
Adnan,

3

JavaScript (ES7), 200 bayt

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

Test kolaylığı için ES6 sürümü:

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>


İlginç uygulama. Bunu yapmayı düşünmemiştim. Katkıları ve güzel iş için teşekkür ederiz!
jacksonecac

3

Perl, 111 110 bayt

İçin +1 içerir -p

STDIN'e boyut verin

snake.pl:

#!/usr/bin/perl -p
s%> %->%+s%\^ %/>%||s/
/  
/g+s%.%!s/.$//mg<//&&join"",//g,$/%seg+s/ /^/+y%/\\|>-%\\/\-|%for($\="/
\@
")x$_}{

Müthiş! İyi iş! Katkınız için teşekkürler!
jacksonecac

0

Toplu iş, 563 bayt

@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:/\=/@%

Açıklama: Kodun geri kalanı olarak özel durumlar 1, en az iki yılan genişliği gerektirir. Ardından, alanı yılanın uzunluğundan daha az olan en büyük çeyrek kareyi (tam kare veya yüksek olandan 1 dikdörtgen) hesaplar. Yılan sol alt köşeden başlayıp kuyruğun ortasından bitecek şekilde bu dikdörtgenin içine sarılır ve kalan uzunluk dikdörtgenin altından geçer. Dikdörtgen aslında basit dize değişimlerinden üretilir; çapraz çizgiler 1 aşamayı hareket ettirmek suretiyle her bir çizginin bir önceki çizgiden üretildiği zaman çoğu zaman, ancak açıkça görüldüğü üzere kuyruğun da ele alınması gerekir ve dikdörtgenin yüksekliğinin eşit veya tek olmasına bağlı olarak hafif farklılıklar vardır.


Müthiş! Katkınız için teşekkürler!
jacksonecac

-1

Python 2.7, Bir WHOPPING 1230 bayt

Python'da ve golf kodunda yeniyim ama kendi soruma cevap vermek zorunda kaldığımı hissettim ve bu durumdan sonra utanç duyuyorum. Bununla birlikte çalışırken çok eğlenceli!

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


5
Gereksiz boşlukları, yeni satırları, yorumları, işlevleri vb. Kaldırarak bu büyük ölçüde azaltılabilir.
Addison Crump
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.