医生,我们螺旋式上升!


11

为了逃避达莱克部队的努力,医生决定将它们以螺旋运动在各个空间移动,从而使其旋转。

根据可用时空的性质,医生需要进入TARDIS,控制空间部分的高度和宽度以及开始螺旋的入口点。

可以将空间的一部分想象成一个h x w的网格,从左到右,从上到下,从1开始填充连续的整数。

起始位置以rc的形式提供给行和列...从这开始,TARDIS的软件需要吐出从rc沿逆时针方向向外螺旋地向上获得的整数的有序列表。

作为Doctor的助手,您的任务是对TARDIS进行编程,使其采用以下格式的四个数字,height width row column并确定TARDIS需要移动哪个空间区域以匹配下面描述的螺旋运动...

输入1

5 5 3 3

(5 x 5格,从位置3,3开始)

输出1

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

解释输出

原始网格 在此处输入图片说明

产生螺旋 在此处输入图片说明

输入2

2 4 1 2

(从位置1,2开始的2 x 4网格)

输出2

2 1 5 6 7 3 8 4

解释输出

略有不同,因为螺旋现在必须围绕网格旋转才能生成相应的输出...

原始网格 在此处输入图片说明

产生螺旋 在此处输入图片说明

规则:

  1. 这是代码高尔夫球,因此最短的代码长度会得到批准。

  2. 以上示例必须用于测试您的代码。如果没有提供相应的输出,则说明存在问题...

  3. 您必须在答案中同时提供高尔夫版本和高尔夫版本的代码...

祝好运!


我可以向您指出draw.io,在那里可以快速制作出相当合理的图纸(您的手绘版本具有出色的可读性,只是我看不到任何红色圆圈)。考虑i.stack.imgur.com/xbLSA.png作为可以完成的示例。请注意,其中嵌入了xml,因此如果您进入draw.io,则可以从url导入。

我会记住这一点,因为我下次需要绘图时,@ MichaelT,谢谢您……
WallyWest 2015年

1
我发布一个答案,函数返回数组作为输出。可以接受吗?
edc65

@ edc65 Mate,您和我在CG上回到了这里,为此我将允许使用S(h,w,r,c)之类的功能... :)
WallyWest

Answers:


3

JavaScript的(ES6)124 163 177

编辑完全不同的方式,不需要数组来存储访问的单元格。利用每2圈后螺旋边增加1的事实。

// New way
f=(h,w,y,x)=>
  (e=>{
    for(o=[],d=i=t=l=0;l<w*h;i<t?i+=2:[i,d,e]=[1,-e,d,++t])
      o[l]=y*w-w+x,l+=x>0&x<=w&y>0&y<=h,x+=d,y-=e
  })(1)||o


// Golfed
g=(h,w,y,x)=>
  (g=>{
    for(e=n=0;n<h*w;)g[[n%w+1,-~(n/w)]]=++n;
    for(o=[g[[x,y]]],l=d=1;l<n;l+=!!(o[l]=g[[x+=d,y+=e]]))
      g[[x,y]]=0,
      g[[x+e,y-d]]!=0&&([d,e]=[e,-d])
  })([])||o



// Not golfed
u=(h,w,y,x)=>{
  var i,j,dx,dy,kx,ky,o,n,
    g={} // simulate a 2dimensional array using a hashtable with keys in the form 'x,y'

  for(n=i=0; i++<h;) // fill grid (probably better done in a single loop)
    for(j=0; j++<w;)
      g[[j,i]] = ++n;
  o=[g[[x,y]]] // starting point in output
  dx=1, dy=0 // start headed right
  
  for(; !o[w*h-1]; ) // loop until all w*h position are put in output
  {
    g[[x, y]] = 0 // mark current position to avoid reusing
    kx=dy, ky=-dx // try turning left
    if(g[[x+kx, y+ky]] != 0) // check if position marked
    { // found a valid position
      dx=kx, dy=ky // change direction
    }
    x+=dx, y+=dy // move
    k=g[[x, y]] // get current value
    if (k) o.push(k) // put in output list if not 'undefined' (outside grid)
  }
  return o
}

// TEST - In FireFox

out=x=>O.innerHTML+=x+'\n';
[
 [[5,5,3,3],'13 8 7 12 17 18 19 14 9 4 3 2 1 6 11 16 21 22 23 24 25 20 15 10 5'],
 [[2,4,1,2],'2 1 5 6 7 3 8 4']
].forEach(t=>out(t[0] + '\n Result: ' + f(...t[0])+'\n Check:  ' + t[1]))

test=()=>
{
  var r, i=I.value.match(/\d+/g), h=i[0]|0, w=i[1]|0, y=i[2]|0, x=i[3]|0
  if (y>h||x>w) r = 'Invalid input'
  else r = f(h,w,y,x)
  out(i+'\n Reault: ' +r)
}
<pre id=O></pre>
Your test:<input id=I><button onclick="test()">-></button>


惊人的高尔夫!从300到163 ...我向你摘下帽子...
WallyWest

1
@WallyWest的评论让您推动我做得更好。Thnx
edc65

真好!我的Python解决方案长了很多,但我想,没关系,您可以使用更好的方法。现在您使用的是相同的东西,它甚至更短...我要做一些工作。:)
randomra'5

@randomra我还是很想看看...
WallyWest 2015年

2

Python 3、191

可能分数不高,但实际情况如下:

def f(b,a,d,c):
 p,r,l,s,h=c+1j*d,-1j,1,0,0
 for _ in [0]*((a+b)**2):x,y=p.real,p.imag;0<x<a+1and 0<y<b+1and print(int((y-1)*a+x),end=' ');p+=r;s=(s+1)%l;t=s==0;h=(h+t)%2;l+=h<t;r*=(-1j)**t 

我们每隔一秒钟转一圈,通过增加边长来沿着螺旋运动。如果我们的位置在给定的网格内,我们将打印其相应的数字。

变量是:

  • p是复数位置
  • x和y是位置坐标
  • r是方向
  • s是当前边的位置
  • l是当前边长
  • h是当前边序数的奇偶校验
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.