Real Ch Quashev Rotation


15

Đây là một thử thách lấy cảm hứng từ Ch Quashev Rotation . Tôi đề nghị nhìn vào câu trả lời ở đó để lấy cảm hứng cho thử thách này.

Cho một điểm trên mặt phẳng có một hình vuông duy nhất (một hình chữ nhật có các cạnh bằng nhau) được căn giữa gốc tọa độ và giao với điểm đó ( bản demo tương tác ):

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

Cho một điểm p và một khoảng cách d , trả về điểm thu được bằng cách di chuyển khoảng cách d từ p , ngược chiều kim đồng hồ (và theo chiều kim đồng hồ cho âm d ), dọc theo chu vi của hình vuông chính giữa gốc tọa độ p . Câu trả lời của bạn phải chính xác đến ít nhất 4 chữ số thập phân.

Testcase:

(0, 0), 100 -> (0, 0)
(1, 1), 81.42 -> (-0.4200, 1.0000)
(42.234, 234.12), 2303.34 -> (-234.1200, 80.0940)
(-23, -39.234), -234.3 -> (39.2340, -21.8960)

Các trường hợp thử nghiệm sau đây là từ thử thách ban đầu của Martin Ender và tất cả đều có d = 1 :

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

Không phải hầu hết tất cả những điều này chỉ được thay đổi một chút so với các thách thức khác sao? Điều này có vẻ như một bổ sung không cần thiết.
ATaco

1
@ATaco Không, nó phức tạp hơn một chút.
orlp

Khoảng cách nên được tính dọc theo chu vi bắt đầu từ p?
Gábor Fekete

@ GáborFekete Còn gì nữa không?
orlp

Vâng tôi hiểu, các trường hợp thử nghiệm ngụ ý điều này nhưng nó không được nêu rõ ràng. Lúc đầu tôi nghĩ rằng nó sẽ bắt đầu tại giao điểm dương ở trục x.
Gábor Fekete

Câu trả lời:


4

Python 2, 363 335 296 266 262 258 256 233 Bytes

Woo, mất 130 byte! Cảm ơn Neil vì đã lưu 4 byte, Nathan Merrill đã lưu 2 byte và xnor vì đã tiết kiệm được 23 byte vô lý!

Ý tưởng chung là thế này: Chúng ta có thể giảm quãng đường di chuyển bằng cách lấy mô đun của nó so với chu vi của hình vuông. Chu vi được xác định là 8 lần lớn nhất trong hai tọa độ, vì điểm phải nằm trên nó. Sau đó, sau khi mô đun được thực hiện, chúng tôi được đảm bảo không có sự chồng chéo. Nó cũng đảm bảo chúng ta chỉ phải di chuyển ngược chiều kim đồng hồ, vì mô-đun cho kết quả khả quan.

Từ đó, tôi chỉ cần sử dụng những gì chúng ta biết từ tọa độ x và y đã cho để tìm ra vị trí của chúng ta: trên, dưới, trái, phải hoặc trong một góc và xác định hướng, có thể là một trong 0, 1, 2, 3:

0 --> we are on the 'top', moving 'left'
1 --> we are on the 'left', moving 'down'
2 --> we are on the 'bottom', moving 'right'
3 --> we are on the 'right', moving 'up'

Sau này, nó đơn giản như vòng lặp trong khi chúng ta vẫn có khoảng cách để di chuyển, và dựa trên hướng chúng ta trừ hoặc thêm vào tọa độ thích hợp, và cho biết vòng lặp chúng ta sẽ đi theo hướng nào.

p,d=input()
x,y=p
s=max(x,y,-x,-y)
d=d%(s*8or 1)
r=[(y<s)*[2,[3,x>-s][x<s]][y>-s],[2*(y<0),3*(y<=0)][x>0]][y*y==x*x]
while s>0<d:f=1-2*(r<2);m=abs(f*s-p[r%2]);j=d>m;p[r%2]=[p[r%2]+f*d,f*s][j];r=-~r%4;d=(d-m)*j
print"%.4f "*2%tuple(p)

Trong khi khá dài, nó chắc chắn hoạt động. Dưới đây là một số ví dụ I / O:

[0, 0], 100 --> 0.0000 0.0000
[1, 1], 81.42 --> -0.4200 1.0000
[42.234, 234.12], 2303.34 --> -234.1200 80.0940
[-23, -39.234], -234.3 --> 39.2340 -21.8960

Hãy thử trực tuyến hoặc chạy thử trường hợp .


s=max(x,y,-x,-y)hoạt động không?
Neil

@Neil Nó, cảm ơn rất nhiều!
Kade

(s>0)*(d>0)s>0<d. Đầu ra có thể "%.4f "*2%tuple(p). if s:d=d%(8*s)có thể d%(s*8or 1). (r+1)có thể ~-r. 1*(x>-s)chỉ có thể được (x>-s). abs(y)==abs(x)có thểy*y==x*x
xnor

@xnor Wow, cảm ơn! Chỉ những điều tôi đã thay đổi là (x>-s)không cần dấu ngoặc đơn và ~-rgiảm dần, vì vậy tôi đã sử dụng -~r.
Kade

3

JavaScript (ES6), 147 byte

f=(x,y,d,s=Math.max(x,y,-x,-y),c=(d/8%s+s)%s*8,v=0,w=x+y>0?1:-1,b=(v?x:y)*w+c-s)=>c?b>0?f(v?s*w:x,v?y:s*w,d,s,b,!v,v?w:-w):[x+c*w*v,y+c*w*!v]:[x,y]

Giải thích: Hoạt động bằng cách cố gắng thêm vectơ chỉ hướng trong khi giữ trong giới hạn của hình vuông. Bất kỳ phần vượt quá nào cũng được đệ quy trở lại với hướng quay ngược chiều kim đồng hồ 90 độ. Hướng thực sự được mã hóa bằng cờ dọc vvà đơn vị wsao cho các vectơ (1, 0), (0, 1), (-1, 0) và (0, -1) được mã hóa với v0, 1, 0 , 1 và w1, 1, -1, -1 tương ứng. Vectơ chỉ hướng ban đầu có thể không chỉ theo một hướng phù hợp nhưng nó không bao giờ chỉ lùi về phía sau nên cuối cùng nó sẽ xoay thành một hướng có thể sử dụng được.

f=(x,y,d,                   Input parameters
 s=Math.max(x,y,-x,-y),     Calculate half the side of the square
 c=(d/8%s+s)%s*8,           Reduce the distance modulo the perimeter
 v=0,                       Initial vertical flag
 w=x+y>0?1:-1,              Initial direction
 b=(v?x:y)*w+c-s)=>         Will we overshoot the corner?
  c?b>0?f(v?s*w:x,v?y:s*w,  Advance to the next corner
          d,s,b,!v,v?w:-w): Rotate the direction
        [x+c*w*v,y+c*w*!v]: Advance the remaining amout
    [x,y]                   Nothing to do, zero input

Điều này có thể là do trình duyệt của tôi (Opera 40.0.2308.81), nhưng có vẻ như nó có một chút lỗi làm tròn f(42.234, 234.12, 2303.34) -> [-234.12, 80.09399999999988]có nghĩa là nó không có độ chính xác 4 chữ số. Có lẽ thêm một số định dạng đầu ra sẽ khắc phục điều này? Câu trả lời tốt đẹp mặc dù! :)
Kade

@Shebang Định dạng đầu ra về mặt kỹ thuật sẽ yêu cầu làm tròn, và do đó gây ra lỗi làm tròn tiềm năng. Các số được tạo là gần nhất có thể trong giới hạn của số học dấu phẩy động, không nên dự kiến ​​sẽ cho kết quả chính xác cho các biểu diễn thập phân tùy ý. Bám sát phân số nhị phân nếu bạn muốn câu trả lời chính xác.
Neil
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.