Шукаю Leapers


19

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

Листя - це казкове шахове узагальнення лицарів. Листки параметризовані двома цілими числами m і n і можуть переміщувати m квадратів в одну сторону, а потім ще n n квадратів у будь-якому перпендикулярному напрямку. Для стандартного лицаря маємо (m, n) = (2, 1) . Весь хід вважається одиночним стрибком, так що жоден з квадратів на шляху до цілі не повинен бути порожнім або навіть існувати.

Змагання

Вам надається «шахова дошка» у вигляді списку позитивних 2D цілих цілих координат, які представляють квадрати, що входять до дошки. Ваше завдання - знайти стрибка, який при достатній кількості рухів може досягти будь-якого квадрата на дошці.

Давайте розглянемо кілька прикладів. У стандартній шаховій дошці використовується звичайна сітка площею 8х8 (зауважте, що для цього виклику ми не розрізняємо білі та чорні квадрати):

########
########
########
########
########
########
########
########

Стандартний лицар може охопити всіх цих, тому це (2, 1)був би дійсний вихід. Однак, (1, 1)наприклад, це не було б дійсним, оскільки такий шматок може досягати лише половини квадратів незалежно від того, де він починається. (1, 0)з іншого боку, також був би дійсний вихід, оскільки всі квадрати ортогонально пов'язані.

Тепер, якщо у нас є неправильна дошка, наприклад:

#   #
 # # #
  # # #
 # #
    #

Тоді можливі рішення є (1, 1)і (3, 1). Ми також можемо мати дошку з повністю відключеними регіонами, як-от:

#### ####
#### ####
#### ####
#### ####

Стандартний лицар (2, 1)все ще може дістатися до всіх квадратів тут, що насправді є єдиним рішенням.

І, нарешті, наступну просту дошку взагалі не може досягти жоден скакун:

#
 ##

Зауважте, що формат введення буде не представленням ASCII, а списком координат. Наприклад, другий приклад вище можна навести у вигляді:

[[1, 1], [5, 1], [2, 2], [4, 2], [6, 2], [3, 3], [5, 3], [7, 3], [2, 4], [4, 4], [5, 5]]

Правила

Ви можете написати програму або функцію, взявши введення через STDIN (або найближчу альтернативу), аргумент командного рядка або аргумент функції та вивівши результат через STDOUT (або найближчу альтернативу), значення повернення функції або параметр функції (out).

Координати введення можна приймати у будь-якому зручному форматі списку (плоский список, список пар, список складних цілих чисел, рядок з послідовними роздільниками тощо).

Вихід повинен бути двома цілими числами m і n, які ідентифікують скачок, якщо рішення існує (як два окремі цілі числа, список, рядок з нечисловим роздільником і т. Д.). Якщо рішення не існує, ви можете вивести будь-яке послідовне значення, яке, можливо, не може бути дійсним перепусником. Сюди входить пара цілих чисел (0, 0)у вашому звичайному форматі, а також все, що не є парою невід’ємних цілих чисел.

Вашій програмі потрібно обробити будь-який тестовий випадок протягом хвилини . Це дещо нечітке обмеження, але використовуйте здоровий глузд: якщо на вашій машині потрібно 2 хвилини, я думаю, ми можемо припустити, що він може працювати протягом 1 на чужому, але якщо це займе 20, це менш ймовірно. Кожен тестовий випадок не повинен бути важким вирішити за лічені секунди, тому це правило діє лише для виключення наївної грубої сили.

Діють стандартні правила .

Випробування

Кожен тестовий випадок має форму board => all valid leapers. Пам'ятайте, що вам потрібно вивести лише один із них. Якщо список випускників порожній, не забудьте повернути щось, що не є дійсним.

Examples above:
[[1, 1], [1, 2], [1, 3], [1, 4], [1, 5], [1, 6], [1, 7], [1, 8], [2, 1], [2, 2], [2, 3], [2, 4], [2, 5], [2, 6], [2, 7], [2, 8], [3, 1], [3, 2], [3, 3], [3, 4], [3, 5], [3, 6], [3, 7], [3, 8], [4, 1], [4, 2], [4, 3], [4, 4], [4, 5], [4, 6], [4, 7], [4, 8], [5, 1], [5, 2], [5, 3], [5, 4], [5, 5], [5, 6], [5, 7], [5, 8], [6, 1], [6, 2], [6, 3], [6, 4], [6, 5], [6, 6], [6, 7], [6, 8], [7, 1], [7, 2], [7, 3], [7, 4], [7, 5], [7, 6], [7, 7], [7, 8], [8, 1], [8, 2], [8, 3], [8, 4], [8, 5], [8, 6], [8, 7], [8, 8]] => [[0, 1], [1, 2], [1, 4], [2, 3], [3, 4]]
[[1, 1], [5, 1], [2, 2], [4, 2], [6, 2], [3, 3], [5, 3], [7, 3], [2, 4], [4, 4], [5, 5]] => [[1, 1], [1, 3]]
[[1, 1], [2, 2], [3, 2]] => []
[[1, 1], [1, 2], [1, 3], [1, 4], [2, 1], [2, 2], [2, 3], [2, 4], [3, 1], [3, 2], [3, 3], [3, 4], [4, 1], [4, 2], [4, 3], [4, 4], [6, 1], [6, 2], [6, 3], [6, 4], [7, 1], [7, 2], [7, 3], [7, 4], [8, 1], [8, 2], [8, 3], [8, 4], [9, 1], [9, 2], [9, 3], [9, 4]] => [[1, 2]]

Square boards:
[[1, 1], [1, 2], [2, 1], [2, 2]] => [[0, 1]]
[[1, 1], [1, 2], [1, 3], [2, 1], [2, 2], [2, 3], [3, 1], [3, 2], [3, 3]] => [[0, 1]]
[[1, 1], [1, 2], [1, 3], [1, 4], [2, 1], [2, 2], [2, 3], [2, 4], [3, 1], [3, 2], [3, 3], [3, 4], [4, 1], [4, 2], [4, 3], [4, 4]] => [[0, 1], [1, 2]]
[[1, 1], [1, 2], [1, 3], [1, 4], [1, 5], [2, 1], [2, 2], [2, 3], [2, 4], [2, 5], [3, 1], [3, 2], [3, 3], [3, 4], [3, 5], [4, 1], [4, 2], [4, 3], [4, 4], [4, 5], [5, 1], [5, 2], [5, 3], [5, 4], [5, 5]] => [[0, 1], [1, 2]]
[[1, 1], [1, 2], [1, 3], [1, 4], [1, 5], [1, 6], [2, 1], [2, 2], [2, 3], [2, 4], [2, 5], [2, 6], [3, 1], [3, 2], [3, 3], [3, 4], [3, 5], [3, 6], [4, 1], [4, 2], [4, 3], [4, 4], [4, 5], [4, 6], [5, 1], [5, 2], [5, 3], [5, 4], [5, 5], [5, 6], [6, 1], [6, 2], [6, 3], [6, 4], [6, 5], [6, 6]] => [[0, 1], [1, 2], [2, 3]]
[[1, 1], [1, 2], [1, 3], [1, 4], [1, 5], [1, 6], [1, 7], [2, 1], [2, 2], [2, 3], [2, 4], [2, 5], [2, 6], [2, 7], [3, 1], [3, 2], [3, 3], [3, 4], [3, 5], [3, 6], [3, 7], [4, 1], [4, 2], [4, 3], [4, 4], [4, 5], [4, 6], [4, 7], [5, 1], [5, 2], [5, 3], [5, 4], [5, 5], [5, 6], [5, 7], [6, 1], [6, 2], [6, 3], [6, 4], [6, 5], [6, 6], [6, 7], [7, 1], [7, 2], [7, 3], [7, 4], [7, 5], [7, 6], [7, 7]] => [[0, 1], [1, 2], [2, 3]]

Miscellaneous:
[[1, 1], [2, 1]] => [[0, 1]]
[[1, 1], [1, 2]] => [[0, 1]]
[[1, 1], [12, 35]] => [[11, 34]]
[[1, 1], [1, 2], [2, 1], [2, 2], [6, 1], [6, 2], [6, 3], [6, 4], [7, 1], [7, 2], [7, 3], [7, 4], [8, 1], [8, 2], [8, 3], [8, 4], [9, 1], [9, 2], [9, 3], [9, 4]] => []
[[1, 1], [1, 2], [1, 3], [1, 4], [1, 5], [1, 6], [2, 1], [2, 2], [2, 3], [2, 4], [2, 5], [2, 6], [3, 1], [3, 2], [3, 5], [3, 6], [4, 1], [4, 2], [4, 5], [4, 6], [5, 1], [5, 2], [5, 3], [5, 4], [5, 5], [5, 6], [6, 1], [6, 2], [6, 3], [6, 4], [6, 5], [6, 6]] => [[0, 1], [1, 2], [1, 4]]
[[2, 2], [2, 4], [2, 6], [2, 8], [4, 2], [4, 4], [4, 6], [4, 8], [6, 2], [6, 4], [6, 6], [6, 8], [8, 2], [8, 4], [8, 6], [8, 8]] => [[0, 2], [2, 4]]

Random boards:
[[1, 5], [1, 9], [2, 6], [2, 8], [2, 10], [2, 12], [3, 5], [3, 7], [3, 9], [3, 11], [3, 13], [4, 2], [4, 4], [4, 6], [4, 8], [4, 14], [5, 1], [5, 3], [5, 5], [5, 7], [6, 2], [6, 4], [7, 1], [8, 2]] => [[1, 1], [1, 3]]
[[1, 3], [1, 4], [1, 5], [1, 6], [1, 7], [2, 1], [2, 2], [2, 3], [2, 4], [2, 7], [3, 1], [3, 2], [3, 3], [3, 4], [3, 6], [3, 7], [4, 2], [4, 3], [4, 4], [4, 5], [4, 6], [5, 3], [5, 4], [5, 6]] => [[0, 1], [1, 2]]
[[1, 8], [2, 6], [2, 10], [3, 3], [3, 4], [3, 8], [4, 1], [4, 11], [5, 3], [5, 9], [6, 12], [8, 11], [10, 10], [11, 12], [12, 6], [12, 8], [13, 6], [13, 8], [13, 10], [13, 11], [14, 5], [14, 7], [14, 8], [14, 13], [14, 14], [15, 7], [15, 9], [15, 11], [15, 12], [16, 6], [16, 7], [16, 9], [16, 13], [16, 14], [17, 10], [17, 12], [18, 8], [18, 12], [20, 9], [21, 11], [22, 13], [23, 10], [23, 11], [23, 15], [24, 12]] => [[1, 2]]
[[1, 17], [1, 21], [3, 11], [3, 15], [3, 19], [3, 23], [5, 13], [5, 21], [7, 11], [7, 15], [7, 19], [9, 1], [9, 13], [9, 17], [11, 3], [11, 7], [11, 15], [11, 19], [13, 5], [13, 9], [13, 13], [13, 17], [13, 21], [15, 11], [15, 15], [15, 19], [17, 13], [17, 17]] => [[2, 2], [2, 6], [2, 10]]
[[1, 3], [2, 4], [2, 5], [3, 6], [4, 1], [5, 3], [5, 6], [5, 7], [6, 12], [6, 14], [6, 21], [7, 9], [7, 19], [8, 9], [8, 15], [8, 17], [8, 18], [8, 24], [9, 12], [9, 19], [10, 12], [10, 14], [10, 17], [10, 21], [11, 22], [12, 15], [12, 17], [12, 24], [13, 16], [14, 20], [14, 21], [14, 26], [15, 13], [15, 19], [16, 18], [16, 23], [17, 16], [17, 24]] => [[2, 3]]
[[1, 11], [3, 13], [4, 10], [6, 14], [8, 12], [9, 9], [9, 15], [12, 8], [13, 5], [13, 19], [13, 21], [14, 8], [15, 1], [15, 17], [16, 4], [16, 14], [16, 18], [16, 20], [17, 21], [18, 2], [18, 16], [18, 18], [19, 9], [19, 13], [19, 15], [20, 12], [21, 1], [21, 17], [22, 4], [22, 10], [23, 7]] => [[1, 3]]
[[1, 39], [6, 37], [8, 32], [10, 27], [11, 31], [11, 35], [12, 22], [16, 21], [16, 29], [16, 33], [18, 34], [21, 3], [21, 9], [21, 19], [23, 8], [23, 14], [23, 22], [23, 24], [23, 36], [24, 6], [25, 13], [25, 17], [26, 1], [26, 11], [28, 6], [28, 20], [28, 26], [28, 30], [28, 34], [30, 11], [30, 15], [30, 21], [32, 6], [33, 28], [33, 32], [35, 13], [35, 23]] => [[2, 5]]

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


Швидке запитання. Як рицар (2,1)? Виправте мене, якщо я помиляюся, але я впевнений, що лицарі можуть рухати 3 квадрати в будь-якому напрямку, а потім 1 квадрат у будь-якому напрямку, перпендикулярному попередньому, так натомість має бути (3,1).
Р. Кап

1
@ R.Kap Ви помиляєтесь. ;) en.wikipedia.org/wiki/Knight_(chess)#Movement
DLosc

@DLosc Добре, вау. Гадаю, я був. Дякую за це!
Р. Кап

Чи можемо ми випустити всіх дійсних скачок у списку? Якщо ми це зробимо, чи можемо ми випустити еквівалентні скачки, як [[1, 0], [0, 1]]?
FryAmTheEggman

@FryAmTheEggman Просто (будь-який) один із них, будь ласка.
Мартін Ендер

Відповіді:


12

Pyth, 41 35

hfqQu@+G+VM*s_BM*F_BMTGQ]hQ)maVhQdt

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

Спробуйте тут або запустіть тестовий набір

Збережено 6 байт завдяки isaacg ! По суті, просто знаходить усіх високопрофільних кандидатів, вибираючи кожного дійсного стрибка від першої плитки до другої плитки. Тоді для кожного з них він робить усі вісім конфігурацій [x, y]компенсацій, які може здійснити прокату. Потім він знаходить усі рухи, починаючи з першої плитки, що слідує за переходом, і відкидає ті, які не є у вході. Це продовжує робити, поки результат не зміниться. Якщо цей остаточний список такий самий, як вхідний, то лідер був дійсним.

Стандартна шахова дошка зайняла найдовше, коли я тестував, на моєму не дуже вражаючому комп'ютері пішло близько 3 секунд.

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