Захват на шахматной доске пешки

17

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

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

Каждый ранг описан, начиная с ранга 8 и заканчивая рангом 1; в пределах каждого ранга содержимое каждого квадрата описывается от файла "a" до файла "h". Каждая пешка обозначена одной буквой (белая пешка = "P", черная пешка = "p",). Пустые квадраты отмечаются цифрами от 1 до 8 (количество пустых квадратов), а "/" разделяет ранги. (частично взято из Википедии)

Например

8/pppppppp/8/8/4P3/8/PPPP1PPP/8

описывает доску

--------

pppppppp


    P   

PPPP PPP

--------

Белая пешка может захватить черную, если черная расположена по диагонали вверх от нее (черные - вверх-влево или вверх-вправо), а черная пешка может захватить белую пешку, если белая находится по диагонали от нее (белая вниз-влево или вниз-вправо). Никакое другое движение захвата ( en passant ) не должно рассматриваться.

вход

  • А Fen -как строка , состоящая из символов 12345678pP/.
  • Входные данные описывают пешки действительной шахматной позиции. Это означает (среди других более сложных ограничений) будет максимум 8 пешек для каждой стороны и не будет пешек в рядах 1 и 8.

Выход

  • Если есть возможность захвата для любой из сторон, вы должны вывести истинное значение и ложное значение в противном случае.

Примеры

Входы с правдивым выходом (по одному на строку)

8/7p/6P1/8/8/8/8/8
8/8/p7/1P6/3P3p/8/8/8
8/2P5/8/4P1p1/2p2P2/3p4/3p1P2/8
8/P7/8/5P2/2pp4/3P2p1/3pP3/8
8/P7/p7/p1P1P3/1P3p2/8/1p6/8
8/4p1P1/2P2P1P/2p1pPpp/8/6P1/pP1p4/8

Входы с ложным выходом (по одному на линию)

8/8/8/8/8/8/8/8
8/7P/6p1/8/8/8/8/8
8/7p/7P/8/8/8/8/8
8/pppppppp/8/8/8/8/PPPPPPPP/8
8/p7/8/1p6/5P2/8/8/8
8/p7/P7/2P1p1p1/2p5/8/PP6/8

Это код гольф, поэтому выигрывает самый короткий вход.

randomra
источник
Разве пример доски не должен быть описан 8/pppppppp/8/8/8/7P/PPPP1PPP/8?
TheNumberOne
@TheNumberOne Нет, это 7Pбудет означать, что пешка находится на последнем восьмом файле. (Диаграмма была неправильной, хотя, я исправил это.)
randomra
1
Я чувствую, что удаление en passant делает эту задачу менее интересной.
CorsiKa

Ответы:

6

Pyth, 25 байт

/smC,>JsXz`M9*LN9dJ,8T"Pp

Тестирование

шаги:

Преобразуйте ввод, заменив цифры эквивалентным количеством кавычек ( N). Это сохраняется в J. Затем мы отрезаем первые 8 или 10 символов и сжимаем результат с оригиналом. Любая пара захвата будет преобразована в "Pp", поэтому мы находим количество этой строки в результирующем списке. Это выход.

В качестве бонуса это фактически подсчитывает количество возможных захватов на входе.

isaacg
источник
Другое решение 25: к :sXz`M9*LN9"p.{7}(..)?P"1сожалению, последний параметр :не является обязательным (я думаю, что это должно быть).
Якуб
3
@Jakube будет делать.
Исаак
12

Сетчатка , 33 29 байт

T`d`w
)`\d
$0.
_

p.{7}(..)?P

Чтобы запустить код из одного файла, используйте -sфлаг.

Должно быть легко разбито чем-то вроде Perl, где разложение цифр в строки пробелов (или других символов) не занимает 17 байт.

Выход является положительным (правдивым), если есть возможный захват, и нулевым (ложным), если нет.

объяснение

T`d`w
)`\d
$0.

Это цикл из двух этапов. Первый - это этап транслитерации, который уменьшает каждую цифру и превращает нули в подчеркивания. Почему? Потому dи wрасширим следующие две строки:

0123456789
_0123456789AB...YZab...yz

Если целевой набор этапа транслитерации длиннее исходного набора, посторонние символы игнорируются, что ведет к снижению поведения (честно говоря, мне просто повезло, что я решил поставить подчеркивание перед цифрами при расширении wкласса символов) ,

Затем вторым этапом является замена, которая добавляет .к каждой цифре. Это означает , что для каждой цифры n, nпериоды добавляются до того, что цифра превратилась в подчеркивание.

_
<empty>

Это только избавляет от подчеркивания.

p.{7}(..)?P

Наконец, мы находим спички. Так как мы игнорируем en passant, захват возможен только при наличии pи затем по Pдиагонали под ним. В линейной строке это просто означает, что между двумя пешками должно быть 7 или 9 символов. Это соответствует .{7}(..)?(т.е. соответствует 7 символам, а затем, по выбору, соответствует еще двум).

Такой этап совпадения возвращает количество найденных совпадений.

Мартин Эндер
источник
Re "Должно быть легко побиваемым чем-то вроде Perl, где разложение цифр в строки пробелов (или других символов) не занимает 17 байт.": Я не могу заставить Perl даже связать ваш счет, не говоря уже о том, чтобы разбить его , ( Мой ответ на Perl. ) Но, может быть, кто-то еще может ...
msh210
3

Javascript, 272 символа

function h(t){b=[[]];for(i=-1;i++<7;){c=0;b.push(l=[]);for(j=-1;j++<7;){o=t.split('/')[i][j];switch(o){case'P':l[c++]=-1;break;case'p':l[c++]=1;break;default:c+=parseInt(o);}}}b.push([]);for(i=1;i<9;i++)for(j=0;j<8;j++)if((p=b[i][j])&&(b[i+p][j-1]||b[i+p][j+1]))return 1;}

Там, вероятно, много возможностей для улучшения.

Najkin
источник
3

Рубин, 145 123 46 байт

->b{b.gsub(/\d/){|x|?.*x.to_i}=~/p.{7}(..)?P/}

Я не знаю, почему я вообще не думал об этом. Это намного короче и также довольно читабельно.

Вот тест: http://ideone.com/Gzav8N


Старый подход:

->b{l={}
r=p
b.split(?/).map{|s|c={}
i=0
s.chars.map{|x|n=x.to_i;c[i]=x;i+=n<1?1:n;x==?P&&r||=l[i-2]==?p||l[i]==?p}
l=c}
r}

Онлайн тест: http://ideone.com/9L01lf , версия до игры в гольф: http://ideone.com/CSmqlW

История изменений доступна здесь .

Кристиан Лупаску
источник
2

ES6, 64 байта

Соответствующее количество байтов, если оно длится!

f=s=>/p.{7}(..)?P/.test(s.replace(/\d/g,n=>"        ".slice(-n)))

Я действительно думал об этом решении, не читая сначала другие ответы, но я не буду возражать, если вы мне не верите.

Нил
источник
0

PHP, 94 87 80 байт

for(;$i++<8;)$t[$i]=$s.=" ";echo preg_match("#p.{7}(..)?P#",strtr($argv[1],$t));

Эта петля + strtrнамного короче, чем preg_replace_callbackс str_pad.

Titus
источник
0

Желе, 88 84 79 72 69 65 64 63 60 байт

Определенно возможности для улучшения. Неконкурентоспособен, потому что Желе было создано до вопроса. Спасибо @lirtosiast за это!

ØDṖḊ
”_x
e1£¬
1£iЀ2Ŀ€
x"3Ŀ€;"ÇFṣ”/
w€⁾pPn0
5ĿUŒDÇ
5ĿŒD6ĿoÇS
Zachary
источник