체비 쇼프 회전


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)

예를 들어 튜플을 사용하여 복소수를 출력하는 것과 같이 입력 및 출력 형식을 혼합 할 수 있습니까?
Dennis

@Dennis 예, 괜찮습니다.
Martin Ender

답변:


16

자바 스크립트 (ES6), 60 59 바이트

카레 구문으로 입력을 (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] 을 추가하여 진행 합니다.

  • 1 사분면의 이등분선을 포함하여 맨 위 삼각형의 점은 양의 합과 음이 아닌 델타 ( y-x )를 갖습니다 . 시작점에 [-1, 0] 을 추가하여 진행 합니다.

  • 2 사분면의 이등분선을 포함하여 맨 왼쪽 삼각형의 점에는 양수가 아닌 양의 델타가 있습니다. 시작점에 [0, -1] 을 추가하여 진행 합니다.

  • 3 사분면의 이등분선을 포함하여 맨 아래 삼각형의 점은 음의 합과 양수가 아닌 델타를 갖습니다. 시작점에 [1, 0] 을 추가하여 진행 합니다.

  • 4 사분면의 이등분선을 포함하여 맨 오른쪽 삼각형의 점은 음이 아닌 합과 음의 델타를 갖습니다. 시작점에 [0, 1] 을 추가하여 진행 합니다.

올바른 방향을 찾으려면 [-sign (x + y), -sign (y-x)] 를 계산하면 9 가지 가능한 결과 만 얻을 수 있습니다.

다음 표는 어떤 결과를 어떤 방향으로 매핑해야하는지 보여줍니다.

    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] = [-sign (x + y), -sign (yx)] 입니다.

  • 부호가 같고 0이 아닌 경우 [Δx, Δy] = [-sign (x + y), 0] 입니다.

  • 부호가 다르고 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

파이썬, 55 바이트

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

4 개의 대각선 사분면을 감지하고 적절한 좌표를 이동합니다.


4

하스켈, 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)

이것은 기울어 진 사분면 각각을 확인하고 그에 따라 입력을 수정하는 것입니다. 공백이 필요하다는 점에 유의하십시오. 그렇지 않으면 예를 들어 >-연산자로 정의됩니다 (정의되지 않음).

바이트를 몇 개 더 제거해 주셔서 감사합니다.


,&&첫 번째 가드 대신에 바이트를 저장합니다. 그런 다음 두 번째 비교를 -x<y다른 바이트 로 전환 할 수 있습니다 .
nimi

감사합니다, 나는 몰랐습니다 ,!
flawr

4

루비, 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. 따라서 4 사분면을 모두 통과하며 특정 사분면에있을 때 수정한다는 점을 제외하고 변경되지 않은 상태로 반환됩니다. 항상 동일한 사분면에서 수정되므로 수정이 간단 해집니다.

z오른쪽 사분면에있을 때 변경하면 따르는 것이 가장 쉬운 방법 입니다. 이 경우 우리는 y는 1 좌표 증가시켜야합니다 (즉, 추가 iz.)

우리는 확인 x.abs>=y.abs의 제곱을 비교 x하고 y. 이것은 포인트가 상단 또는 하단이 아니라 오른쪽 또는 왼쪽 사분면에 있음을 나타냅니다. 실제로는 오른쪽 사분면에서이를 확인하기 위해 추가로 확인합니다 x>y( x=y"상단"사분면에 속하는 경우를 제외하기 위해 엄청나게 더 큼 ).이 경우에 추가 i합니다 z.

골프를 이유로 추가 i하는 것은 바람직하지 않습니다. 대신, 우리는 그것이 아래 사분면에있을 때 숫자를 수정합니다 .이 경우 x좌표 에 1을 더해야 합니다 (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 2016 년

@ 마틴 설명이 추가되었습니다. 이것은 흥미로운 접근법 이었지만 처음 움직일 때 사분면이 변하는 점의 이중 이동을 억제해야했기 때문에 내가 바라는 것만 큼 우아하지는 않았습니다.
Level River St

4

파이썬, 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도 회전시킵니다. 입력이 0이면 특별히 출력 자체를 처리합니다.

복소수의 다른 시도 :

## 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]

이것은 단항 연산자 ±를 정의합니다.이 연산자 는 구성 요소가 x및을 나타내는 복소수를 가져오고 반환합니다 y.

Lynn이 복잡한 숫자 솔루션을 공개하고 Dennis가 내 점수를 이겼으므로 골프 참조 구현을 게시하는 것이 그렇게 나쁘지 않습니다. :) (Lynn의 대답과 거의 동일합니다.)


도움이 되겠습니까? ± 0 = 0 ± z_ : = z + I ^ ⌊ 2 Arg @ z / Pi + 3/2 ⌋ (아마도 괄호에 다른 문자가있을 수 있음)
DavidC

불행히도 @DavidC는 UTF-8 인코딩을 사용해야하며 ±는 각각 2 바이트가 필요하기 때문에 아닙니다.
Martin Ender

7이 아닌 4 바이트가 아니므로 3 바이트의 경제를 제공합니까?
DavidC

@DavidC 아니요, 바닥 괄호는 각각 3 바이트입니다.
Martin Ender

나는 그것을 몰랐다. 그러나 그럼에도 불구하고 여전히 1 바이트를 절약해야합니다.
DavidC

3

MATL , 19 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

루비, 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)

는 IS d할당의 가치는? 그냥 비교할 수있을 것 같습니다 x*x>y*y.
xnor

@Xnor 불행하게도 루비 사이의 공간이 필요 y*y하고 ?그래서 정확히 같은 길이입니다. 나는 당신의 방법이 어떤면에서 더 깔끔하다고 생각할 때 그것을 포함 시켰습니다. 루비가 y?합법적 인 함수 이름 으로 전달하려고 생각 합니다.
Level River St

3

줄리아, 38 34 바이트

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

Dennis는 4 바이트를 절약했습니다. 감사!

온라인으로 사용해보십시오!


내가 혼합과 같은 지능 의 (나의 방어에서, 줄리아의 다른 버전에서 동작이 정말 일치). Julia 0.4 (TIO의 버전)는 반으로 반올림하므로 그대로 작동하지 않습니다. Julia 0.3에서는 int(2angle(z)/pi+5)동일한 바이트 수로 사용할 수 있습니다 (음의 거듭 제곱은 어떤 이유로 든 오류를 발생시킵니다).
Dennis

또한 !z=z+(z!=0)im^...모든 버전에서 바이트를 저장할 수 있습니다 .
Dennis

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)is 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

자바 스크립트 (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우리는 조정한다 Y 값. 우리가 나누는 x = -y 대각선 (원점 포함) 에있을 때와 마찬가지로 . 다른 모든 경우 인덱스는 0( x )입니다.

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

i이다 1, 우리는 지정된 값에 추가합니다. 때 i이다 0, 우리는 값에서 1을 빼는 것입니다 및 경우에만 경우 우리가 원점이 아니다. 후자는 x|y0이 아닌 값 을 생성하여 부울 강제에 의해 {0, 1}로 클리핑되어 감지되며 , 부정 i은 논리 대신 비트 OR을 사용할 수있게합니다 ( -10 비트가 없으므로 수정이 안전합니다).

c

배열이 마지막이므로 반환됩니다.

테스팅

† 변형

의미있는 리턴 값을 건너 뛰고 입력 돌연변이 사용하여 2 바이트를 더 절약 할 수 있습니다 .

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

또는 입력 돌연변이를 건너 뛰고 6 바이트의 비용으로 모든 함수를 순수 함수에 대해 로컬로 만들 수 있습니다.

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

1

자바 스크립트 (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

하스켈, 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)))])

Ungolfed (중간 공식을 사용하지 않고 그림 방향을 코드로 직접 변환) :

(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

스칼라, 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
}
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.