切比雪夫旋转


36

考虑一个规则的网格,其中每个单元格都有整数坐标。我们可以将单元格分组为(方形)“环”,其中每个环中的单元格与原点的切比雪夫距离(或棋盘距离)相同。您的任务是获取一个像元坐标,并将该像元在其环内逆时针旋转一个位置。这实现了以下映射:

在此处输入图片说明

因此,例如,如果输入是(3, -2)您应该输出(3, -1)。请注意,这(0, 0)是唯一应映射到其自身的输入。

规则

I / O格式相当灵活。您可以使用两个单独的数字,一对数字/列表/数组/元组,单个复数,包含两个数字的字符串等。

您可能会认为-128 < x,y < 128

您可以编写程序或函数,并使用我们的任何标准方法来接收输入和提供输出。

您可以使用任何编程语言,但是请注意,默认情况下,这些漏洞是禁止的。

这是,因此以字节为单位的最短有效答案为准。

测试用例

(0, 0)       => (0, 0)
(1, 0)       => (1, 1)
(1, 1)       => (0, 1)
(0, 1)       => (-1, 1)
(-1, 1)      => (-1, 0)
(-1, 0)      => (-1, -1)
(-1, -1)     => (0, -1)
(0, -1)      => (1, -1)
(1, -1)      => (1, 0)
(95, -12)    => (95, -11)
(127, 127)   => (126, 127)
(-2, 101)    => (-3, 101)
(-65, 65)    => (-65, 64)
(-127, 42)   => (-127, 41)
(-9, -9)     => (-8, -9)
(126, -127)  => (127, -127)
(105, -105)  => (105, -104)

我们可以混合输入和输出格式,例如取一个元组并输出一个复数吗?
丹尼斯

@丹尼斯是的,很好。
Martin Ender

Answers:


16

JavaScript(ES6),60 59字节

以currying语法接受输入(x)(y)并返回一个数组[new_x, new_y]

x=>y=>(x|y&&((z=x+(y<0))>-y?z>y?y++:x--:z>y?x++:y--),[x,y])

怎么运行的

我们的主要任务是确定我们在哪个象限中,以便我们知道向哪个方向移动。

我们可以将此公式用作第一近似值:

x > -y ? (x > y ? 0 : 1) : (x > y ? 2 : 3)

这是我们得到的:

3 1 1 1 1 1 1 1 1
3 3 1 1 1 1 1 1 0
3 3 3 1 1 1 1 0 0
3 3 3 3 1 1 0 0 0
3 3 3 3 3 0 0 0 0
3 3 3 3 2 2 0 0 0
3 3 3 2 2 2 2 0 0
3 3 2 2 2 2 2 2 0
3 2 2 2 2 2 2 2 2

差不多好了。但是圆环的左下角和右下角无效。我们需要将矩阵的下半部分向左移动一个位置,因此我们定义z为:

z = y < 0 ? x + 1 : x

我们用公式替换xz

z > -y ? (z > y ? 0 : 1) : (z > y ? 2 : 3)

这导致:

3 1 1 1 1 1 1 1 1 
3 3 1 1 1 1 1 1 0 
3 3 3 1 1 1 1 0 0 
3 3 3 3 1 1 0 0 0 
3 3 3 3 3 0 0 0 0 
3 3 3 2 2 0 0 0 0 
3 3 2 2 2 2 0 0 0 
3 2 2 2 2 2 2 0 0 
2 2 2 2 2 2 2 2 0 

整个矩阵现在是正确的,除了特殊情况[0, 0](根本没有动静),必须单独解决。

测试用例


13

果冻20 14 12 字节

S;IṠN0n/¦Ạ¡+

输入和输出采用数组形式。在线尝试!验证所有测试用例

背景

为了弄清楚我们必须朝哪个方向移动,我们可以观察起点与象限二等分线x + y = 0(蓝色)和x-y = 0(红色)的相对位置。

图

  • 原点是固定的。我们通过在起点添加[0,0]来前进。

  • 最高三角形中的点(包括第一象限的等分线)具有正和和非负增量(y-x)。我们通过在起点添加[-1,0]来前进。

  • 最左边的三角形中的点(包括第二个象限的平分线)具有非正和和正三角形。我们通过在起点添加[0,-1]来进行前进。

  • 最下面的三角形中的点(包括第三象限的等分线)具有负和和非正增量。我们通过在起点添加[1,0]来前进。

  • 最右边的三角形中的点(包括第四象限的等分线)具有非负和和负德尔塔。我们通过在起点添加[0,1]来前进。

为了找出正确的方向,我们计算了[-sign(x + y),-sign(y-x)],它只有九种可能的结果。

下表说明了必须将哪些结果映射到哪个方向。

    sign(x+y) |  sign(y-x) | -sign(x+y) | -sign(y-x) |     Δx     |     Δy
  ------------+------------+------------+------------+------------+------------
        0     |      0     |      0     |      0     |      0     |      0
        1     |      0     |     -1     |      0     |     -1     |      0
        1     |      1     |     -1     |     -1     |     -1     |      0
        0     |      1     |      0     |     -1     |      0     |     -1
       -1     |      1     |      1     |     -1     |      0     |     -1
       -1     |      0     |      1     |      0     |      1     |      0
       -1     |     -1     |      1     |      1     |      1     |      0
        0     |     -1     |      0     |      1     |      0     |      1
        1     |     -1     |     -1     |      1     |      0     |      1

剩下三个案例。

  • 如果至少一个符号是0,则[Δx,Δy] = [-符号(x + y),-符号(yx)]

  • 如果符号相等且不为零,则[Δx,Δy] = [-sign(x + y),0]

  • 如果符号不同并且非零,则[Δx,Δy] = [0,-sign(yx)]

怎么运行的

S;IṠN0n/¦Ạ¡+  Main link. Argument: [x, y] (pair of integers)

S             Sum; compute x + y.
  I           Increments; compute [y - x].
 ;            Concatenate; yield [x + y, y - x].
   Ṡ          Sign; compute [sign(x + y), sign(y - x)].
    N         Negate; yield [-sign(x + y), -sign(y - x)].
          ¡   Do n times:
         Ạ      Set n to all([-sign(x + y), -sign(y - x)]), i.e., 1 if the signs
                are both non-zero and 0 otherwise.
        ¦       Conditional application:
      n/          Yield 1 if the signs are not equal, 0 if they are.
     0            Replace the coordinate at 1 or 0 with a 0.
              This returns [Δx, Δy].
           +  Add; yield  [Δx + x, Δy + y].


5

Python,55个字节

lambda x,y:(x-(-y<x<=y)+(y<=x<-y),y+(~x<y<x)-(x<y<=-x))

检测四个对角象限,并移动适当的坐标。


4

Haskell,77 71 69字节

x#y|y>=x,-x<y=(x-1,y)|y>x=(x,y-1)|y< -x=(x+1,y)|y<x=(x,y+1)|1>0=(0,0)

这只是检查每个倾斜的象限,并相应地修改输入。注意,空格是必需的,否则例如>-将其理解为运算符(未定义)。

感谢@nimi删除了更多字节!


,而不是&&在第一个警卫队内保存一个字节。然后,您可以将第二个比较切换-x<y为另一个字节。
nimi

谢谢,我没有意识到,
瑕疵的

4

Ruby,68岁

Lambda函数以复数为参数,返回复数。

->z{k=1
4.times{z*=?i.to_c
x,y=z.rect
y*y>=x*x&&y<-x&&(z+=k;k=0)}
z} 

通过乘以将点旋转90度4次i。因此,它会通过所有四个象限,并且将保持不变,除非我们在其中一个特定象限中对其进行了修改。总是在同一象限中对其进行修改的事实简化了修改。

如果我们将其更改z为右侧象限,则最容易遵循。在这种情况下,我们需要将y坐标增加1(即i加到)z

我们检查x.abs>=y.abs通过比较的平方xy。这告诉我们该点位于右侧或左侧象限,而不是顶部或底部。要检查它实际上是在右侧象限,我们进一步检查 x>y(严格更大,因为我们要排除的情况下,x=y属于“顶”象限。)如果这是真的,我们添加iz

由于打高尔夫球的原因,添加i是不希望的。相反,当数字位于底部象限时,我们将对其进行修改,在这种情况下,我们必须将1加到x坐标(将1加到)z。在这种情况下,我们测试y*y>=x*x以检查其是否位于顶部或底部象限。为了进一步确保它在底部象限中,我们需要检查y<-x(严格排除右下角在的情况)y=-x

此检查的优点是,坐标0,0没有特殊情况。不幸的是,发现移动点可以将其移动到不同的象限,这意味着如果再次检查该象限,则必须抑制第二个运动,这可能会抵消其优势。

例子1

Input                                        95,-12
Rotate 90deg                                 12,95    
Rotate 90deg                                -95,12    
Rotate 90deg                                -12,-95 
Rotate 90deg                                 95,-12
y.abs>=x.abs=TRUE, y<-x=TRUE, increase x     95,-11

The check and alteration of the coordinate is done AFTER the rotation.
Thus in this case it gets done in the 4th iteration of the loop, not the 1st.
If the code were rewritten to do the check and alteration BEFORE the rotation, 
it would be done in the 1st iteration instead of the 4th.

例子2

Input                                        -1,0
Rotate 90deg                                  0,-1
y.abs>=x.abs=TRUE, y<-x=TRUE, increase x      1,-1
Rotate 90deg                                  1,1
Rotate 90deg                                  1,-1
Rotate 90deg                                 -1,-1
y.abs>=x.abs?=TRUE, y<-x=TRUE but DO NOT CHANGE x!

This is an unusual situation due to the fact that the first move caused the
point to advance by one quadrant. We do NOT want to move it again, for this
reason we need to set k to 0 the first time it is moved.

在测试程序中

f=->z{k=1                   #amount to be added to coordinate
4.times{z*=?i.to_c          #iterate 4 times, rotating point by 90deg till it reaches the original orientation
x,y=z.rect                  #separate out x and y for testing
y*y>=x*x&&y<-x&&(z+=k;k=0)} #if y.abs>=x.abs and y negative and not equal -x, move the point and zero k.
z}                          #return z

puts f[Complex(0, 0)]       # (0, 0)
puts f[Complex(1, 0)]       # (1, 1)
puts f[Complex(1, 1)]       # (0, 1)
puts f[Complex(0, 1)]       # (-1, 1)
puts f[Complex(-1, 1)]      # (-1, 0)
puts
puts f[Complex(-1, 0)]      # (-1, -1)
puts f[Complex(-1, -1)]     # (0, -1)
puts f[Complex(0, -1)]      # (1, -1)
puts f[Complex(1, -1)]      # (1, 0)
puts f[Complex(95, -12)]    # (95, -11)
puts f[Complex(127, 127)]   # (126, 127)
puts
puts f[Complex(-2, 101)]    # (-3, 101)
puts f[Complex(-65, 65)]    # (-65, 64)
puts f[Complex(-127, 42)]   # (-127, 41)
puts f[Complex(-9, -9)]     # (-8, -9)
puts f[Complex(126, -127)]  # (127, -127)
puts f[Complex(105, -105)]  # (105, -104)

图表

下图显示了(蓝色)的区域x*x>=y*y,(黄色)区域y<-x和(绿色)它们的交点,这是正确的变换是将1加到的区域z

在此处输入图片说明


1
抱歉,我没有遵循说明。您介意添加示例还是图表?
Martin Ender

@Martin说明已添加。这是一种有趣的方法,但是由于需要抑制在第一次移动象限时会改变象限的点的两次移动,因此结果并没有我希望的那么优雅。
水平河圣

4

Python,52个字节

h=lambda z:z and 1j*h(z/1j)if'-'in`z*1j-z-1`else z+1

复杂的输入和输出。若要测试该点是否位于较低的对角象限中,请首先将其逆时针旋转135,以将该象限移动到(x> 0,y> 0)标准象限,然后测试结果是否在字符串表示中没有减号。首先减去1将注意边界条件。

如果不在该象限中,则将整个问题旋转90度。输入为零是经过特殊处理以自行输出的。

使用复数的其他尝试:

## 56 bytes
## Coordinate input, complex output
q=lambda x,y:(y<=x<-y)*(1j*y-~x)or x+1j*y and 1j*q(y,-x)

## 60 bytes
h=lambda z:(z+1)*(z.imag<=z.real<-z.imag)or z and 1j*h(z/1j)

## 63 bytes
from cmath import*
h=lambda z:z and 1j**(phase(z*1j-z)*2//pi)+z

3

Mathematica,34个字节

±0=0
±z_:=z+I^Floor[2Arg@z/Pi+3/2]

这定义了一个一元运算符±,该运算符采用并返回一个复数,其成分表示xy

既然Lynn公开了复数解决方案,而Dennis击败了我,我对于发布我的高尔夫球参考实现并不感到难过。:)(结果实际上与林恩的答案相同。)


这会有所帮助吗?±0 = 0⁢±z_:= z + I ^ 2⁢Arg @ z / Pi + 3/2⌋(也许地板支架的字符不同)
DavidC

@DavidC不幸的是不是,因为那样的话我必须使用UTF-8编码,然后±将花费2个字节。
Martin Ender

那不是4个字节而不是7个字节,从而节省了3个字节吗?
DavidC

@DavidC不,每个方括号为3个字节。
Martin Ender

我没有意识到。但是,即使这样,您仍然应该保存1个字节。
DavidC

3

MATL19 17字节

t|?JGJq*X/EYP/k^+

这使用复数作为输入和输出。

在线尝试!验证所有测试用例

说明

让我们以输入-127+42j为例。

t|       % Implicit input. Duplicate and take absolute value
         % STACK: -127+42j, 133.764718816286
?        % If nonzero
         % STACK: -127+42j
  J      %   Push j (imaginary unit)
         %   STACK: -127+42j, j
  GJq*   %   Push input multiplied by -1+j. This adds 3*pi/4 to the phase of the input
         %   STACK: -127+42j, j, 85-169i
  X/     %   Phase of complex number
         %   STACK: -127+42j, j, -1.10478465600433
  EYP/   %   Divide by pi/2
         %   STACK: -127+42j, j, -0.703327756220671
  k      %   Round towards minus infinity
         %   STACK: -127+42j, j, -1
  ^      %   Power
         %   STACK: -127+42j, -j
  +      %   Add
         %   STACK: -127+41j
         % Implicit end
         % Implicit display

3

Ruby,51个字节

原始形式

->x,y{d=x*x-y*y
[x+(d>0?0:-y<=>x),y+(d<0?0:x<=>y)]}

Xnor的评论的替代形式

->x,y{[x+(x*x>y*y ?0:-y<=>x),y+(x*x<y*y ?0:x<=>y)]}

使用与我的其他答案相同的不平等类型,但方式不同。

在测试程序中

f=->x,y{d=x*x-y*y
[x+(d>0?0:-y<=>x), #if y.abs>=x.abs: x+=1 if -y>x, x-=1 if -y<x 
y+(d<0?0:x<=>y)]}  #if x.abs>=y.abs: y+=1 if  x>y, y-=1 if  x<y

p f[0, 0]       # (0, 0)
p f[1, 0]       # (1, 1)
p f[1, 1]       # (0, 1)
p f[0, 1]       # (-1, 1)
p f[-1, 1]      # (-1, 0)
puts
p f[-1, 0]      # (-1, -1)
p f[-1, -1]     # (0, -1)
p f[0, -1]      # (1, -1)
p f[1, -1]      # (1, 0)
p f[95, -12]    # (95, -11)
p f[127, 127]   # (126, 127)
puts
p f[-2, 101]    # (-3, 101)
p f[-65, 65]    # (-65, 64)
p f[-127, 42]   # (-127, 41)
p f[-9, -9]     # (-8, -9)
p f[126, -12]   # (127, -127)
p f[105, -105]  # (105, -104)

d分配值得吗?看来您可以比较x*x>y*y
xnor

不幸的是,@ Xnor Ruby需要一个空格y*y?因此它的长度完全相同。我将其包括在内,因为我认为您的方式在某些方面更加整洁。我认为Ruby试图通过它,因为y?这将是一个合法的函数名称。
水平河圣

3

朱莉娅38 38字节

!z=z==0?0:z+im^int(2angle(z)/pi+1)

丹尼斯节省了四个字节。谢谢!

在线尝试!


看起来我在不同版本的Julia中混淆了int的行为(以我的辩称,这是非常不一致的)。Julia 0.4(TIO上的版本)将平均数减半,因此无法按原样工作。在Julia 0.3中,您可以使用int(2angle(z)/pi+5)相同的字节数(无论出于何种原因,负幂都会导致错误)。
丹尼斯

同样,您可以!z=z+(z!=0)im^...在所有版本中保存一个字节。
丹尼斯

2

C ++,94个字节

#define a(x) (x>0?x:-(x))
#define f(x,y) y>a(x-.5)?x--:-y>a(x+.5)?x++:x>a(y+.5)?y++:x|y?y--:x;

取消高尔夫:

#define a(x) (x>0?x:-(x))  //shorter than std::abs from <cmath>
#define f(x,y) 
    y>a(x-.5)?      // shift absolute value function by 0.5 to the right to get upper fourth
        x--:
        -y>a(x+.5)? //same for lower fourth
            x++:
            x>a(y+.5)? //same for right fourth
                y++:
                x|y? //only left fourth and 0 are left
                    y--:
                    x; //can't be empty, just does nothing

用法:

#include <iostream>
void test(int x, int y, int rx, int ry){
    std::cout << "(" << x << ", " << y << ")=>";
    f(x,y);
    std::cout << "(" << x << ", " << y << ") - " << ((x==rx&&y==ry)?"OK":"FAILURE") << std::endl;
}

//Using the test cases from the question
int main() {
    test(0, 0, 0, 0);
    test(1, 0, 1, 1);
    test(1, 1, 0, 1);
    test(0, 1, -1, 1);
    test(-1, 1, -1, 0);
    test(-1, 0, -1, -1);
    test(-1, -1, 0, -1);
    test(0, -1, 1, -1);
    test(1, -1, 1, 0);
    test(95, -12, 95, -11);
    test(127, 127, 126, 127);
    test(-2, 101, -3, 101);
    test(-65, 65, -65, 64);
    test(-127, 42, -127, 41);
    test(-9, -9, -8, -9);
    test(126, -127, 127, -127);
    test(105, -105, 105, -104);

    return 0;
}

在线尝试


我肯定(x>0?x:-(x))可以(x>0?x:-x)
伊西(Yytsi)

不幸的是没有,因为令牌x将被替换为例如x + .5,它将得到-x + .5。
Anedar

好的。我的思维定式是:没有括号的否定符号就会使符号翻转:D
Yytsi

严格来说,您使用了C 预处理程序(虽然它是C ++的一部分,但也与其他C变体和后代共享)
tucuxi

2

R,131110字节

该函数将两个整数x,y作为输入并将输出写入stdout。该解决方案遵循@Dennis的控制流方案,但可能会打高尔夫球。

编辑:根据@JDL的建议更新了代码,并节省了一堆字节。

function(x,y){X=sign(x+y);Y=sign(y-x);if(!X|!Y){x=x-X;y=y-Y}else if(X==Y&X&Y)x=x-X else if(X-Y&X)y=y-Y;c(x,y)}

不打高尔夫球

f=function(x,y){
    X=sign(x+y)                 # calculate sign 
    Y=sign(y-x)                 #  =||=
    if(!X|!Y){x=x-X;y=y-Y}      # if at least one is 0: subtract sign
    else if(X==Y&X&Y)x=x-X      # if signs are equal and non-zero: add sign to x
    else if(X-Y&X)y=y-Y         # if signs are not equal and non-zero: add sign to y
    c(x,y)                      # print to stdout
}

1
我认为某些逻辑条件可以缩短:as.logical(-1)TRUE,因此X==0|Y==0可以变为!X|!Y,条件if(X!=Y...)可以变为if(X-Y)。另外,如果X==YX!=0然后Y!=0是多余的。实际上,所有!=0部分都是多余的。if(X!=0)等同于if(X)
JDL

1
另外,鉴于“ I / O格式相当灵活”,使用c(x,y)而不是隐式输出可能是公平的游戏cat(x,y)
JDL

@JDL这些是我从未想过的非常有用的高尔夫技巧,非常感谢!更新了答案。
Billywob

2

JavaScript(ES6),57个字节(55–63†)

接受[x,y]数组,就地对其进行修改,然后将其返回。

c=>([x,y]=c,i=x>y|x==y&x<0,c[i^x<-y|x==-y]-=-i|!!(x|y),c)

怎么运行的

c=>(

这是单参数箭头功能,带有return简洁的主体。

[x,y]=c

参数立即被分解为xy变量。

,

逗号运算符使用最后一个的结果将多个表达式组合为一个表达式。

i=x>y|x==y&x<0

i用于区分增量和减量情况。当x大于时y,我们位于下象限或右象限,并且需要在一个维度上前进(i=1按布尔值对数字强制)。同样,当我们位于x = y对角线的负数部分时。在所有其他情况下,包括原点,都不需要增加(i=0)。

c[i^x<-y|x==-y]

我们使用某种类似的表达式来控制要调整的数组索引。当我们在左侧或底部象限递增和不(或者当我们递增和左侧或底部),然后按位XOR将产生1,我们将调整ÿ值。同样,当我们在对角x = -y对角线(包括原点)上时。在所有其他情况下,索引将是0x)。

-=-i|!!(x|y)

i为时1,我们会将其添加到指定值。当iis时0当且仅当我们不在原点时,我们将从值中减去1 。通过x|y产生非零来检测后者,并通过布尔强制将其裁剪为{0,1},并且对的求反i允许我们使用按位或而不是逻辑(因为-1没有零位,因此可以安全修改)。

c

该数组是最后一个数组,因此将被返回。

测试中

†变化

我们可以通过跳过有意义的返回值并使用输入变量来节省两个字节:

c=>([x,y]=c,i=x>y|x==y&x<0,c[i^x<-y|x==-y]-=-i|!!(x|y))

…或者我们可以跳过输入突变,使所有变量成为纯函数的局部变量,代价是六个字节:

([x,y],i=x>y|x==y&x<0,c=[x,y])=>(c[i^x<-y|x==-y]-=-i|!!(x|y),c)

1

JavaScript(ES6),80 76字节

(x,y,s=Math.max(x,y,-x,-y))=>(s?x+s?y-s?x-s?x++:y++:x--:y+s?y--:x++:0,[x,y])

1

Haskell,53个字节

0%0=(0,0)
x%y|y>=0-x,y<x=(x,y+1)|(p,q)<-(-y)%x=(q,-p)

取两个数字,输出一个元组。如果该点在东部-x<=y<x,则将第二个坐标增加1。否则,将输入点旋转90度,在其上调用该函数,然后向后旋转,从而使象限循环。


1

球拍191字节

(cond[(= 0 x y)(list x y)][(= x y)(if(> x 0)(list(sub1 x)y)(list(add1 x)y))][(> x y)(if(>= x(abs y))
(list x(add1 y))(list(add1 x)y))][(< x y)(if(> y(abs x))(list(sub1 x)y)(list x(sub1 y)))])

取消高尔夫(无需使用任何中间公式即可直接将图形方向转换为代码):

(define(f x y)
  (cond
    [(= 0 x y) (list x y)]
    [(= x y)
     (if (> x 0)
         (list (sub1 x) y)   ; left
         (list (add1 x) y))] ; right
    [(> x y)
     (if (>= x (abs y))
         (list x (add1 y))   ; up
         (list (add1 x) y))] ; right
    [(< x y)
     (if (> y (abs x))
         (list (sub1 x) y)   ; left
         (list x (sub1 y)))] ; down
    ))

测试:

(f 0  0)      
(f 1  0)     
(f 1  1)     
(f 0  1)     
(f -1  1)    
(f -1  0)    
(f -1  -1)   
(f 0  -1)    
(f 1  -1)    
(f 95  -12)  
(f 127  127) 
(f -2  101)  
(f -65  65)  
(f -127  42) 
(f -9  -9)    
(f 126  -127) 
(f 105  -105) 

输出:

'(0 0)
'(1 1)
'(0 1)
'(-1 1)
'(-1 0)
'(-1 -1)
'(0 -1)
'(1 -1)
'(1 0)
'(95 -11)
'(126 127)
'(-3 101)
'(-65 64)
'(-127 41)
'(-8 -9)
'(127 -127)
'(105 -104)

1

实际上,16个字节

这需要一个复数作为输入并输出另一个复数。欢迎打高尔夫球!在线尝试!

;`₧╦@/τuLïⁿ+0`╬X

开球

         Implicit input z.
;        Duplicate z.
`...`╬   If z is non-zero (any a+bi except 0+0j), run the following function.
           Stack: z, z
  ₧        Get phase(z).
  ╦@/      Divide phase(z) by pi.
  τuL      Push floor(2*phase(z)/pi + 1).
  ïⁿ       Push 1j ** floor(2*phase(z)/pi + 1).
  +        And add it to z. This is our rotated z.
  0        Push 0 to end the function.
X        Discard either the duplicate (0+0j) or the 0 from the end of function.
         Implicit return.

0

Scala,184个字节

val s=math.signum _
(x:Int,y:Int)=>{val m=x.abs max y.abs
if(x.abs==y.abs)if(s(x)==s(y))(x-s(x),y)else(x,y-s(y))else
if(x.abs==m)(x,y+Seq(0,x).indexOf(m))else(x-Seq(0,y).indexOf(m),y)}

取消高尔夫:

import math._

(x: Int, y: Int) => {
  val max = max(x.abs, y.abs)
  if (x.abs == y.abs)
    if (signum(x) == signum(y))
      (x - signum(x), y)
    else
      (x, y - signum(y))
  else
    if (x.abs == max)
      (x, y + Seq(0, x).indexOf(max))
    else
      (x - Seq(0, y).indexOf(max), y)
}

说明:

val s=math.signum _             //define s as an alias to math.signum
(x:Int,y:Int)=>{                //define an anonymous function
  val m=x.abs max y.abs           //calculate the maximum of the absolute values,
                                  //which is 1 for the innermost circle and so on.
  if(x.abs==y.abs)                //if we have a cell at a corner of a circle
    if(s(x)==s(y))                  //if it's at the top-left or bottom-right, we need to
                                    //modify the x value
      (x-s(x),y)                      //if x is positive (bottom-right),
                                      //we need to return (x+1,y),
                                      //(x-1,y) If it's at the top-left.
                                      //This can be simplified to (x-s(x),y)
    else                            //for top-right and bottom-left, 
      (x,y-s(y))                      //modify y in the same way.
  else                            //we don't have a corner piece
    if(x.abs==m)                    //if we're at the left or right edge of the square
      (x,y+Seq(0,x).indexOf(m))       //if it's a piece from the right edge, add one
                                      //to y, else subtract 1
    else                            //it's a piece from the top or bottm edge
      (x-Seq(0,y).indexOf(m),y)       //subtract 1 from x if it's from the top edge,
                                      //else subtract -1
}
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.