Скільки рухається?


16

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

Правила

Даний твір може бути королем, королевою, граком, лицарем та єпископом. (Цей вхід можна прийняти за будь-які 5 унікальних символів)

2 позиції можна приймати в будь-якому зручному форматі,

Example:
a8 b8 c8 d8 ... h8
a7 b7 c7 d7 ... h7
...
...
a1 b1 c1 d1 ... h1

У випадку, якщо шматок не може дійти до нього, виведіть нічого, крім додатного цілого числа.

Приклади

i/p ---- o/p
King
a1,a4    3
a1,h6    7
b3,h5    6

Queen
a1,a4    1
a1,h6    2
b3,f7    1

Rook
a1,a4    1
a1,h6    2
h2,c7    2

Knight
a1,a4    3
a1,h6    4
b2,d3    1
b2,c3    2
b3,c3    3
a1,b2    4

Bishop
a1,a4    -1
a1,h6    2
b2,d3    -1
e1,h4    1

1
Для чого Кінгу потрібно від 12 до a1-h6? Не може Кінг піти діагностувати?
l4м2

@ l4m2, виправлено
Vedant Kandoi

1
@ngn, ви можете використовувати 0, щоб вказати на недосяжність, дві позиції завжди будуть різними.
Ведант Кандой


1
Деякі визначення натуральних чисел (наприклад, ISO-80000-2) включають 0. Рекомендуйте замінити "натуральним числом".

Відповіді:


9

JavaScript (Node.js) , 183 180 179 байт

with(Math)(a,b,c,d,t,x=abs(a-c),y=abs(b-d),v=x<y?y:x,q=0|.9+max(/[18][18]/.test(a+b+9+c+d)-v?x/2:3,y/2,x*y?x*y-4?(x+y)/3:3:2))=>t?t==2&x+y?0:t&1>x*y|t/2&x==y?1:t<4?2:v:q+(q+x+y&1)

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

Тож чекаємо крайової справи, дякую Арнольду за перевірку. Лицарська проба


@Arnauld Ну кут дійсно коштував
l4m2

Я думаю, що ви, можливо, зможете зберегти байт, замінивши останній maxна тернар.
Кудлатий

170 байт (я думаю. Я в телефоні.)
Кудлатий

@Shaggy було те, що Арнольд зазначив, що це неправильно
l4m2

6

APL (Dyalog Classic) , 117 107 105 103 98 97 95 92 89 87 байт

{(⍎⍺⊃'⌈/' '≢∘∪~∘0' '+/×' '{⍺∊⍵:0⋄1+⍺∇i/⍨∨⌿2=|×/↑⍵∘.-i←,⍳8 8}/,¨⊂¨↓⍵' '≢∘∪×2=.|⊢')⊣|-⌿⍵}

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

лівий арг - тип штуки: 0 = король, 1 = королева, 2 = грак, 3 = лицар, 4 = єпископ; правий арг - матриця 2x2 координат, кожен рядок представляє позицію; повертає 0 за недосяжність

|-⌿⍵ обчислює пару [abs (∆x), abs (∆y)]

(⍎⍺⊃... )⊣вибирає вираз зі списку "..."; якщо це функція, вона застосовується до |-⌿⍵; якщо це значення (це трапляється лише для лицаря), обов’язково повертайте його замість|-⌿⍵

  • king: max ( ⌈/) abs ∆-s

  • королева: видаліть нулі ( ~∘0) та порахуйте ( ) унікальні ( )

  • грак: сума ( +/) сигналу (монадичний ×; 0 за 0, 1 для позитивного)

  • лицар: {⍺∊⍵:0⋄1+⍺∇i/⍨∨⌿2=|×/↑⍵∘.-i←,⍳8 8}/,¨⊂¨↓⍵- починайте з початкової позиції та рекурсивно обчислюйте покоління лицарських рухів, поки остання позиція не буде встановлена; повернути глибину рекурсії

  • єпископ: чи рівні паритети двох ∆-s? (що 2=.|⊢еквівалентно =/2|⊢) помножте булевий результат (0 або 1) на унікальний для рахунку ( ≢∘∪)


Я люблю ⍎⍺⊃. Дуже розумний.
J. Sallé

@ J.Sallé дякую
квітня 1818

2

Java (JDK) , 229 байт

(p,a,b,c,d)->{c^=a/4*7;a^=a/4*7;d^=b/4*7;b^=b/4*7;int x=c<a?a-c:c-a,y=d<b?b-d:d-b,z=(x^=y^(y=y<x?y:x))-y;return p<1?x:p<2?z*y<1?1:2:p<3?2-z%2:p<4?x+y<2?3:(a<c?a+b:c+d)+x<2|x==2&z<1?4:z+2*Math.ceil((y-z)/(y>z?3:4.)):z<1?1:~z*2&2;}

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

Пояснення

  • Дошка - це дошка на основі 0.
  • Повернене значення - це ціле число, представлене як подвійне. Ніколи не буде десяткової частини.

Код:

(p,a,b,c,d)->{                          // double-returning lambda.
                                        // p is the piece-type (0: king, 1: queen, 2: rook, 3: knight, 4: bishop)
                                        // a is the origin-X
                                        // b is the origin-Y
                                        // c is the destination-X
                                        // d is the destination-Y
 c^=a/4*7;a^=a/4*7;                     // Mirror board if origin is in the top part of the board
 d^=b/4*7;b^=b/4*7;                     // Mirror board if origin is in the left part of the board
 int x=c<a?a-c:c-a,                     // x is the X-distance between a and c
     y=d<b?b-d:d-b,                     // y is the Y-distance between b and d
     z=(x^=y^(y=y<x?y:x))-y;            // z is the delta between x and y
                                        // also, swap x and y if necessary so that x is the greater value.
               //    At this point,
               //     x      cannot be 0 (because the two positions are different)
               //     z<1    means the origin and destination are on the same diagonal
               //     y<1    means the origin and destination are on the same horizontal/vertical line
 return
  p<1?x:                                //  For a king, just take the max distance.
  p<2?z*y<1?1:2:                        //  For a queen, just move once if in direct line, or twice.
  p<3?2-z%2:                            //  For a rook, just move once if on the same horizontal or vertical line, or twice
  p<4?                                  //  For a knight, 
   x+y<2?3:                             //   Hardcode 3 if moving to the next horizontal/vertical square
   (a<c?a+b:c+d)+x<2|x==2&z<1?4:        //   Hardcode 4 if moving 2 cases in diagonal or one case in diagonal in a corner.
   z+2*Math.ceil((y-z)/(y>z?3:4.)):     //   Compute the number of moves necessary for the usual cases
  z<1?1:                                //  For a bishop, hardcode 1 if they are on the same diagonal
   ~z*2&2;                              //   Return 2 if they have the same parity else 0.
}

Кредити

  • -2 байти завдяки Арнольду , а також за те, що я дав мені зрозуміти, що у мене виникли проблеми з усіма моїми кутовими справами.

1

Вугілля деревне , 108 байт

F…β⁸F⁸⊞υ⁺ι⊕κ≔⟦⟦η⟧⟧δW¬№§δ±¹ζ⊞δΦυΦ§δ±¹⁼⁵ΣEμX⁻℅ξ℅§κπ²≔Eη↔⁻℅ι℅§ζκε≡θKI⌈εQI∨∨¬⌊ε⁼⊟ε⊟ε²RI∨¬⌊ε²BI∧¬﹪Σε²∨⁼⊟ε⊟ε²NI⊖Lδ

Спробуйте в Інтернеті! Посилання на багатослівну версію коду. Пояснення:

F…β⁸F⁸⊞υ⁺ι⊕κ

Перерахуйте всі 64 квадрати дошки у попередньо задану змінну порожнього списку.

≔⟦⟦η⟧⟧δ

Складіть список списків, першим записом яких є список, що містить початкову позицію.

W¬№§δ±¹ζ

Повторюйте, поки останній запис списку не містить кінцевої позиції.

⊞δΦυΦ§δ±¹⁼⁵ΣEμX⁻℅ξ℅§κπ²

Фільтруйте всі позиції дошки, які знаходяться на відстані лицаря від будь-якого запису в останньому записі списку списків, і натисніть цей список до списку списків. Сюди входять позиції, які раніше відвідували, але ми їх все одно не цікавили, тому ми закінчуємо широким першим пошуком дошки для кінцевої позиції.

≔Eη↔⁻℅ι℅§ζκε

Обчисліть абсолютні різниці координат між початковою та кінцевою позиціями.

≡θ

Виберіть на основі вхідного фрагмента.

KI⌈ε

Якщо це король, тоді надрукуйте максимальну абсолютну різницю координат.

QI∨∨¬⌊ε⁼⊟ε⊟ε²

Якщо це королева, то надрукуйте 2, якщо дві різниці не рівні або одна дорівнює нулю.

RI∨¬⌊ε²

Якщо це грак, тоді надрукуйте 2, якщо одна з різниць не дорівнює нулю.

BI∧¬﹪Σε²∨⁼⊟ε⊟ε²

Якщо це єпископ, тоді надрукуйте 0, якщо квадрати мають протилежний паритет, інакше надрукуйте 2, якщо дві різниці не рівні.

NI⊖Lδ

Якщо це лицар, то надрукуйте кількість петель, взятих, щоб знайти кінцеве положення.


1

Japt , 67 байт

®ra
g[_rw}_â è}@=ã ü;@pUÌïVõ á ÈíaY})Ìde[TT]}a Ä}_è}_ra v *Zâ l}]gV

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

Це був досить досвід. Я взяв багато натхнення від чудового відповіді APL . Я підозрюю, що багато гольфу все ще можливо, особливо в кодексі Найт.

Позиції - це перший вхід у формі [[x1,x2],[y1,y2]]. Це також має добре працювати [[y1,y2],[x1,x2]]. Вибір штук є другим входом, з 0 = король, 1 = королева, 2 = лицар, 3 = грак, 4 = єпископ. Зауважте, що Найт і Грак обміняються місцями порівняно з відповіддю на APL.

Пояснення:

®ra         :Turn absolute positions into relative movement and store in U
®           : For each of X and Y
 ra         : Get the absolute difference between the start position and the end position

g[...]gV    :Apply the appropriate function
 [...]      : A list of functions
      gV    : Get the one indicated by the second input
g           : Apply it to U

_rw}        :King function
 rw         : Get the maximum of X and Y

_â è}       :Queen function
 â          : Get unique elements
   è        : Count non-zero elements

@=ã ü;@pUÌï2õ á ÈíaY})Ìde[TT]}a Ä}  :Knight function
 =ã ü;                              : Wrap U twice (U -> [[U]])
      @                      }a Ä   : Repeat until True; return number of tries:
        UÌ                          :  Get the previous positions
          ï                         :  Cartesian product with:
           2õ                       :   The range [1,2]
              á                     :   All permutations, i.e. [[1,2],[2,1]]
                ÈíaY})              :  Apply each move to each position
       p                            :  Store the new positions
                      Ìde[TT]       :  True if any are at the destination

_è}         :Rook function
 è          : Count non-zero elements

_ra v *Zâ l}    :Bishop function
 ra             : Absolute difference between X and Y
    v           : Is divisible by 2? (returns 1 or 0)
      *         : Times:
       Zâ       :  Get the unique elements
          l     :  Count them

@ETHproductions Гарні пропозиції. Поки я вкладав їх, я виявив, що áце [[1,2][2,1]]значно скоротилося .
Каміль Дракарі

Нічого собі, ніколи б не подумав користуватися á, приємний!
ETHproductions

Ще пара пропозицій: Uпісля цього неявна інформація @, тож ви можете зберегти два байти у рицарській функції. Ви також можете почати його, @=ã ü;щоб зберегти інший. ( ãТрюк теж розумний :-))
ETHproductions

@ETHproductions Хороша знахідка, часи, коли U мається на увазі, - це одне з речей, яких я ще не зрозумів.
Каміль Дракарі
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.