Ch Quashev Xoay


36

Hãy xem xét một lưới thông thường, trong đó mỗi ô có tọa độ nguyên. Chúng ta có thể nhóm các ô thành các "vòng" hình vuông, trong đó các ô trong mỗi vòng có cùng khoảng cách Ch Quashev (hoặc khoảng cách bàn cờ) từ gốc. Nhiệm vụ của bạn là lấy tọa độ ô như vậy và xoay ô đó theo một vị trí ngược chiều kim đồng hồ trong vòng của nó. Điều này thực hiện ánh xạ sau:

nhập mô tả hình ảnh ở đây

Vì vậy, ví dụ nếu đầu vào là (3, -2)bạn nên đầu ra (3, -1). Lưu ý rằng đó (0, 0)là đầu vào duy nhất nên ánh xạ tới chính nó.

Quy tắc

Định dạng I / O khá linh hoạt. Bạn có thể sử dụng hai số riêng lẻ, một cặp / danh sách / mảng / bộ số, một số phức duy nhất, một chuỗi chứa hai số, v.v.

Bạn có thể cho rằng -128 < x,y < 128.

Bạn có thể viết chương trình hoặc chức năng và sử dụng bất kỳ phương pháp tiêu chuẩn nào để nhận đầu vào và cung cấp đầu ra.

Bạn có thể sử dụng bất kỳ ngôn ngữ lập trình nào , nhưng lưu ý rằng các lỗ hổng này bị cấm theo mặc định.

Đây là , vì vậy câu trả lời hợp lệ ngắn nhất - được đo bằng byte - thắng.

Các trường hợp thử nghiệm

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

Chúng ta có thể trộn định dạng đầu vào và đầu ra, ví dụ, lấy một tuple và xuất một số phức?
Dennis

@Dennis vâng, điều đó tốt.
Martin Ender

Câu trả lời:


16

JavaScript (ES6), 60 59 byte

Đưa đầu vào với cú pháp currying (x)(y)và trả về một mảng [new_x, new_y].

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

Làm thế nào nó hoạt động

Nhiệm vụ chính của chúng tôi là xác định góc phần tư của chúng tôi, để chúng tôi biết nên di chuyển theo hướng nào.

Chúng ta có thể sử dụng công thức này như một xấp xỉ đầu tiên:

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

Đây là những gì chúng ta nhận được:

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

Gần đến rồi. Nhưng góc dưới bên trái và dưới cùng bên phải của các vòng không hợp lệ. Chúng ta cần dịch chuyển nửa dưới của ma trận theo một vị trí sang trái, vì vậy chúng ta xác định zlà:

z = y < 0 ? x + 1 : x

Và chúng tôi thay thế xbằng ztrong công thức của chúng tôi:

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

Điều này dẫn đến:

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 

Toàn bộ ma trận bây giờ là chính xác, ngoại trừ trường hợp đặc biệt [0, 0](không di chuyển chút nào) phải được giải quyết riêng.

Các trường hợp thử nghiệm


13

Thạch , 20 14 12 byte

S;IṠN0n/¦Ạ¡+

Đầu vào và đầu ra ở dạng mảng. Hãy thử trực tuyến! hoặc xác minh tất cả các trường hợp thử nghiệm .

Lý lịch

Để tìm ra hướng nào chúng ta phải di chuyển, chúng ta có thể quan sát vị trí tương đối của điểm bắt đầu với đường phân giác góc phần tư x + y = 0 (màu xanh) và x - y = 0 (màu đỏ).

sơ đồ

  • Nguồn gốc là cố định. Chúng tôi tiến lên bằng cách thêm [0, 0] vào điểm bắt đầu.

  • Các điểm trong tam giác trên cùng - bao gồm đường phân giác của góc phần tư thứ nhất - có tổng dương và delta không âm ( y - x ). Chúng tôi tiến lên bằng cách thêm [-1, 0] vào điểm bắt đầu.

  • Các điểm trong tam giác ngoài cùng bên trái - bao gồm đường phân giác của góc phần tư thứ hai - có tổng không dương và delta dương. Chúng tôi tiến lên bằng cách thêm [0, -1] vào điểm bắt đầu.

  • Các điểm trong tam giác đáy - bao gồm đường phân giác của góc phần tư thứ ba - có tổng âm và đồng bằng không dương. Chúng tôi tiến lên bằng cách thêm [1, 0] vào điểm bắt đầu.

  • Các điểm trong tam giác ngoài cùng bên phải - bao gồm đường phân giác của góc phần tư thứ tư - có tổng không âm và delta âm. Chúng tôi tiến lên bằng cách thêm [0, 1] vào điểm bắt đầu.

Để tìm ra hướng chính xác, chúng tôi tính toán [-sign (x + y), -sign (y - x)] , chỉ có chín kết quả có thể xảy ra.

Bảng sau đây minh họa kết quả nào phải được ánh xạ tới hướng nào.

    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

Điều này để lại ba trường hợp.

  • Nếu ít nhất một trong các dấu hiệu là 0 , [x, y] = [-sign (x + y), -sign (yx)] .

  • Nếu các dấu bằng nhau và khác không, [x, y] = [-sign (x + y), 0] .

  • Nếu các dấu hiệu khác nhau và khác không, [x, y] = [0, -sign (yx)] .

Làm thế nào nó hoạt động

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 byte

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

Phát hiện bốn góc phần tư chéo và dịch chuyển tọa độ thích hợp.


4

Haskell, 77 71 69 byte

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)

Đây chỉ là kiểm tra từng góc phần tư nghiêng và sửa đổi đầu vào cho phù hợp. Lưu ý rằng các không gian là cần thiết, nếu không, ví dụ>- sẽ được hiểu là một toán tử (không được xác định).

Cảm ơn bạn @nimi vì đã xóa thêm một vài byte!


,thay vì&& trong bảo vệ đầu tiên tiết kiệm một byte. Và sau đó bạn có thể chuyển đổi so sánh thứ hai sang -x<ymột byte khác.
nimi

Cảm ơn bạn, tôi đã không nhận thức được ,!
flawr

4

Hồng ngọc, 68

Hàm Lambda lấy số phức làm đối số, trả về số phức.

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

Chúng tôi xoay điểm qua 90 độ 4 lần bằng cách nhân với i . Do đó, nó đi qua tất cả 4 góc phần tư và sẽ được trả lại không thay đổi - ngoại trừ thực tế chúng ta sửa đổi nó khi nó nằm trong một trong số chúng cụ thể. Thực tế nó luôn được sửa đổi trong cùng một góc phần tư đơn giản hóa việc sửa đổi.

Dễ dàng nhất để làm theo nếu chúng ta thay đổi nó zkhi nó nằm trong góc phần tư bên phải. trong trường hợp này, chúng ta cần tăng tọa độ y lên 1 (tức là thêm ivào z.)

Chúng tôi kiểm tra x.abs>=y.absbằng cách so sánh các hình vuông của xy. Điều này cho chúng ta biết điểm nằm ở góc phần tư bên phải hoặc bên trái, không phải trên cùng hoặc dưới cùng. Để kiểm tra xem thực tế là trong góc phần tư tay phải, chúng tôi kiểm tra thêm x>y(hoàn toàn lớn hơn vì chúng tôi muốn loại trừ trường hợp x=ythuộc góc phần tư "trên cùng".) Đây là điều đúng mà chúng tôi thêm ivào z.

Đối với lý do chơi golf, thêm ilà không mong muốn. Thay vào đó, chúng tôi sửa đổi số khi nó nằm trong góc phần tư dưới cùng, trong trường hợp đó chúng ta phải thêm 1 vào xtọa độ (thêm 1 vào z.) Trong trường hợp này, chúng tôi kiểm y*y>=x*xtra xem nó có nằm trong góc phần tư trên hay dưới không. Để đảm bảo hơn nữa nó nằm trong góc phần tư phía dưới, chúng ta cần kiểm tra y<-x(không bao gồm nghiêm ngặt trường hợp góc dưới cùng bên phải y=-x.)

Một lợi thế của kiểm tra này là không có trường hợp đặc biệt nào cho tọa độ 0,0. Thật không may, người ta đã phát hiện ra rằng việc di chuyển điểm có thể chuyển nó sang một góc phần tư khác và điều này có nghĩa là một chuyển động thứ hai phải bị triệt tiêu nếu góc phần tư đó được kiểm tra lại, điều này có thể phủ nhận lợi thế.

ví dụ 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.

Ví dụ 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.

Trong chương trình thử nghiệm

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)

Sơ đồ

Hình ảnh sau đây cho thấy (màu xanh) khu vực trong đó x*x>=y*y, (màu vàng) khu vực nơi y<-xvà (màu xanh lá cây) giao điểm của những khu vực này, là khu vực nơi chuyển đổi chính xác là thêm 1 vào z.

nhập mô tả hình ảnh ở đây


1
Xin lỗi, tôi không làm theo lời giải thích. Bạn có phiền khi thêm một ví dụ hoặc sơ đồ?
Martin Ender

@Martin giải thích thêm. Đây là một cách tiếp cận thú vị nhưng do nhu cầu triệt tiêu chuyển động gấp đôi của các điểm thay đổi góc phần tư ngay lần đầu tiên chúng di chuyển, nó đã không trở nên thanh lịch như tôi mong đợi.
Cấp sông St

4

Python, 52 byte

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

Đầu vào và đầu ra phức tạp. Để kiểm tra điểm nằm trong góc phần tư đường chéo dưới, trước tiên hãy xoay nó 135 theo chiều ngược chiều kim đồng hồ để di chuyển góc phần tư đó sang góc phần tư chuẩn (x> 0, y> 0) và kiểm tra xem kết quả không có ký hiệu trừ trong biểu diễn chuỗi. Trừ đi 1 trước tiên sẽ quan tâm đến điều kiện biên.

Nếu nó không nằm trong góc phần tư đó, xoay toàn bộ vấn đề 90 độ. Đầu vào bằng không được xử lý đặc biệt để đầu ra chính nó.

Các nỗ lực khác với số phức:

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

Toán học, 34 byte

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

Điều này định nghĩa một toán tử đơn nguyên ±lấy và trả về một số phức có các thành phần đại diện xy.

Bây giờ Lynn đã tiết lộ giải pháp số phức và Dennis đã đánh bại điểm số của tôi, tôi không cảm thấy quá tệ khi đăng bài thực hiện tham chiếu golf của mình. :) (Hóa ra nó gần như giống hệt với câu trả lời của Lynn.)


Điều này sẽ giúp? ± 0 = 0 ± z_: = z + I ^ ⌊ 2 Arg @ z / Pi + 3/2 (có lẽ với một char khác cho dấu ngoặc sàn)
DavidC

Rất tiếc, @DavidC không phải vì sau đó tôi phải sử dụng mã hóa UTF-8 và sau đó, giá trị ± sẽ tốn 2 byte mỗi lần.
Martin Ender

Sẽ không phải là 4 byte thay vì 7, do đó mang lại nền kinh tế 3 byte?
DavidC

@DavidC không, dấu ngoặc sàn sẽ là 3 byte mỗi.
Martin Ender

Tôi đã không nhận thức được điều đó. Nhưng, ngay cả như vậy, bạn vẫn nên tiết kiệm 1 byte.
DavidC

3

MATL , 19 17 byte

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

Điều này sử dụng số phức làm đầu vào và đầu ra.

Hãy thử trực tuyến! Hoặc xác minh tất cả các trường hợp thử nghiệm .

Giải trình

Hãy lấy đầu vào -127+42jlàm ví dụ.

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 byte

Mẫu ban đầu

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

Hình thức thay thế cho mỗi nhận xét của Xnor

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

Sử dụng cùng một loại bất đẳng thức như câu trả lời khác của tôi, nhưng theo một cách khác.

Trong chương trình thử nghiệm

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)

Là sự dphân công xứng đáng? Có vẻ như bạn chỉ có thể so sánh x*x>y*y.
xnor

@Xnor không may là Ruby yêu cầu một khoảng cách giữa y*y?do đó, nó có cùng độ dài. Tôi đã bao gồm nó vì tôi nghĩ rằng cách của bạn là một cách gọn gàng hơn. Tôi nghĩ rằng Ruby đang cố gắng vượt qua nó vì y?đó sẽ là một tên chức năng hợp pháp.
Cấp sông St

3

Julia, 38 34 byte

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

Dennis đã lưu bốn byte. Cảm ơn!

Hãy thử trực tuyến!


Có vẻ như tôi đã trộn lẫn hành vi của int trên các phiên bản khác nhau của Julia (mà theo tôi, là không phù hợp khủng khiếp ). Julia 0.4 (phiên bản trên TIO) làm tròn một nửa về phía chẵn, vì vậy điều này sẽ không hoạt động như hiện tại. Trong Julia 0.3, bạn có thể sử dụng int(2angle(z)/pi+5)cho cùng một số byte (quyền hạn âm gây ra lỗi vì bất kỳ lý do gì).
Dennis

Ngoài ra, bạn có thể lưu một byte với !z=z+(z!=0)im^...tất cả các phiên bản.
Dennis

2

C ++, 94 byte

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

Ung dung:

#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

Sử dụng:

#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;
}

Dùng thử trực tuyến


Tôi khá chắc chắn rằng (x>0?x:-(x))có thể (x>0?x:-x).
Yytsi

Thật không may là không, vì mã thông báo x sẽ được thay thế bằng ví dụ x + .5 sẽ chỉ nhận được -x + .5.
Anedar

Ổn thỏa. Tôi đã có một suy nghĩ trong đó phủ định không có dấu ngoặc đơn lật dấu hiệu: D
Yytsi

Nói đúng ra, bạn đã sử dụng bộ tiền xử lý C (được thừa nhận là một phần của C ++, nhưng cũng được chia sẻ với các biến thể và hậu duệ C khác)
tuc lửa

2

R, 131 110 byte

Một hàm lấy hai số nguyên x,ylàm đầu vào và ghi đầu ra vào thiết bị xuất chuẩn. Giải pháp tuân theo sơ đồ dòng kiểm soát của @Dennis nhưng có lẽ có thể bị đánh gôn.

EDIT: Mã được cập nhật dựa trên đề xuất của @ JDL và lưu một loạt byte.

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

Ung dung

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
Tôi nghĩ rằng một số điều kiện logic có thể được rút ngắn: as.logical(-1)TRUE, vì vậy X==0|Y==0có thể trở thành !X|!Y, và điều kiện if(X!=Y...)có thể trở thành if(X-Y). Ngoài ra, nếu X==YX!=0sau đó Y!=0là dư thừa. Trên thực tế, tất cả các !=0phần là dư thừa; if(X!=0)tương đương với if(X).
JDL

1
Ngoài ra, do "định dạng I / O khá linh hoạt", đây có thể là trò chơi công bằng để đầu ra hoàn toàn c(x,y)thay vì cat(x,y).
JDL

@JDL Đó là một số mẹo chơi golf rất hữu ích mà tôi chưa bao giờ nghĩ tới, cảm ơn rất nhiều! Cập nhật câu trả lời.
Billywob

2

JavaScript (ES6), 57 byte (55 Bếp63 †)

Chấp nhận một mảng [x, y], sửa đổi nó tại chỗ và trả về nó.

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

Làm thế nào nó hoạt động

c=>(

Đây là một hàm mũi tên tham số đơn với returnthân ngắn gọn tự do.

[x,y]=c

Tham số ngay lập tức bị phá hủy vào xycác biến.

,

Toán tử dấu phẩy kết hợp nhiều biểu thức thành một, sử dụng kết quả cuối cùng.

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

iđược sử dụng để phân biệt các trường hợp tăng và giảm. Khi xlớn hơn y, chúng ta ở góc phần tư phía dưới hoặc bên phải và cần tiến lên theo một chiều ( i=1bằng cách ép boolean-to-number). Tương tự như vậy khi chúng ta ở phần âm của đường chéo chia x = y . Trong tất cả các trường hợp khác, bao gồm cả nguồn gốc, không bắt buộc phải tăng ( i=0).

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

Chúng tôi sử dụng một biểu thức hơi giống nhau để kiểm soát chỉ số mảng nào cần điều chỉnh. Khi chúng ta tăng và không ở góc phần tư bên trái hoặc bên dưới (hoặc khi chúng ta không tăng và bên trái hoặc bên dưới), thì XOR bitwise sẽ tạo ra 1và chúng ta sẽ điều chỉnh giá trị y . Tương tự như vậy khi chúng ta ở trên đường chéo chia x = -y (bao gồm cả gốc). Trong tất cả các trường hợp khác, chỉ số sẽ là 0( x ).

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

Khi i1, chúng tôi sẽ thêm nó vào giá trị được chỉ định. Khi i0, chúng tôi sẽ trừ đi 1 từ giá trị khi và chỉ khi chúng ta không tại gốc. Cái sau được phát hiện bằng cách x|ytạo ra nonzero, được cắt thành {0, 1} bằng cách ép boolean và phủ định icho phép chúng ta sử dụng bitwise OR thay vì logic (vì -1không có bit nào, nên nó không bị thay đổi).

c

Mảng là cuối cùng, vì vậy nó sẽ được trả lại.

Kiểm tra

Biến thể

Chúng ta có thể lưu thêm hai byte bằng cách bỏ qua một giá trị trả về có ý nghĩa và chỉ sử dụng đột biến đầu vào:

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

Hoặc hoặc chúng ta có thể bỏ qua đột biến đầu vào và biến tất cả các biến cục bộ thành một hàm thuần túy, với chi phí là sáu byte:

([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 byte

(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 byte

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

Mất hai số, xuất ra một tuple. Nếu điểm nằm ở phần phía đông -x<=y<x, hãy tăng tọa độ thứ hai thêm 1. Nếu không, hãy xoay các góc phần tư bằng cách xoay điểm đầu vào 90 độ, gọi hàm trên đó, sau đó quay lại.


1

Vợt 191 byte

(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 (dịch trực tiếp các hướng hình thành mã mà không sử dụng bất kỳ công thức trung gian nào):

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

Kiểm tra:

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

Đầu ra:

'(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

Thực ra , 16 byte

Điều này có một số phức làm đầu vào và đầu ra một số phức khác. Gợi ý chơi golf chào mừng! Hãy thử trực tuyến!

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

Ungolfing

         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 byte

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

Ung dung:

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

Giải trình:

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
}
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.