pssssssssssssstst


31

前書き

これは非常に簡単です。アスキーでヘビを描きます。これは、果物を収集し、継続的に成長しなければならない古いヘビのゲームに触発されました。

定義

ヘビの長さを表す正の整数Nが与えられた場合、ヘビを描画して、nの体に頭と尾を加えます。

部品:

  • 頭: <, >, ^, v
  • 尾: @
  • 垂直: |
  • 水平: -

すべてのコーナーは、\またはで/それぞれ満たされる必要があります。頭が角で終わっていない限り、頭<, >, ^, vは蛇がカールする方向に優先されます。すなわち、長さ1の例の場合、反時計回りに回されるため、ヘッドはそのように回されます。時計回りのソリューションの場合、右側になり>ます。

ヘビは尾の真ん中から始まらなければなりませんが、時計回りまたは反時計回りのどちらの方向にでも外向きに行くことができます。また、円形に外側に広がるにつれて、それ自体をしっかりと包む必要があります。

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

どこ @が尾と開始位置です。上に見られるように、尾は中央から始まり、左回りに外側に反時計回りに回転します。

ここで、長さは19尾と頭を加えたものです。

別の例として、長さは1次のとおりです。

<\
 @

勝ち

これはコードゴルフなので、最小バイト数で送信された回答が優先され、タイブレーカーとして使用される時間がかかります。

楽しむ!


2
のようなまっすぐな蛇を描くことを許可されているだけではないことはあまり明確ではありません@---->。あなたはおそらくヘビの形についてより厳しい条件を意図しています。また、空白がどれだけ許可されているか、または許可されていないかを明確にしてください。
Ton Hospel

1
「蛇は尾で真ん中から始まらなければなりませんが、時計回りまたは反時計回りのどちらの方向にでも外に出ることがあります」
-jacksonecac

1
だから、私は言う@(それを作るためにいくつかのスペースを追加することができます)、方向として「右に」を宣言し、ちょうど頭を下に向けて、それを時計回りに宣言します。あなたの条件は明確に見えるかもしれませんが、実際にはあいまいです。おそらく、できる限りきつい巻き蛇を意味していると思いますが、それを明確にする必要があります
トンホスペル

1
心配しないで。その挑戦のオフセットのために、それはずっと難しいです。
マーティンエンダー

2
素敵な最初の挑戦!サイトへようこそ!
ルイスメンドー

回答:


10

MATL85 83バイト

そして、spiralビルトインがあると短いコードになると思いました...

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

オンラインでお試しください!

説明

してみましょうNは入力を示します。lengthのベクトルceil(sqrt(N+2))^2、つまりN +2 以上の最小完全正方形を作成します。このベクトルには数値が入力され、らせん状に丸められ(その長さが完全な正方形である必要があります)、数値は文字に置き換えられます。

ましょN螺旋の中心に1から始まる各ステップを示します。ヘビが回るステップは、シンボルのn 2 +1(つまり、2、5、10、...)\n 2 + n +1(つまり、3、7、13 、...)によって与えられます。のために/。間のステップ\/であるべきである-、との間のもの/\であるべきです|

ベクトルは1、ターンポイント(2、3、5、7、10、13 ...)および0残りに含まれるように作成されます。累積合計のパリティは、各エントリがa -かaかを示し|ます。この結果に1を加えると、1(for |)または2(for -)を含むベクトルが得られます。しかし、これにより、転換点自体が、1またはそれ以上になり2ます。そのため、位置がわかっているターンポイントは上書きされます。位置n 2 +1は塗りつぶされ3、位置n 2 + n +1は塗りつぶされ4ます。テールとヘッドも特殊なケースです:ベクトルの最初の要素(テール)はに設定され5、インデックスNの要素+2(ヘッド)はに設定され6ます。最後に、インデックスがN +2 を超える要素はに設定され0ます。

入力N = 19を例にとると、長さ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

このベクトルを渦巻きに巻く必要があります。このために、スパイラルマトリックスを生成する組み込み関数を使用し、その後に反射と転置を行って以下を生成します。

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 

行列でベクトルにインデックスを付けると、

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

ここで、0空間に相当、1に相当する|2-3\4/5@、と6ヘッド。

知っている4文字のどのために^<v、または>ヘッドが持つべき、我々は以前に計算されたターンポイントの累積合計を使用します。具体的には、この累積合計の最後から2番目の値(つまり、N +1番目の値)4を法として、どの文字を頭に使用すべきかがわかります。私たちは、理由は「コーナーの頭部端がヘッドがあれば要件を、累積和、最後ではないの最後から2番目の値をとる<>^v蛇がカールしている方向に優先されます」。以下のためにN = 19の例のヘッドです>

これで、6番目の位置の頭に適切な文字を含む、すべての蛇文字を含む文字列を作成できます。 '|-\/@> '。次に、この文字列に上記のマトリックスを使用してインデックスを付けます(インデックス付けは1ベースでモジュール式なので、スペースが最後になります)。

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

1
素晴らしい仕事!参加してくれてありがとう!
jacksonecac

8

Python 2、250 233 191バイト

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のおかげで39バイト節約

repl.it

ヘビ全体を時計回りに90度回転させ、下部セグメントを追加して、ヘビを描画します。これにより、ヘビは常に反時計回りになります。
新しいセグメントは常に始まります\し、持って-も、両側のための体のように/ -奇数の辺のために。(コーナー無し)セグメントサイズがあり011223...ですfloor(side/2)
セグメントが最後の場合、余分な文字を削除し、頭を追加してスペースで補完します。

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)

良くやった!タイブレーカーが勝ちます。他の人々が思いついたものを見てみましょう。
jacksonecac

2
確かに、これはこの課題を解決するための理想的な言語です
ニール

+1。唯一の不具合は、頭が角にあるとき、角を曲がるのではなく、まっすぐに指すことを意味します。
ジョナサンアラン

1
次のような文字列にインデックスを付けることで16バイトを節約します'\/'[m]'-|'[m]および'>v'[m]
ジョナサンアラン

1
間にスペースを除去することにより、保存1以上print''.join
ジョナサン・アラン

7

JavaScript(ES6)、193 201 203 215 220 224

編集は4バイトを保存しましたthx @Arnauld
Edit2はロジックを変更し、xとyの現在の増分を保存せず、現在の方向からそれらを取得します
Edit3は数バイトを保存し、
Edit4 8他の回答のように、頭の方向に関する例に正確に従わずに保存されたバイト

現在のバージョンはChrome、Firefox、MS Edgeで動作します

この答えは、末尾と先頭のスペース(および空白行)を提供します。

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

ゴルフがやや少ない

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>


あなたは置き換えることによって、数バイトを保存することができ(' ')` ` ('@')して`@`
アルノー

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

@usandfriends-はい。しかし、一度参加すれば、違いは生じないはずです。
アーナルド

@Arnauld最初は私たちと友達に同意しましたが、実際に機能します。ありがとう
-edc65

@TravisJ Chromeでは動作しませんが、Firefoxは動作するようです。
アドナン

3

JavaScript(ES7)、200バイト

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

テストを容易にするES6バージョン:

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>


興味深い実装。私はそうすることを考えていませんでした。貢献してくれてありがとう。
jacksonecac

3

Perl、111 110バイト

+1を含む -p

STDINでサイズを指定する

snake.pl

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

驚くばかり!良くやった!貢献してくれてありがとう!
jacksonecac

0

バッチ、563バイト

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

説明:残りのコードとしての特殊なケース1では、少なくとも2のスネーク幅が必要です。次に、面積が蛇の長さよりも小さい最大の四分の一正方形(正確な正方形または高さが1より大きい長方形のいずれか)を計算します。ヘビは、左下隅から始まり、中央の尾で終わるこの長方形に巻き付けられ、残りの長さは長方形の底の下に続きます。長方形は実際には単純な文字列の置換から生成されます。ほとんどの場合、各行は前の行から対角線を1ステップ移動することで生成されますが、明らかにテールも処理する必要があり、長方形の高さが偶数か奇数かによって若干の違いがあります。


驚くばかり!貢献してくれてありがとう!
jacksonecac

-1

Python 2.7、WHOPPING 1230バイト

私はPythonとコードゴルフを初めて使いましたが、自分の質問に答えなければならないと感じ、事実に恥ずかしがりました。しかし、それに取り組むのはとても楽しいです!

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
これは、大規模なだけで、不要なスペース、改行、コメント、機能、など。を除去することによって、減少させることができる
アディソンCrumpの
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.