Capture sur l'échiquier du pion

17

Vous devez écrire un programme ou une fonction qui reçoit une chaîne représentant un échiquier avec uniquement des pions en entrée et en sortie ou renvoie si une capture est possible sur le tableau.

L'entrée est dans une notation de type FEN décrivant les positions des pions blancs et noirs sans autres pièces présentes. Vous devez décider s'il existe un pion qui peut capturer un ennemi.

Chaque rang est décrit, commençant par le rang 8 et se terminant par le rang 1; à l'intérieur de chaque rang, le contenu de chaque carré est décrit du fichier "a" au fichier "h". Chaque pion est identifié par une seule lettre (pion blanc = "P", pion noir = "p",). Les carrés vides sont notés en utilisant les chiffres 1 à 8 (le nombre de carrés vides), et "/" sépare les rangs. (partiellement extrait de Wikipedia)

Par exemple

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

décrit le tableau

--------

pppppppp


    P   

PPPP PPP

--------

Un pion blanc peut capturer un noir si le noir est positionné en diagonale vers le haut (le noir est en haut à gauche ou en haut à droite) et un pion noir peut capturer un blanc si le blanc est en diagonale en dessous de lui (le blanc est en bas à gauche ou en bas à droite). Aucun autre mouvement de capture ( en passant ) ne doit être envisagé.

Contribution

  • Une chaîne de type FEN composée des caractères 12345678pP/.
  • L'entrée décrit les pions d'une position de jeu d'échecs valide. Cela signifie (entre autres contraintes plus complexes) qu'il y aura au plus 8 pions pour chaque côté et aucun pion aux rangs 1 et 8.

Production

  • S'il y a une capture possible pour l'un ou l'autre côté, vous devez sortir une valeur véridique et une valeur fausse sinon.

Exemples

Entrées avec sortie véridique (une par ligne)

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

Entrées avec sortie falsifiée (une par ligne)

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

C'est le golf de code, donc l'entrée la plus courte gagne.

randomra
la source
Le tableau d'exemple ne devrait-il pas être décrit par 8/pppppppp/8/8/8/7P/PPPP1PPP/8?
TheNumberOne
@TheNumberOne Non, 7Pcela signifierait que le pion est sur le dernier, 8ème fichier. (Le diagramme était cependant incorrect, j'ai corrigé cela.)
randomra
1
Je pense que retirer en passant rend ce puzzle moins intéressant.
corsiKa

Réponses:

6

Pyth, 25 octets

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

Suite de tests

Pas:

Transformez l'entrée en remplaçant les chiffres par le nombre équivalent de guillemets ( N). Ceci est enregistré dans J. Nous coupons ensuite les 8 ou 10 premiers caractères et compressons le résultat avec l'original. Toute paire de capture sera transformée en "Pp", donc nous trouvons ensuite le nombre de cette chaîne dans la liste résultante. Ceci est la sortie.

En prime, cela compte en fait le nombre de captures possibles dans l'entrée.

isaacg
la source
Autre solution: :sXz`M9*LN9"p.{7}(..)?P"1malheureusement, le dernier paramètre de :n'est pas facultatif (je pense qu'il devrait l'être).
Jakube
3
@Jakube fera l'affaire.
isaacg
12

Rétine , 33 29 octets

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

p.{7}(..)?P

Pour exécuter le code à partir d'un seul fichier, utilisez l' -sindicateur.

Devrait être facilement battable par quelque chose comme Perl où l'expansion des chiffres en chaînes d'espaces (ou d'autres caractères) ne prend pas 17 octets.

La sortie est positive (véridique) s'il y a une capture possible et nulle (fausse) s'il n'y en a pas.

Explication

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

Il s'agit d'une boucle de deux étapes. Le premier est une étape de translittération qui décrémente chaque chiffre et transforme les zéros en tirets bas. Pourquoi? Parce que det wdéveloppez les deux lignes suivantes:

0123456789
_0123456789AB...YZab...yz

Si l'ensemble cible d'une étape de translittération est plus long que l'ensemble source, les caractères étrangers sont ignorés, d'où le comportement de décrémentation (honnêtement, c'est juste par chance que j'ai décidé de mettre le trait de soulignement devant les chiffres lors du développement de la wclasse de caractères) .

Ensuite, la deuxième étape est un remplacement, qui ajoute un .à chaque chiffre. Cela signifie que pour chaque chiffre n, des npoints sont ajoutés avant que ce chiffre ne soit transformé en trait de soulignement.

_
<empty>

Cela supprime simplement les traits de soulignement.

p.{7}(..)?P

Enfin, nous trouvons les correspondances. Puisque nous ignorons en passant, les captures ne sont possibles que s'il y a un ppuis un Pdiagonalement en dessous. Dans la chaîne linéaire, cela signifie simplement qu'il doit y avoir 7 ou 9 caractères entre les deux pions. Cela correspond à .{7}(..)?(c.-à-d. Faire correspondre 7 caractères puis, éventuellement, en faire correspondre deux autres).

Une telle étape de correspondance renvoie le nombre de correspondances trouvées.

Martin Ender
la source
Re "Devrait être facilement battable par quelque chose comme Perl où l'expansion des chiffres en chaînes d'espaces (ou d'autres caractères) ne prend pas 17 octets.": Je ne peux pas faire en sorte que Perl égalise votre score, encore moins le battre . ( Ma réponse Perl. ) Mais peut-être que quelqu'un d'autre peut ....
msh210
3

Javascript, 272 caractères

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

Il y a probablement beaucoup de place pour l'amélioration.

Najkin
la source
3

Rubis, 145 123 46 octets

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

Je ne sais pas pourquoi je n'y ai pas pensé en premier lieu. C'est beaucoup plus court et aussi assez lisible.

Voici le test: http://ideone.com/Gzav8N


L'ancienne approche:

->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 en ligne: http://ideone.com/9L01lf , version avant le golf: http://ideone.com/CSmqlW

Un historique des modifications est disponible ici .

Cristian Lupascu
la source
2

ES6, 64 octets

Un nombre d'octets approprié, s'il dure!

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

En fait, j'ai pensé à cette solution sans lire les autres réponses au préalable, mais cela ne me dérangera pas si vous ne me croyez pas.

Neil
la source
0

Perl 5, 30 octets

29, plus 1 pour -peau lieu de-e

s/\d/1x$&/ge;$_=/p.{7}(..)?P/

Une copie Perl de la réponse Ruby de w0lf .

msh210
la source
0

PHP, 94 87 80 octets

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

Cette boucle + strtrest beaucoup plus courte preg_replace_callbackqu'avec str_pad.

Titus
la source
0

Gelée, 88 84 79 72 69 65 64 63 60 octets

Certainement matière à amélioration. Pas de compétition car Jelly a été créée avant la question. Merci à @lirtosiast de me l'avoir dit!

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