pssssssssssssst


31

介绍

这很简单。我们将在ascii中画一条蛇。这是从那个古老的蛇游戏中获得灵感的,您必须收集果实并不断成长。

定义

给定一个代表蛇的长度的正整数N,绘制一条蛇,使它的主体为n加上头和尾。

部分:

  • 头: <, >, ^, v
  • 尾巴: @
  • 垂直: |
  • 水平的: -

所有角都应分别用\或表示/。除非头部不在一个角上,否则在这种情况下头部<, >, ^, v在蛇的卷曲方向上优先。例如,对于长度1的示例,它是逆时针方向旋转的,因此磁头会以这种方式旋转。对于顺时针方向的解决方案将是正确的>

蛇的尾巴必须从中间开始,但是它可能会沿您选择的顺时针或逆时针方向向外延伸。当它以圆形方式向外扩展时,它还必须紧紧包裹自己。

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

哪里 @是尾巴和起始位置。从上方可以看到,尾巴从中间开始,以逆时针方向向外旋转到左侧。

这里的长度是19尾巴和头。

再举一个例子,这里是length 1

<\
 @

获奖

这是代码高尔夫球,因此以最少的字节数提交的答案会获胜,并且有时间用作决胜局。

玩得开心!


2
还不是很清楚我是否不能像那样画一条直蛇@---->。您可能打算对蛇形设置更严格的条件。还要弄清楚允许或不允许多少空格
Ton Hospel

1
“蛇必须从尾巴开始在中间,但它可能会朝您选择的任何方向向外(顺时针或逆时针)
延伸

1
因此,我说的@是中间位置(可能要添加一些空格以使其成为中间位置),将“向右”声明为方向,仅使头部指向下方,然后顺时针声明该方向。您的用语对您来说似乎很清楚,但实际上是模棱两可的。我意识到您可能是指一条尽可能紧紧的盘绕的蛇,但您应该清楚说明这一点
Ton Hospel'Oct 4'16

1
不用担心 由于克服了这一挑战,因此要困难得多。
Martin Ender

2
不错的第一个挑战!欢迎光临本站!
路易斯·门多

Answers:


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开始的每个步骤。其中蛇匝由下式给出的步骤Ñ 2为:1(2,5,10,...那是)\符号和Ñ 2 + Ñ 1(即:3,7,13,...)为/。一个之间的步骤\和一个/-,和那些之间/和一个\|

创建矢量,使其包含1转折点(2,3,5,7,10,13 ...)和0其余转折点。累积总和的奇偶校验指示每个条目应该是a -还是a |。将1加到这个结果中,我们得到一个包含1(for |)或2(for -)的向量。但是这使得依次指向自己变得12过。因此,我们知道其位置的转折点将被覆盖:位置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头部。

要知道这四个大字^<v,或>头应该有,我们用我们先前计算的转点的累计总和。具体来说,该累加和的倒数第二个值(即N + 1个值)的模数为4告诉我们哪个字符应该用于头部。我们采取的是因为该规定“如果在一个角落里的头端头的累计总和,而不是最后的倒数第二个价值,<>^v优先在蛇卷曲的方向”。对于N = 19的示例,头为>

现在,我们可以构建一个包含所有蛇字符的字符串,包括在第六个位置的头部适当的字符'|-\/@> '。然后,我们使用上面的矩阵对这个字符串进行索引(索引是基于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个字节

代表

通过将整个蛇顺时针旋转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
当然,这是解决这一挑战的理想语言
Neil

+1。唯一的毛病是,当头部在拐角处时,它的意思是笔直而不是拐角。
乔纳森·艾伦

1
保存16个字节通过索引进入像这样的字符串:'\/'[m]'-|'[m]'>v'[m]
乔纳森·艾伦

1
删除和之间的空格,print再节省1个''.join
Jonathan Allan

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] ],而Array(2).fill(' ')==>[' ',' ']
usandfriends

@usandfriends-是的。但这一旦加入就不会有任何区别。
Arnauld

@Arnauld起初我与usandfriends达成了一致,但是确实有效。谢谢
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,111110字节

包括+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
这可以大规模刚刚通过消除不必要的空格,换行,注释,函数等。减少
艾迪克伦普
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.