Você se encontra em um tabuleiro de xadrez, como se faz. Você pode ver a saída, mas é muito longe e você prefere não andar até o fim. Felizmente, alguns locais ofereceram uma carona. Um cavaleiro, uma torre, um bispo e um rei estão todos dispostos a levá-lo ao seu destino, mas, vendo como este é um tabuleiro de xadrez, cada um deve respeitar as regras do xadrez no caminho para o seu destino. Gostaria de sair daqui o mais rápido possível, cuja oferta você aceita?
Tarefa
Dado um tabuleiro de xadrez de tamanho e formato arbitrário e dois pontos no tabuleiro, produza a peça de xadrez que pode se mover entre os dois locais no menor número de movimentos possível. Os painéis não serão necessariamente contínuos, o que significa que pode haver lacunas entre as seções do painel. Cada uma das quatro peças (rei, torre, cavaleiro e bispo) pode se mover de acordo com suas regras padrão no xadrez. As peças da rainha e do peão foram intencionalmente deixadas de fora desse desafio.
I / O
Você pode receber entradas em qualquer formato razoável e também pode imprimir em qualquer formato que escolher. Sua entrada e saída devem ser autoconsistentes. Se várias peças puderem chegar ao destino com o mesmo número de movimentos, você deverá produzir todas as peças que podem chegar lá no período mínimo de tempo. Se nenhuma das quatro peças chegar ao fim, você poderá produzir qualquer coisa, desde que seja distinto de todas as outras saídas possíveis. Isso pode incluir não produzir nada ou gerar um erro.
Casos de teste
Um quadrado indica o ponto inicial e um círculo indica o ponto final.
Bispo
Cavaleiro
Rei
Torre
Cavaleiro Rei
Nenhum
Respostas:
Haskell ,
447439437432 bytesLigue usando
g <board> <start> <end>
onde<board> :: [(Int, Int)]
,<start> :: (Int, Int)
e<end> :: (Int, Int)
. Retorna uma lista contendo1
Knight,2
Rook,3
Bishop e4
King. Se nenhuma solução for encontrada, ela transborda consistentemente a pilha (que conta como um erro, certo?).A inspiração tirada dos capítulos de LYAH sobre Mônadas -
(%)
é apenas uma generalização e um jogo de golfeinMany
, com o(&)
equivalente a(Control.Monad.<=<)
. Tudo o resto deve ser mais ou menos auto-explicativo.Provavelmente isso pode ser jogado muito mais, mas já me diverti bastante.
Ungolfed:
fonte
Mathematica,
326325 bytesObrigado a masterX224 por apontar uma economia de bytes!
Define uma função que
f
aceita três argumentos:g
é uma lista de pares ordenados de números inteiros representando o quadrow
ex
pares ordenados e representando os quadrados inicial e final. A saída é o subconjunto de{b, k, n, r}
(representando bispo, rei, cavaleiro e torre, respectivamente) que tem um caminho de movimentos mínimos entre os dois quadrados. Por exemplo, o terceiro caso de teste é invocado porf[{{0, 0}, {1, 1}, {1, 2}, {0, 3}}, {0, 0}, {0, 3}]
e retorna{k}
; os dois últimos casos de teste retornam{k, n}
e{}
, respectivamente.A estratégia é converter os quadrados do tabuleiro em vértices de um gráfico, onde as arestas são determinadas pelos movimentos de cada peça e, em seguida, usar rotinas gráficas incorporadas.
Versão mais amigável do código:
Na linha 3,
Select[g~Tuples~2, # - #2 & @@ # == d
encontra todos os pares ordenados de vértices cuja diferença é o vetord
;e
depois, transforma cada par ordenado em uma aresta do gráfico não direcionada. Assima
é uma função que cria arestas entre todos os vértices que diferem por um vetor fixo.Isso é suficiente para definir, nas linhas 4 e 5, o gráfico de rei
y@k
(o que leva a união de bordas gerados pelos vectores{1, 1}
,{-1, 1}
,{0, 1}
, e{-1, 0}
) e gráfico do cavaleiroy@n
(que faz o mesmo com{1, 2}
,{2, 1}
,{-2, 1}
, e{-1, 2}
).Na linha 7,
ConnectedComponents@a@#
pega um desses gráficos vizinhos e encontra seus componentes conectados; isso corresponde ao agrupamento de todos os segmentos de linha dos vértices na direção especificada (para que uma torre ou bispo não precise passar por eles um por um). Entãoe@t@#
na linha 6 coloca arestas entre cada par de vértices no mesmo componente conectado, que são entãoFlatten
editados em um único gráfico. Assim, as linhas 6 a 8 definem o gráfico da torrey@r
e o gráfico do bispoy@b
.Finalmente, as linhas 9 a 11 escolhem os elementos
{b, k, n, r}
que produzem o caminho mais curto entre os dois vértices de destino.FindShortestPath
lançará um erro e retornará sem avaliação se um vértice de destino não aparecer no gráfico (o que acontecerá se nenhuma borda emanar dele), então usamosh@__ -> 0
para retornar0
nesses casos. E a falta de um caminho entre vértices válidos retorna uma lista de comprimento0
,Min[z~Complement~{0}]
calcula o comprimento do menor caminho que realmente existe, ignorando os casos ruins acima.fonte
f
nessa sessão, mas deveria ter mudado antes da submissão!