Лицарська відстань


24

У Шахах Лицар на сітці (x, y) може переміститися до (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) за один крок. Уявіть нескінченну шахівницю з лише Лицарем на (0, 0):

Скільки кроків потрібно для переміщення лицаря від (0, 0) до (t x , t y )?

Вхідні дані

Два цілих числа: t x , t y ;

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

Вихідні дані

Мінімальні кроки, необхідні для переміщення лицаря з (0, 0) до (t x , t y ).

Правила

  • код гольфу

Тестові шафи

  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}%)}`));

Пов'язані OEIS

Ось декілька OEIS для подальшого читання

  • A018837 : Кількість кроків для досягнення лицарем (n, 0) на нескінченній шаховій дошці.
  • A018838 : Кількість кроків для досягнення лицарем (n, n) на нескінченній шаховій дошці.
  • A065775 : Масив T, прочитаний по діагоналях: T (i, j) = найменша кількість рухів лицаря на шаховій дошці (нескінченна в усіх напрямках), необхідна для переходу від (0,0) до (i, j).
  • A183041 : Найменша кількість ходів лицаря від (0,0) до (n, 1) на нескінченній шаховій дошці.

Ви можете взяти довідку про формулу , наведеної в oeis.org/A065775
TSH

2
Чи можу я прийняти введення як комплексне число x+yi?
Лінн

1
@lynn я думаю, що це прийнятно.
tsh

@ user202729 оновив фрагмент коду, щоб показати результат.
tsh

Дуже тонка карта.
Willtech

Відповіді:


11

Мова Вольфрама (Mathematica) , 64 байти

Використання вбудованого KnightTourGraph.

Збережено 2 байти завдяки Mathe172 .

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

Спробуйте в Інтернеті!

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


14
Mathematica
buildins

1
Трохи коротше:GraphDistance[KnightTourGraph@@({x,y}=Abs@{##}+5),2y+3,(x-2)y-2]&
Лукас Ленг

Що з цією мовою? Чому всі ці вбудовані файли попередньо завантажені? Чи намагається завершити фразу за допомогою вкладки віками?
OganM

@OganM Mathematica не підтримує автоматичне завершення в інтерфейсі командного рядка. Завершення авто в інтерфейсі ноутбука виглядає це .
алефальфа

1
@OganM Можливо, розробники використовують Trie (структуру даних) або просто двійковий пошук у списку відсортованих вбудованих модулів. Так, чому лінійний пошук? | Зауважте, що Mathematica - це невільна мова із закритим кодом, тому ніхто не знає, як працює насправді предиктор. | Справжнім програмістам не потрібно автоматичного завершення. : P
користувач202729

7

JavaScript (ES6), 90 75 72 байти

Натхненний формулою, наведеною для A065775 . Повільно, як пекло, на (не дуже) великі відстані.

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

Спробуйте в Інтернеті!

Як?

Ми визначаємо z як порозрядну АБО між x і y .

Крок 1

Спочатку переконуємося, що ми знаходимося в певному квадранті, примушуючи і x, і y бути негативними. Поки z <0 (що означає, що або x або y є від'ємним), ми обробляємо рекурсивний виклик f (-y, x) :

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

Крок №2

У той час як у нас z> 1 (це означає, що або x, або y більше, ніж 1 ), ми рекурсивно намагаємось два ходи, що наближають нас до (0, 0) : f (x-1, y-2) і f ( х-2, у-1) . Ми врешті-решт тримаємо найкоротший шлях.

Крок №3

Коли z менше або дорівнює 1 , нам залишаються три можливості, які обробляються z*3^x&y(ми можемо використовувати z*3-x*yзамість цього):

  • x & y == 1 означає x | y == 1 і означає, що x = y = 1 . Нам потрібні ще два рухи, щоб досягти (0, 0) :

    2 ходи

  • x & y == 0 і x | y == 1 означає, що у нас або x = 1 / y = 0, або x = 0 / y = 1 . Нам потрібні ще три рухи, щоб досягти (0, 0) :

    3 ходи

  • x & y == 0 і x | y == 0 означає, що у нас вже x = y = 0 .

Графіка, запозичена у chess.com


5

Python 3 , 90 байт

Дякую tsh за -11 байт!

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

Спробуйте в Інтернеті!

(вбудоване форматування коду, щоб уникнути необхідності прокрутки читачів. Вибачте, але я маю програму для гольфу)

Дуже дуже ефективно.


Як я міг придумати це !?

1. Паритет

Передбачає, що вся дошка забарвлена ​​в шаховому порядку (тобто клітинки з x+yнепарними і x+yпарними забарвлюються різними кольорами).

Зауважте, що кожен крок повинен переходити між двома клітинками різного кольору. Тому:

  • Паритет кількості кроків повинен дорівнювати паритету x+y.

2. Наближення

Припускає, що лицар починається з координати (0,0)і перемістив nкроки, і в даний час знаходиться (x,y).
Для простоти передбачається x ≥ 0, y ≥ 0.
Можна зробити висновок:

  • Так як кожен крок xзбільшується НЕ більш ніж на 2, x ≤ 2×n. Точно так же y ≤ 2×n.
  • Так як кожен крок x+yзбільшується НЕ більш ніж на 3, x+y ≤ 3×n.

Тому n ≥ l(x,y)де l(x,y) = max(max(x,y)/2, (x+y)/3. (зауважте, що нам не потрібно включати -xабо x-yу формулу, оскільки, припускаючи x ≥ 0 and y ≥ 0, так, x+y ≥ max(x-y,y-x,-x-y)і x ≥ -x, y ≥ -y)

Виявляється, a(x,y) = round(0.4 + l(x,y))це гарне наближення до n.

  • Припустимо a(x,y), це наближення з помилкою менше 1, правильне значення задається значенням

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

    (круглі під відніманням x+yі діленням на 2)

3. Особливі випадки, що не відповідають формулі

Припустимо x ≥ 0і y ≥ 0. Є два особливих випадки, коли алгоритм виходить з ладу:

  • x == 1 and y == 0або x == 0 and y == 1: Алгоритм повертається неправильно, 1коли правильна відповідь 3.
  • x == y == 2: Алгоритм повертається неправильно, 2тоді як правильна відповідь 4.

Отже, лише спеціальні. Додайте результат, 2якщо значення xта yє одним із таких.


1
@tsh Але це x==y==0теж правда .
користувач202729

Чому max(x+y,x-y,y-x)?
tsh

@tsh: Ні, дивіться: x = -5, y = 5. x + y = 0, abs (xy) = 10 і тому x + y <abs (xy)
Нова

@Nova "Припустимо x ≥ 0і y ≥ 0".
користувач202729


4

TI-Basic, 86 54 байти

На основі старішого рішення @ 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 байт

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

Введення - це складне число з цілими дійсними та уявними частинами.

Код дуже неефективний. Потреби в пам'яті збільшуються експоненціально з виходом. Час вичерпується в TIO для тестових випадків, вихід яких перевищує 7.

Спробуйте в Інтернеті!


2

Haskell, 79 72 байти

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]

Спробуйте в Інтернеті!

Приймає вхід як однотонний список пар чисел.

Проста груба сила. Потрібно багато часу та пам'яті для отримання результатів> 8. Починаючи з одного списку координат елементів (введення), кілька разів додайте всі позиції, до яких можна дійти для кожного елемента, поки не (0,0)буде в цьому списку. Слідкуйте за рівнем рекурсії та повертайте її як результат.

Редагувати: -7 байт завдяки @Lynn



1

JavaScript (ES6), 90 78 байт

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

Edit: Збережено 12 байтів завдяки @supercat вказуючи на те , що x<0має на увазі або y<0або x<y. Пояснення: Це рекурсивне рішення. Перші дві умови просто забезпечують правильний квадрант для інших умов. Третя умова генерує відповідь на координати поблизу початку, тоді як останні два умови стосуються двох інших спеціальних випадків (1 байт коротший, ніж тестування обох ходів):

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

Усі позначені квадрати +можна визначити, рухаючись безпосередньо до початку, а потім повторюючись.


Вам потрібен x<0тест? Враховуючи, наприклад, -3,6, x<yтест перетворив би його на 6, -3, що y<0тест перетвориться на 6,3, а x<yтест перетвориться на 3,6.
supercat

@supercat Дійсно, як би сказав Python, x>=y>=0...
Ніл

1

Котлін , 148 146 140 байт

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

Спробуйте в Інтернеті!


Досить впевнений, що вам не потрібно :Intвказувати тип повернення.
therealfarfetchd

Рекурсивні функції вимагають повернення типу, оскільки компілятор недостатньо розумний, щоб визначити тип.
JohnWells

1
О, я пропустив рекурсивні дзвінки. Упс
therealfarfetchd

1

Желе , 27 26 25 23 байт

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

Спробуйте в Інтернеті!

Дуже повільно; тайм-аут на TIO для виходів понад 6. Бере як вхідне комплексне число.

Пояснення

Код використовує складні числа, оскільки він був коротшим на проміжному кроці, а також здається набагато швидшим; Ви можете також використовувати пари шляхом видалення Æiі заміни 0з 0,0на другий лінії.

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.
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.