Hiệp sĩ khoảng cách


24

Trong Cờ vua, một Hiệp sĩ trên lưới (x, y) có thể di chuyển đến (x-2, y-1), (x-2, y + 1), (x-1, y-2), (x-1, y + 2), (x + 1, y-2), (x + 1, y + 2), (x + 2, y-1), (x + 2, y + 1) trong một bước. Hãy tưởng tượng một bàn cờ vô hạn chỉ có một Hiệp sĩ trên (0, 0):

Có bao nhiêu bước cần thiết để di chuyển một Hiệp sĩ từ (0, 0) đến (t x , t y )?

Đầu vào

Hai số nguyên: t x , t y ;

-100 <t x <100, -100 <t y <100

Đầu ra

Các bước tối thiểu cần thiết để di chuyển một Hiệp sĩ từ (0, 0) đến (t x , t y ).

Quy tắc

  • mã golf

Tủ thử

  x    y -> out
  0,   0 ->  0
  0,   1 ->  3
  0,   2 ->  2
  1,   1 ->  2
  1,   2 ->  1
  3,   3 ->  2
  4,   0 ->  2
 42,  22 -> 22
 84,  73 -> 53
 45,  66 -> 37
 99,  99 -> 66
-45, -91 -> 46
-81,   1 -> 42
 11,  -2 ->  7

document.write('<div>');[..."EFEDEDCDCBCBCBCBCBCBCBCBCBCBCBCBCBCDCDEDEFE;FEDEDCDCBCBABABABABABABABABABABABCBCDCDEDEF;EDEDCDCBCBABABABABABABABABABABABABCBCDCDEDE;DEDCDCBCBABA9A9A9A9A9A9A9A9A9A9ABABCBCDCDED;EDCDCBCBABA9A9A9A9A9A9A9A9A9A9A9ABABCBCDCDE;DCDCBCBABA9A9898989898989898989A9ABABCBCDCD;CDCBCBABA9A989898989898989898989A9ABABCBCDC;DCBCBABA9A98987878787878787878989A9ABABCBCD;CBCBABA9A9898787878787878787878989A9ABABCBC;BCBABA9A989878767676767676767878989A9ABABCB;CBABA9A98987876767676767676767878989A9ABABC;BABA9A9898787676565656565656767878989A9ABAB;CBA9A989878767656565656565656767878989A9ABC;BABA98987876765654545454545656767878989ABAB;CBA9A987876765654545454545456567678789A9ABC;BABA98987676565454343434345456567678989ABAB;CBA9A987876565454343434343454565678789A9ABC;BABA98987676545434323232343454567678989ABAB;CBA9A987876565434323232323434565678789A9ABC;BABA98987676545432341214323454567678989ABAB;CBA9A987876565434321232123434565678789A9ABC;BABA98987676545432323032323454567678989ABAB;CBA9A987876565434321232123434565678789A9ABC;BABA98987676545432341214323454567678989ABAB;CBA9A987876565434323232323434565678789A9ABC;BABA98987676545434323232343454567678989ABAB;CBA9A987876565454343434343454565678789A9ABC;BABA98987676565454343434345456567678989ABAB;CBA9A987876765654545454545456567678789A9ABC;BABA98987876765654545454545656767878989ABAB;CBA9A989878767656565656565656767878989A9ABC;BABA9A9898787676565656565656767878989A9ABAB;CBABA9A98987876767676767676767878989A9ABABC;BCBABA9A989878767676767676767878989A9ABABCB;CBCBABA9A9898787878787878787878989A9ABABCBC;DCBCBABA9A98987878787878787878989A9ABABCBCD;CDCBCBABA9A989898989898989898989A9ABABCBCDC;DCDCBCBABA9A9898989898989898989A9ABABCBCDCD;EDCDCBCBABA9A9A9A9A9A9A9A9A9A9A9ABABCBCDCDE;DEDCDCBCBABA9A9A9A9A9A9A9A9A9A9ABABCBCDCDED;EDEDCDCBCBABABABABABABABABABABABABCBCDCDEDE;FEDEDCDCBCBABABABABABABABABABABABCBCDCDEDEF;EFEDEDCDCBCBCBCBCBCBCBCBCBCBCBCBCBCDCDEDEFE"].forEach(c=>document.write(c==';'?'<br>':`<span class="d-${c}">${c}</span>`));
document.write('<style>body{line-height:16px;color:rgba(255,255,255,0.2);}span{display:inline-block;width:16px;font-size:16px;text-align:center;}div{white-space:pre;}');[...'0123456789ABCDEF'].map((c,i)=>document.write(`.d-${c}{background:hsl(${60-4*i},80%,${65-2*i}%)}`));

Liên quan đến OEIS

Dưới đây là một số OEIS để đọc thêm

  • A018837 : Số bước để hiệp sĩ đạt (n, 0) trên bàn cờ vô hạn.
  • A018838 : Số bước để hiệp sĩ đạt (n, n) trên bàn cờ vô hạn.
  • A065775 : Mảng T được đọc theo đường chéo: T (i, j) = số lần di chuyển hiệp sĩ ít nhất trên bàn cờ (vô hạn theo mọi hướng) cần thiết để chuyển từ (0,0) sang (i, j).
  • A183041 : Số lần di chuyển của hiệp sĩ ít nhất từ ​​(0,0) đến (n, 1) trên bàn cờ vô hạn.

Bạn có thể tham khảo công thức được đưa ra trong oeis.org/A065775
tsh

2
Tôi có thể lấy đầu vào là một số phức x+yikhông?
Lynn

1
@lynn tôi nghĩ là chấp nhận được
tsh

@ user202729 đã cập nhật đoạn mã để hiển thị kết quả.
tsh

Một bản đồ rất tốt.
Willtech

Câu trả lời:


11

Ngôn ngữ Wolfram (Mathicala) , 64 byte

Sử dụng tích hợp KnightTourGraph.

Đã lưu 2 byte nhờ Mathe172 .

GraphDistance[KnightTourGraph@@({x,y}=Abs@{##}+4),y+2,(x-2)y-2]&

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

ArrayPlot @ Array [GraphDistance [KnightTourGraph @@ ({x, y} = abs @ {##} + 5), 2y + 3, (x-2) y-2] &, {65,65}, - 32]


14
Các nhà xây dựng toán học tấn công một lần nữa
qwr

1
Hơi ngắn hơn một chút:GraphDistance[KnightTourGraph@@({x,y}=Abs@{##}+5),2y+3,(x-2)y-2]&
Lukas Lang

Ngôn ngữ này là gì? Làm thế nào đến tất cả các tích hợp này được tải sẵn? Có phải cố gắng để hoàn thành một cụm từ với tab mất nhiều thời gian?
OganM

@OganM Mathematica không hỗ trợ hoàn thành tự động trong giao diện dòng lệnh của nó. Việc hoàn thành tự động trong giao diện máy tính xách tay trông như thế này .
alephalpha

1
@OganM Có thể các nhà phát triển sử dụng Trie (cấu trúc dữ liệu) hoặc chỉ tìm kiếm nhị phân trong danh sách các phần dựng sẵn được sắp xếp. Có, tại sao tìm kiếm tuyến tính? | Lưu ý rằng Mathematica là ngôn ngữ nguồn đóng không miễn phí, vì vậy không ai biết công cụ dự đoán thực sự hoạt động như thế nào. | Lập trình viên thực sự không cần tự động hoàn thành. : P
user202729

7

JavaScript (ES6), 90 75 72 byte

Lấy cảm hứng từ công thức được đưa ra cho A065775 . Chậm như địa ngục cho (không phải) khoảng cách dài.

f=(x,y,z=x|y)=>z<0?f(-y,x):z>1?1+Math.min(f(x-1,y-2),f(x-2,y-1)):z*3^x&y

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

Làm sao?

Chúng tôi định nghĩa z là bit OR OR giữa xy .

Bước 1

Trước tiên, chúng tôi đảm bảo rằng chúng tôi được đặt trong một góc phần tư cụ thể bằng cách buộc cả xy không âm. Miễn là z <0 (có nghĩa là x hoặc y là âm), chúng tôi xử lý lệnh gọi đệ quy f (-y, x) :

(+1, -2) --> (+2, +1)
(-1, +2) --> (-2, -1) --> (+1, -2) --> (+2, +1)
(-1, -2) --> (+2, -1) --> (+1, +2)

Bước 2

Mặc dù chúng tôi có z> 1 (có nghĩa là x hoặc y lớn hơn 1 ), chúng tôi thử đệ quy hai động tác đưa chúng tôi đến gần hơn (0, 0) : f (x - 1, y - 2)f ( x-2, y-1) . Cuối cùng chúng tôi giữ con đường ngắn nhất.

Bước 3

Khi z nhỏ hơn hoặc bằng 1 , chúng ta còn lại 3 khả năng được xử lý z*3^x&y( z*3-x*ythay vào đó chúng ta có thể sử dụng ):

  • x & y == 1 ngụ ý x | y == 1 và có nghĩa là x = y = 1 . Chúng ta cần thêm hai bước nữa để đạt được (0, 0) :

    2 động tác

  • x & y == 0x | y == 1 có nghĩa là chúng ta có x = 1 / y = 0 hoặc x = 0 / y = 1 . Chúng tôi cần thêm ba bước nữa để đạt được (0, 0) :

    3 động tác

  • x & y == 0x | y == 0 có nghĩa là chúng ta đã có x = y = 0 .

Đồ họa mượn từ cờ vua.com


5

Python 3 , 90 byte

Cảm ơn tsh cho -11 byte!

def f(x,y):x=abs(x);y=abs(y);s=x+y;return(.9+max(x/4,y/4,s/6)-s/2+(s==1or x==y==2))//1*2+s

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

(định dạng mã nội tuyến để tránh độc giả phải cuộn. Xin lỗi, nhưng tôi phải đánh golf chương trình của mình)

Rất rất hiệu quả.


Làm thế nào tôi có thể đến với điều này!?

1. chẵn lẻ

Giả sử rằng toàn bộ bảng được tô màu theo mẫu bàn cờ (nghĩa là các ô có x+ysố lẻ và x+ythậm chí được tô bằng các màu khác nhau).

Lưu ý rằng mỗi bước phải nhảy giữa hai ô có màu khác nhau. Vì thế:

  • Tính chẵn lẻ của số bước phải bằng với mức tương đương của x+y.

2. Xấp xỉ

Giả sử hiệp sĩ bắt đầu từ tọa độ (0,0), và đã di chuyển ncác bước, và hiện đang ở (x,y).
Để đơn giản, giả định x ≥ 0, y ≥ 0.
Chúng ta có thể kết luận rằng:

  • Vì mỗi bước xtăng nhiều nhất 2, x ≤ 2×n. Tương tự , y ≤ 2×n.
  • Vì mỗi bước x+ytăng nhiều nhất 3, x+y ≤ 3×n.

Do đó, n ≥ l(x,y)ở đâu l(x,y) = max(max(x,y)/2, (x+y)/3. (lưu ý rằng chúng tôi không cần đưa vào -xhoặc x-ytrong công thức vì theo giả định x ≥ 0 and y ≥ 0, vì vậy x+y ≥ max(x-y,y-x,-x-y), và x ≥ -x, y ≥ -y)

Nó chỉ ra rằng đó a(x,y) = round(0.4 + l(x,y))là một xấp xỉ tốt n.

  • Giả sử a(x,y)là một xấp xỉ với sai số nhỏ hơn 1, giá trị đúng được đưa ra bởi

    f(x,y) = round((a(x,y) - (x+y)) / 2) * 2 + (x+y)

    (làm tròn số trừ x+yvà chia cho 2)

3. Các trường hợp đặc biệt không thành công thức

Giả sử x ≥ 0y ≥ 0. Có 2 trường hợp đặc biệt khi thuật toán bị lỗi:

  • x == 1 and y == 0hoặc x == 0 and y == 1: Thuật toán trả về không chính xác 1trong khi câu trả lời đúng là 3.
  • x == y == 2: Thuật toán trả về không chính xác 2trong khi câu trả lời đúng là 4.

Vì vậy, chỉ cần trường hợp đặc biệt. Thêm kết quả bằng 2nếu giá trị của xylà một trong số đó.


1
@tsh Nhưng điều đó cũng đúng x==y==0.
dùng202729

Tại sao max(x+y,x-y,y-x)?
tsh

@tsh: Không, xem: x = -5, y = 5. x + y = 0, abs (xy) = 10 và do đó x + y <abs (xy)
Nova

@Nova "Giả sử x ≥ 0y ≥ 0".
dùng202729


4

TI-Basic, 86 54 byte

Dựa trên giải pháp cũ hơn của @ user202729

Input :abs(X->C:abs(Y->D:C+Ans
Ans+2int(.9+(S=1 or C=2 and D=2)-.5Ans+max({C/4,D/4,Ans/6

2

MATL , 29 byte

`JEQ2J-htZjht_h@Z^2&sG=~}@Gg*

Đầu vào là một số phức với các phần thực và phần nguyên.

Mã này rất không hiệu quả. Yêu cầu bộ nhớ của nó tăng theo cấp số nhân với đầu ra. Nó xuất hiện trong TIO cho các trường hợp thử nghiệm với đầu ra vượt quá 7.

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


2

Haskell, 79 72 byte

p l|elem(0,0)l=0|r<-[-2..2]=1+p[(x+i,y+j)|(x,y)<-l,i<-r,j<-r,(i*j)^2==4]

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

Lấy đầu vào là một danh sách các cặp số.

Một lực lượng vũ phu đơn giản. Cần rất nhiều thời gian và bộ nhớ cho kết quả> 8. Bắt đầu với một danh sách phần tử tọa độ (đầu vào), liên tục thêm tất cả các vị trí có thể đạt được cho mọi phần tử cho đến khi (0,0)có trong danh sách này. Theo dõi mức đệ quy và trả lại kết quả.

Chỉnh sửa: -7 byte nhờ @Lynn.



1

JavaScript (ES6), 90 78 byte

f=(x,y)=>y<0?f(x,-y):x<y?f(y,x):x+y<3?4-x-y&3:x-3|y-1?x-4|y-3?f(x-2,y-1)+1:3:2

Chỉnh sửa: Đã lưu 12 byte nhờ @supercat chỉ ra rằng x<0ngụ ý y<0hoặc x<y. Giải thích: Đây là một giải pháp đệ quy. Hai điều kiện đầu tiên chỉ cần đảm bảo góc phần tư đúng cho các điều kiện khác. Điều kiện thứ ba tạo ra câu trả lời cho tọa độ gần gốc tọa độ, trong khi hai điều kiện cuối cùng xử lý hai trường hợp đặc biệt khác (ngắn hơn 1 byte so với kiểm tra cả hai lần di chuyển):

0
32
2++
+2++
+++3+
++++++
(etc.)

Tất cả các hình vuông được đánh dấu +có thể được xác định bằng cách di chuyển trực tiếp về nguồn gốc và sau đó đệ quy.


Bạn có cần x<0kiểm tra? Cho ví dụ -3,6, x<ythử nghiệm sẽ biến nó thành 6, -3, y<0thử nghiệm sẽ biến thành 6,3, trong đó thử nghiệm sẽ biến thành 6,3,x<y bài kiểm tra sẽ biến thành 3,6.
supercat

@supercat Thật vậy, như Python sẽ nói, x>=y>=0...
Neil

1

Kotlin , 148 146 140 byte

fun s(x:Int,y:Int):Int=if(y<0)s(x,-y)else
if(x<y)s(y,x)else if(x+y<3)4-x-y and 3
else if(x!=3||y!=1)if(x!=4||y!=3)s(x-2,y-1)+1
else 3 else 2

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


Khá chắc chắn rằng bạn không cần :Intchỉ định loại trả về.
trị liệu

Các hàm đệ quy yêu cầu kiểu trả về vì trình biên dịch không đủ thông minh để tìm ra kiểu.
JohnWells

1
Ồ, tôi đã bỏ lỡ các cuộc gọi đệ quy. Rất tiếc
trị liệu

1

Thạch , 27 26 25 23 byte

1,-pḤµ;UÆị
¢ṗS€;0i
0ç1#

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

Rất chậm; lần ra trên TIO cho đầu ra trên 6. Lấy một số phức làm đầu vào.

Giải trình

Mã này sử dụng các số phức vì nó ngắn hơn trong một bước trung gian và nó cũng có vẻ nhanh hơn rất nhiều; bạn cũng có thể sử dụng các cặp bằng cách loại bỏ Æivà thay thế 0bằng 0,0trên dòng thứ hai.

1,-pḤµ;UÆị    Helper link. No arguments.
1,-             Get the pair [1,-1].
    Ḥ           Double each to get [2,-2].
   p            Cartesian product: get [[1,2],[1,-2],[-1,2],[-1,-2]].
     µ          Start a new chain with the list of pairs as argument.
       U        Reverse each pair.
      ;         Append the reversed pairs to the list.
        Æi      Convert each pair [real,imag] to a complex number.

¢ṗS€;0i    Helper link. Arguments: iterations, target
¢            Call the previous link to get knight moves as complex numbers.
 ṗ           Get the iterations-th Cartesian power of the list. This will
             yield 8^n tuples containing move sequences.
  S€         Sum each move sequence to get the resulting square.
    ;0       Add the starting square, since the zeroth iteration results
             in no move sequences.
      i      Find the target squares (1-based) index in the results, or 0.

0ç1#    Main link. Argument: target
0         Starting from 0,
   #      find the
  1       first number of iterations where
 ç        calling the previous link results in a nonzero result.
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.