Seu objetivo é escrever um jogador perfeito para o jogo de Nim de Wythoff .
Regras do Nim de Wythoff
O Nim de Wythoff é um jogo determinístico para dois jogadores, jogado com duas pilhas de marcadores idênticos. Os jogadores alternam turnos, nos quais realizam um destes procedimentos:
- Remova um ou mais contadores da primeira pilha
- Remova um ou mais contadores da segunda pilha
- Remova um número igual de contadores (um ou mais), da primeira pilha e da segunda pilha.
Obviamente, as pilhas não podem ser negativas, mas podem chegar a 0. Qualquer jogador que remover o último contador geral vence o jogo.
Para os mais geométricos, aqui está uma formulação equivalente do jogo que você pode jogar neste applet . Uma única rainha começa em algum quadrado de um tabuleiro de xadrez infinito, cujo canto fica no canto inferior esquerdo. Os jogadores alternam a mudança da rainha, que se move como uma rainha do xadrez, mas restrita a três direções:
- Baixa
- Esquerda
- Na diagonal para baixo e para a esquerda
Quem leva a rainha para o canto ganha.
Associando as coordenadas da rainha (com canto (0,0)
) ao tamanho das respectivas pilhas, é fácil ver os dois jogos iguais.
Jogo perfeito
(Você pode pular isso se estiver familiarizado com as noções de jogo perfeito e movimentos vencedores.)
Como o Nim de Wythoff é um jogo finito e determinístico, ele tem uma noção de jogo perfeito . Um jogador perfeito é uma estratégia que sempre vencerá de uma posição conquistada teoricamente, ou seja, uma posição em que exista uma estratégia que garanta uma vitória.
Para ser uma estratégia vencedora, basta mudar para sempre passar para uma posição teórica de vitória para o jogador que acabou de se mudar e, portanto, o jogador não vai para a próxima. A primeira dessas posições vencedoras (também chamadas de posições frias ) é (0,0), (1,2), (2,1), (3,5), (5,3)
. Consulte o artigo da Wikipedia para obter uma explicação de um algoritmo para encontrar uma estratégia vencedora para o Nim da Wythoff, bem como uma fórmula para gerar posições de vitória.
Requisitos do programa
Escrever um programa ou função toma uma posição como entrada e produz um movimento vencedor na forma da posição após esse movimento. Menos bytes ganha.
Se não houver movimento vencedor, ou seja, a posição é uma perda teórica, seu programa deve indicar isso e perder.
Seu programa deve ser executado dentro de um período de tempo razoável. Portanto, uma pesquisa de árvore de jogo recursiva exponencial não será suficiente. Se você quiser pré-calcular e codificar uma estratégia, tudo bem.
Entrada
Um par (i,j)
de números não negativos representando tamanhos de pilha, cada um no máximo 99
. Podem ser dois números, uma tupla, uma lista ou qualquer contêiner que você preferir.
Resultado
Imprima ou produza a posição após a sua mudança, novamente como dois números ou um contêiner. Isso deve ser uma mudança legal para uma posição vencedora. Se houver vários desses movimentos, qualquer um está bem, mas apenas um.
Se não houver movimento vencedor, você deve indicar isso na saída. Qualquer saída como False
, None
0 ou (-1,-1)
funcionará, desde que não seja uma posição legal e seja a mesma para todas as entradas perdidas.
Execuções de exemplo
f(5,0) = (0,0)
f(2,2) = (1,2) # Or (2,1) or (0,0)
f(1,2) = False
f(13,9) = (13,8) # Or (10,6)
f(10,6) = False
f(5,10) = (5,3)
f(25,30) = (8,13)