Шаховий фінал: Білий до Мате в одному


19

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

Вхідні дані

Введення буде в STDIN - 8 рядків по 8 символів кожен. Значення кожного персонажа такі:

K/k - king
Q/q - queen
B/b - bishop
N/n - knight
R/r - rook
P/p - pawn
- - empty square

Літери верхнього регістру позначають білі шматки, а малі - чорні. Дошка буде орієнтована так, що біла грає знизу, а чорна - зверху.

Вихідні дані

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

Зразок введення

Приклад 1

Вхід:

------R-
--p-kp-p
-----n--
--PPK---
p----P-r
B-------
--------
--------

Вихід:

c6

Приклад 2

Вхід:

--b-r--r
ppq-kp-p
-np-pn-B
--------
---N----
--P----P
PP---PP-
R--QRBK-

Вихід:

Nf5

Приклад 3

Вхід:

---r-nr-
-pqb-p-k
pn--p-p-
R-------
--------
-P-B-N-P
-BP--PP-
---QR-K-

Вихід:

Rh5

Ви можете припустити, що рішення не буде залучати до виходу на ринок чи авангарду.

Це код-гольф - виграє найкоротше рішення.

(Приклади взяті з mateinone.com - пазли 81, 82 та 83)


Ні. Я думаю, для цілей цього питання ви можете припустити, що відповідь не буде мати участь у ролях чи ен-пасанті. Я оновлю питання.
Гарет

Як ми маємо поводитися з позиціями з більш ніж одним напарником?
Роб

@Rob Потрібно лише одне рішення, тому виведіть те рішення, яке ви знайдете першим.
Гарет

Чи безпечно також вважати, що рішення не передбачає просування?
Пітер Тейлор

@ Петер Так, я не хочу надто ускладнювати проблему.
Гарет

Відповіді:


7

Рубі, 589 512 510 499 493 символів

R=0..7
a=->b{o=[];R.map{|r|R.map{|c|v=Hash[?K,[6,7,8,11,13,16,17,18],?R,s=[157,161,163,167],?B,t=[156,158,166,168],?Q,s+t,?N,[1,3,5,9,15,19,21,23],?P,[32,181,183]][z=b[r][c]];v&&v.map{|s|k=2!=l=s/25+1;u=r;v=c;l.times{u+=s/5%5-2;v+=s%5-2;R===u&&R===v||break;t=b[u][v];j=t<?.&&l<8;(j||t=~/[a-z]/&&k)&&o<<=(h=b.map &:swapcase;h[u][v]=h[r][c];h[r][c]=?-;[z+"%c%d"%[97+v,8-u],h.reverse]);j&&(k||r==6)||break}}}};o}
a[$<.map{|l|l}].map{|m,b|a[b].any?{|f,x|a[x].all?{|g,y|y*""=~/K/}}||$><<m[/[^P]+/]}

Введення даних здійснюється через stdin, наприклад:

> ruby mateinone.rb
--------
--------
--------
-k------
b-------
-N-P----
--------
-----K-Q
^Z
Qb7

Вихід - це не один хід, який примушує пару в одному, але кожен хід, який робить це.

Редагувати 1: Функцію eбуло використано лише один раз, тому я її накреслив. По-друге, кодування зараз базується на цифрі 5 замість 10. А рефакторинг клонування дошки заощадив досить багато символів.

Редагувати 2: Все-таки не настільки вдосконалення, як я хотів. Зміна хеша з {a=>b,c=>d}на Hash[a,b,c,d]. Це коштує 4 символи, але економить один на пару ключ-значення.

Редагування 3: Лише незначні скорочення: вставка M (4 символи), t==?--> t<?.(2), видалення пішака в алгебраїчних позначеннях в кінці (2), замінені місцями (3). Зараз у програмі менше 500 символів.

Редагувати 4: Цікаво, скільки ще можна знайти в такій програмі. Перемістив інваріант за межами циклу і знайшов ще один дублікат обчислення.


Під "не одним, а будь-яким" ви маєте на увазі "не обов'язково один, а кожен"?
Матвій

@Matthew Ти маєш рацію. Я мав на увазі «кожен».
Говард

Ви можете використовувати [*$<]замість $<.map{|l|l}.
Lowjacker
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.