pssssssssssssst


31

Giới thiệu

Đây là một trong những khá đơn giản. Chúng tôi sẽ vẽ một con rắn trong ascii. Điều này được lấy cảm hứng từ trò chơi rắn cũ mà bạn phải thu thập trái cây và bạn liên tục phát triển.

Định nghĩa

Cho một số nguyên dương N đại diện cho chiều dài của con rắn, vẽ một con rắn sao cho nó có một cơ thể n cộng với một cái đầu và một cái đuôi.

Các bộ phận:

  • cái đầu: <, >, ^, v
  • đuôi: @
  • theo chiều dọc: |
  • đường chân trời: -

Tất cả các góc nên được thỏa mãn với một \hoặc /tương ứng. Trừ khi đầu kết thúc ở một góc, trong trường hợp đó, đầu <, >, ^, vđược ưu tiên theo hướng con rắn cuộn tròn. tức là đối với ví dụ chiều dài 1, nó được quay ngược chiều kim đồng hồ và do đó đầu được quay theo cách đó. Đối với một giải pháp theo chiều kim đồng hồ, nó sẽ ở bên phải >.

Con rắn phải bắt đầu ở giữa với đuôi của nó nhưng nó có thể đi ra ngoài theo bất kỳ hướng nào bạn chọn theo chiều kim đồng hồ hoặc ngược chiều kim đồng hồ. Nó cũng phải quấn chặt quanh nó khi nó mở rộng ra theo kiểu vòng tròn.

Thí dụ

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

Trường hợp @là đuôi và vị trí bắt đầu. Như đã thấy ở trên đuôi bắt đầu ở giữa, đi lên bên trái theo một vòng quay ngược chiều kim đồng hồ ra bên ngoài.

Ở đây chiều dài 19cộng với một cái đuôi và một cái đầu.

Một ví dụ khác, đây là chiều dài 1:

<\
 @

Chiến thắng

Đây là môn đánh gôn, vì vậy câu trả lời được gửi với số byte nhỏ nhất sẽ thắng, với thời gian được sử dụng làm bộ ngắt kết nối.

Chúc vui vẻ!


2
Không rõ lắm là tôi không được phép vẽ một con rắn thẳng như thế @---->. Bạn có thể có ý định điều kiện nghiêm ngặt hơn về hình dạng con rắn. Ngoài ra, hãy làm rõ có bao nhiêu khoảng trắng hoặc không được phép
TonMedel 4/10/2016

1
"Con rắn phải bắt đầu ở giữa với đuôi của nó nhưng nó có thể đi ra ngoài theo bất kỳ hướng nào bạn chọn và theo chiều kim đồng hồ hoặc ngược chiều kim đồng hồ"
jacksonecac

1
Vì vậy, tôi nói @là ở giữa (có thể thêm một số khoảng trắng để làm cho nó như vậy), khai báo "bên phải" để làm hướng và làm cho chỉ đầu hướng xuống và khai báo theo chiều kim đồng hồ. Điều khoản của bạn có vẻ rõ ràng với bạn, nhưng chúng thực sự mơ hồ. Tôi nhận ra bạn có thể có nghĩa là một con rắn cuộn càng chặt càng tốt, nhưng bạn nên làm rõ điều đó
TonMedel

1
Đừng lo lắng. Đó là một khó khăn hơn rất nhiều do sự bù đắp trong thử thách đó.
Martin Ender

2
Thử thách đầu tiên tốt đẹp! Chào mừng đến với trang web!
Luis Mendo

Câu trả lời:


10

MATL , 85 83 byte

Và tôi nghĩ rằng việc có một spiralnội trang sẽ tạo ra mã ngắn ...

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

Hãy thử trực tuyến!

Giải trình

Gọi N là đầu vào. Chúng ta sẽ tạo một vectơ có độ dài ceil(sqrt(N+2))^2, nghĩa là hình vuông hoàn hảo nhỏ nhất bằng hoặc vượt quá N +2. Vectơ này sẽ được lấp đầy với các giá trị số, được cuộn thành một hình xoắn ốc (đó là lý do tại sao độ dài của nó cần phải là một hình vuông hoàn hảo), và sau đó các giá trị số sẽ được thay thế bằng các ký tự.

Gọi n là mỗi bước bắt đầu từ 1 tại tâm xoắn ốc. Các bước mà con rắn quay được đưa ra bởi n 2 +1 (nghĩa là: 2, 5, 10, ...) cho \các ký hiệu và n 2 + n +1 (nghĩa là: 3, 7, 13, ...) cho /. Các bước giữa a \và a /nên -và những bước giữa a /và a \nên |.

Vectơ được tạo sao cho nó chứa 1tại các điểm rẽ (2,3,5,7,10,13 ...) và 0ở phần còn lại. Tính chẵn lẻ của tổng tích lũy cho biết mỗi mục nên là a -hoặc a |. Thêm 1 vào kết quả này, chúng ta sẽ có một vectơ chứa 1(for |) hoặc 2(for -). Nhưng điều này làm cho các điểm lần lượt trở thành 1hoặc 2quá. Vì vậy, các điểm rẽ, có vị trí mà chúng ta biết, được ghi đè: vị trí n 2 +1 được điền 3và vị trí n 2 + n +1 được điền vào 4. Đuôi và đầu cũng là trường hợp đặc biệt: phần tử đầu tiên của vectơ (đuôi) được đặt thành 5và phần tử có chỉ số N+2 (đầu) được đặt thành 6. Cuối cùng, các phần tử có chỉ số vượt quá N +2 được đặt thành 0.

Lấy đầu vào N = 19 làm ví dụ, giờ đây chúng ta có một vectơ có độ dài 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

Chúng ta cần cuộn vector này thành một hình xoắn ốc. Để làm điều này, chúng tôi sử dụng hàm dựng sẵn tạo ra ma trận xoắn ốc, theo sau là sự phản chiếu và chuyển vị để tạo ra:

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 

Lập chỉ mục vectơ với ma trận cho

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

nơi 0tương ứng với không gian, 1tương ứng với |, 2để -, 3đến \, 4đến /, 5đến @, và 6vào đầu.

Để biết được trong bốn nhân vật ^, <, v, hoặc >người đứng đầu cần phải có, chúng tôi sử dụng số tiền tích lũy điểm lần lượt là chúng ta tính toán trước đây. Cụ thể, giá trị cuối cùng thứ hai của tổng tích lũy này (tức là giá trị N + 1) modulo 4 cho chúng ta biết nên sử dụng ký tự nào cho đầu. Chúng tôi có giá trị thứ hai cuối cùng của tổng tích lũy, không phải là cuối cùng, vì yêu cầu "nếu người đứng đầu tận cùng trên một góc đầu <, >, ^, vđược ưu tiên theo hướng con rắn đang cuộn tròn". Đối với ví dụ N = 19 thì đầu là >.

Bây giờ chúng ta có thể xây dựng một chuỗi chứa tất cả các ký tự rắn, bao gồm cả ký tự thích hợp cho đầu ở vị trí thứ sáu : '|-\/@> '. Sau đó, chúng tôi lập chỉ mục chuỗi này với ma trận trên (lập chỉ mục là dựa trên 1 và mô-đun, vì vậy không gian sẽ kéo dài), điều này mang lại

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

1
công việc tuyệt vời cảm ơn vì đã tham gia!
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)
  • Đã lưu 39 byte nhờ @Jonathan ALLan

thay thế

Vẽ con rắn bằng cách xoay toàn bộ con rắn 90 độ theo chiều kim đồng hồ và thêm đoạn dưới cùng, theo cách này con rắn sẽ luôn luôn ngược chiều kim đồng hồ.
Phân khúc mới sẽ luôn bắt đầu với \và có -cơ thể cho các mặt chẵn và / -các mặt lẻ. Các kích thước phân đoạn (không có các góc) là 0, 1, 1, 2, 2, 3... đó là floor(side/2).
Nếu đoạn cuối cùng, nó sẽ loại bỏ các ký tự thừa, thêm phần đầu và hoàn thành với khoảng trắng.

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)

Công việc tốt! bạn có chiến thắng tiebreaker. Hãy xem những gì người khác đến với.
jacksonecac

2
Chắc chắn đây là ngôn ngữ lý tưởng để giải quyết thách thức này.
Neil

+1. Chỉ có trục trặc là khi đầu nằm ở một góc, nó có nghĩa là chỉ thẳng chứ không phải quanh góc.
Jonathan Allan

1
Lưu 16 byte bằng cách đánh chỉ số thành chuỗi như vậy: '\/'[m], '-|'[m]'>v'[m]
Jonathan Allan

1
Tiết kiệm thêm 1 bằng cách xóa khoảng cách giữa print''.join
Jonathan Allan

7

JavaScript (ES6), 193 201 203 215 220 224

Chỉnh sửa đã lưu 4 byte thx @Arnauld
Edit2 đã thay đổi logic, không lưu trữ số gia hiện tại cho x và y, chỉ cần lấy chúng từ hướng hiện tại
Edit3 đã lưu một vài byte, tôi quyết định sử dụng chúng để quản lý tốt hơn không gian trống
Edit4 8 byte được lưu không tuân theo chính xác các ví dụ về hướng đầu - giống như các câu trả lời khác

Phiên bản hiện tại hoạt động với Chrome, Firefox và MS Edge

Câu trả lời này cung cấp một số dấu cách và không gian hàng đầu (và các dòng trống).

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

Hơi ít chơi 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>


Bạn có thể lưu một vài byte bằng cách thay thế (' ')bằng ` ` ('@')bằng`@`
Arnauld

@Arnauld Mảng (2) .fill` `==> [ Array[1], Array[1] ], trong khi Array(2).fill(' ')==>[' ',' ']
usandfriends

@usandfriends - Đúng. Nhưng điều đó sẽ không tạo ra bất kỳ sự khác biệt nào khi tham gia.
Arnauld

@Arnauld lúc đầu tôi đồng ý với usandfriends, nhưng nó thực sự hoạt động. Cảm ơn
edc65

@TravisJ Nó không hoạt động trong Chrome, nhưng Firefox dường như hoạt động.
Ad Nam

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

Phiên bản ES6 để dễ kiểm tra:

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>


Thực hiện thú vị. Tôi đã không nghĩ làm điều đó. Cảm ơn đã đóng góp và công việc tốt đẹp !!
jacksonecac

3

Perl, 111 110 byte

Bao gồm +1 cho -p

Cung cấp kích thước trên STDIN

snake.pl:

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

Tuyệt vời! Công việc tốt! Cảm ơn đã đóng góp!
jacksonecac

0

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

Giải thích: Các trường hợp đặc biệt 1 vì phần còn lại của mã yêu cầu chiều rộng con rắn ít nhất là hai. Tiếp theo, tính toán hình vuông quý lớn nhất (hình vuông chính xác hoặc hình chữ nhật 1 rộng hơn chiều cao) có diện tích nhỏ hơn chiều dài của con rắn. Con rắn sẽ được cuộn vào hình chữ nhật này bắt đầu từ góc dưới bên trái và kết thúc bằng đuôi ở giữa, và chiều dài còn lại sẽ chạy dưới đáy hình chữ nhật. Hình chữ nhật thực sự được tạo ra từ các thay thế chuỗi đơn giản; hầu hết thời gian mỗi dòng được tạo từ dòng trước bằng cách di chuyển các đường chéo 1 bước, nhưng rõ ràng đuôi cũng phải được xử lý, và có sự khác biệt nhỏ tùy thuộc vào chiều cao của hình chữ nhật là chẵn hay lẻ.


Tuyệt vời! Cảm ơn đã đóng góp!
jacksonecac

-1

Python 2.7, 1230 byte WHOPPING

Tôi chưa quen với python và code golf nhưng tôi cảm thấy mình phải trả lời câu hỏi của chính mình và hờn dỗi vì xấu hổ sau sự thật. Rất nhiều niềm vui làm việc trên đó mặc dù!

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
Điều này có thể được giảm một cách ồ ạt chỉ bằng cách xóa các khoảng trắng, dòng mới, nhận xét, chức năng, v.v.
Addison Crump
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.