Captura no tabuleiro de xadrez de peões

17

Você deve escrever um programa ou função que receba uma string representando um tabuleiro de xadrez com apenas peões como entrada e saída ou retorne se é possível capturar qualquer placa no tabuleiro.

A entrada está em uma notação semelhante à FEN , descrevendo posições de peões brancos e pretos sem outras peças presentes. Você deve decidir se existe um peão que possa capturar um inimigo.

Cada classificação é descrita, começando com a classificação 8 e terminando com a classificação 1; dentro de cada classificação, o conteúdo de cada quadrado é descrito do arquivo "a" ao arquivo "h". Cada peão é identificado por uma única letra (peão branco = "P", peão preto = "p"). Os quadrados vazios são anotados usando os dígitos de 1 a 8 (o número de quadrados vazios) e "/" separa as classificações. (parcialmente retirado da Wikipedia)

Por exemplo

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

descreve o quadro

--------

pppppppp


    P   

PPPP PPP

--------

Um peão branco pode capturar um preto se o preto estiver posicionado na diagonal para cima (o preto é para cima esquerdo ou para a direita) e um peão preto pode capturar um branco se o branco estiver diagonalmente abaixo dele (o branco é baixo-esquerda ou baixo-direita). Nenhum outro movimento de captura ( em passante ) deve ser considerado.

Entrada

  • Uma sequência semelhante a FEN que consiste nos caracteres 12345678pP/.
  • A entrada descreve os peões de uma posição válida no jogo de xadrez. Isso significa (entre outras restrições mais complexas) que haverá no máximo 8 peões para cada lado e nenhum peão nas fileiras 1 e 8.

Resultado

  • Se há uma possível captura para cada lado você deve saída um truthy valor e um Falsas valor de outra forma.

Exemplos

Entradas com saída de verdade (uma por linha)

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

Entradas com saída falsa (uma por linha)

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

Este é um código de golfe, portanto a entrada mais curta vence.

randomra
fonte
O quadro de exemplo não deve ser descrito por 8/pppppppp/8/8/8/7P/PPPP1PPP/8?
TheNumberOne
@TheNumberOne Não, 7Psignifica que o peão está no último, oitavo arquivo. (O diagrama foi embora incorrecta, eu que corrigido.)
randomra
11
Sinto que remover en passant torna esse quebra-cabeça menos interessante.
precisa saber é o seguinte

Respostas:

6

Pitão, 25 bytes

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

Suíte de teste

Passos:

Transforme a entrada substituindo os dígitos pelo número equivalente de aspas ( N). Isso é salvo em J. Em seguida, cortamos os primeiros 8 ou 10 caracteres e compactamos o resultado com o original. Qualquer par de captura será transformado em "Pp", portanto, encontraremos a contagem dessa sequência na lista resultante. Essa é a saída.

Como um bônus, isso realmente conta o número de capturas possíveis na entrada.

isaacg
fonte
Outra solução 25: :sXz`M9*LN9"p.{7}(..)?P"1Infelizmente, o último parâmetro de :não é opcional (acho que deveria ser).
Jakube
3
@Jakube Will.
Isaacg
12

Retina , 33 29 bytes

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

p.{7}(..)?P

Para executar o código de um único arquivo, use o -ssinalizador

Deve ser facilmente superável por algo como Perl, onde a expansão de dígitos em cadeias de espaços (ou outros caracteres) não ocupa 17 bytes.

A saída é positiva (verdade) se houver uma captura possível e zero (falso) se não houver.

Explicação

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

Este é um loop de dois estágios. O primeiro é um estágio de transliteração que diminui cada dígito e transforma zeros em sublinhados. Por quê? Porque de wexpanda para as duas linhas a seguir:

0123456789
_0123456789AB...YZab...yz

Se o conjunto de destino de um estágio de transliteração for maior que o conjunto de origem, os caracteres estranhos serão ignorados, daí o comportamento decrescente (honestamente, foi uma sorte que eu decidisse colocar o sublinhado na frente dos dígitos ao expandir a wclasse de caracteres) .

Em seguida, o segundo estágio é uma substituição, que anexa a .a cada dígito. Isso significa que, para cada dígito n, os nperíodos são adicionados antes que esse dígito seja transformado em um sublinhado.

_
<empty>

Isso apenas elimina os sublinhados.

p.{7}(..)?P

Finalmente, encontramos as correspondências. Como estamos ignorando en passant, as capturas só são possíveis se houver um pe depois um na Pdiagonal abaixo dele. Na cadeia linear, isso significa simplesmente que deve haver 7 ou 9 caracteres entre os dois peões. Isso corresponde a .{7}(..)?(ou seja, corresponde a 7 caracteres e, opcionalmente, corresponde a outros dois).

Esse estágio de correspondência retorna o número de correspondências encontradas.

Martin Ender
fonte
Re "Deveria ser facilmente superável por algo como Perl, onde a expansão de dígitos em cadeias de espaços (ou outros caracteres) não ocupa 17 bytes.": Não consigo fazer com que Perl atinja sua pontuação, muito menos vencê-la. . ( Resposta Meu Perl. ) Mas talvez alguém pode ....
msh210
3

Javascript, 272 caracteres

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

Provavelmente há muito espaço para melhorias.

Najkin
fonte
3

Ruby, 145 123 46 bytes

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

Não sei por que não pensei nisso em primeiro lugar. É muito mais curto e também bastante legível.

Aqui está o teste: http://ideone.com/Gzav8N


A abordagem antiga:

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

Teste online: http://ideone.com/9L01lf , versão antes do golfe: http://ideone.com/CSmqlW

Um histórico de modificações está disponível aqui .

Cristian Lupascu
fonte
2

ES6, 64 bytes

Uma contagem de bytes apropriada, se durar!

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

Na verdade, pensei nessa solução sem ler as outras respostas primeiro, mas não me importarei se você não acreditar em mim.

Neil
fonte
0

Perl 5, 30 bytes

29, mais 1 para em -pevez de-e

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

Uma cópia Perl da resposta Ruby de w0lf .

msh210
fonte
0

PHP, 94 87 80 bytes

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

Esse loop + strtré muito mais curto que preg_replace_callbackcom str_pad.

Titus
fonte
0

Geléia, 88 84 79 72 69 65 64 63 60 bytes

Definitivamente espaço para melhorias. Não-competitivo porque o Jelly foi criado antes da pergunta. Obrigado a @lirtosiast por me dizer isso!

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