Przechwyć na szachownicy

17

Powinieneś napisać program lub funkcję, która odbiera ciąg reprezentujący szachownicę z tylko pionkami jako danymi wejściowymi i wyjściowymi lub zwraca, czy możliwe jest przechwycenie na planszy.

Dane wejściowe są w notacji FEN opisującej pozycje białych i czarnych pionków bez innych elementów. Powinieneś zdecydować, czy istnieje pionek, który może schwytać wroga.

Każda ranga jest opisana, począwszy od rangi 8, a kończąc na rangi 1; w obrębie każdej rangi zawartość każdego kwadratu jest opisana z pliku „a” do pliku „h”. Każdy pion jest oznaczony pojedynczą literą (biały pion = „P”, czarny pion = „p”,). Puste kwadraty są zapisywane za pomocą cyfr od 1 do 8 (liczba pustych kwadratów), a „/” rozdziela szeregi. (częściowo pochodzi z Wikipedii)

Na przykład

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

opisuje tablicę

--------

pppppppp


    P   

PPPP PPP

--------

Biały pionek może schwytać czarnego, jeśli czarny jest ustawiony po przekątnej do góry (czarny jest w górę w lewo lub w górę w prawo), a czarny pionek może złapać biały, jeśli biały znajduje się po przekątnej (biały jest dół-lewo lub dół-prawo). Nie należy brać pod uwagę żadnego innego ruchu przechwytywania ( en passant ).

Wejście

  • Ciąg typu FEN składający się z znaków 12345678pP/.
  • Dane wejściowe opisują pionki prawidłowej pozycji w szachach. Oznacza to (między innymi bardziej złożonymi ograniczeniami), że po każdej stronie będzie maksymalnie 8 pionków i nie będzie pionków na poziomach 1 i 8.

Wynik

  • Jeśli istnieje możliwość przechwycenia którejkolwiek ze stron, w przeciwnym razie powinieneś podać wartość prawdy i fałsz .

Przykłady

Wejścia z prawdziwym wyjściem (jeden na linię)

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

Wejścia z wyjściem falsy (jeden na linię)

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

To jest golf golfowy, więc wygrywa najkrótszy wpis.

randomra
źródło
Czy tablica przykładowa nie powinna być opisywana 8/pppppppp/8/8/8/7P/PPPP1PPP/8?
TheNumberOne
@TheNumberOne Nie, 7Poznaczałoby, że pionek znajduje się w ostatnim 8. pliku. (Schemat był jednak niepoprawny, poprawiłem to.)
randomra
1
Wydaje mi się, że usunięcie en passant sprawia, że ​​jest to mniej interesująca łamigłówka.
corsiKa

Odpowiedzi:

6

Pyth, 25 bajtów

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

Zestaw testowy

Kroki:

Przekształć dane wejściowe, zastępując cyfry równoważną liczbą znaków cudzysłowu ( N). To jest zapisane w J. Następnie odcinamy pierwsze 8 lub 10 znaków i kompresujemy wynik za pomocą oryginału. Każda para przechwytująca zostanie przekształcona "Pp", więc znajdziemy liczbę tego ciągu na wynikowej liście. To jest wynik.

Jako bonus, faktycznie liczy się liczba możliwych przechwyceń na wejściu.

isaacg
źródło
Kolejne 25 rozwiązanie: :sXz`M9*LN9"p.{7}(..)?P"1Niestety ostatni parametr :nie jest opcjonalny (myślę, że powinien).
Jakube
3
@Jakube zrobi.
isaacg
12

Retina , 33 29 bajtów

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

p.{7}(..)?P

Aby uruchomić kod z jednego pliku, użyj -sflagi.

Powinny być łatwe do pokonania przez coś takiego jak Perl, gdzie interpretacja cyfr w ciągi spacji (lub innych znaków) nie zajmuje 17 bajtów.

Wynik jest dodatni (prawda), jeśli możliwe jest przechwycenie, a zero (fałsz), jeśli nie ma.

Wyjaśnienie

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

Jest to pętla dwuetapowa. Pierwszy to etap transliteracji, który zmniejsza każdą cyfrę i zamienia zera na podkreślenia. Dlaczego? Ponieważ di wrozwiń do następujących dwóch wierszy:

0123456789
_0123456789AB...YZab...yz

Jeśli docelowy zestaw etapu transliteracji jest dłuższy niż zbiór źródłowy, znaki z zewnątrz są ignorowane, stąd zachowanie malejące (szczerze mówiąc, to po prostu szczęście, że postanowiłem umieścić wznak podkreślenia przed cyframi podczas rozwijania klasy znaków) .

Następnie drugim etapem jest zamiana, która dołącza .do każdej cyfry. Oznacza to, że dla każdej cyfry n, nokresy są dodawane wcześniej cyfra jest przekształcony podkreślenia.

_
<empty>

To po prostu usuwa podkreślenia.

p.{7}(..)?P

Wreszcie znajdujemy dopasowania. Ponieważ ignorujemy en passant, przechwytywanie jest możliwe tylko wtedy, gdy pod nim znajduje się a, pa następnie Pprzekątna. W ciągu liniowym oznacza to po prostu, że pomiędzy dwoma pionkami musi być 7 lub 9 znaków. Jest to zgodne z .{7}(..)?(tzn. Dopasuj 7 znaków, a następnie, opcjonalnie, dopasuj kolejne dwa).

Taki etap dopasowania zwraca liczbę znalezionych dopasowań.

Martin Ender
źródło
Re „Powinny być łatwe do pokonania przez coś takiego jak Perl, w którym ekspansja cyfr w ciągi spacji (lub innych znaków) nie zajmuje 17 bajtów.”: Nie mogę zmusić Perla do wyrównania twojego wyniku, nie mówiąc już o pobiciu go . ( Moja Perl odpowiada. ) Ale może ktoś inny może ...
msh210
3

JavaScript, 272 znaków

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;}

Prawdopodobnie jest wiele miejsca na ulepszenia.

Najkin
źródło
3

Rubin, 145 123 46 bajtów

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

Nie wiem, dlaczego w ogóle o tym nie myślałem. Jest znacznie krótszy, a także dość czytelny.

Oto test: http://ideone.com/Gzav8N


Stare podejście:

->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}

Test online: http://ideone.com/9L01lf , wersja przed golfem: http://ideone.com/CSmqlW

Historia modyfikacji jest dostępna tutaj .

Cristian Lupascu
źródło
2

ES6, 64 bajty

Odpowiednia liczba bajtów, jeśli trwa!

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

Właściwie pomyślałem o tym rozwiązaniu, nie czytając najpierw innych odpowiedzi, ale nie będę miał nic przeciwko, jeśli mi nie uwierzysz.

Neil
źródło
0

PHP, 94 87 80 bajtów

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

Ta pętla + strtrjest znacznie krótsza niż preg_replace_callbackz str_pad.

Tytus
źródło
0

Galaretka, 88 84 79 72 69 65 64 63 60 bajtów

Zdecydowanie miejsce na ulepszenia. Nie konkuruje, ponieważ Jelly został stworzony przed pytaniem. Dzięki @lirtosiast za powiedzenie mi tego!

ØDṖḊ
”_x
e1£¬
1£iЀ2Ŀ€
x"3Ŀ€;"ÇFṣ”/
w€⁾pPn0
5ĿUŒDÇ
5ĿŒD6ĿoÇS
Zacharý
źródło