O jogo
Nim é um jogo de estratégia matemática, onde 2 jogadores se revezam retirando itens de montes distintos. Por sua vez, você deve pegar pelo menos um item e pode pegar quantos quiser, desde que você pegue apenas um monte. O jogador que pega o último item ganha! Este é um jogo resolvido. Antes de eu entrar na estratégia, você pode tentar jogá-la online aqui .
A estratégia
A estratégia vencedora é explicada com muita clareza e simplicidade aqui neste link. Vou explicar usando termos um pouco mais técnicos. A maneira de ganhar este jogo é sempre levar o máximo de itens possível para que a soma digital-binária seja sempre 0. Considere o seguinte quadro:
*
* *
* * *
* * * *
* * * * *
1 2 3 4 5
Para encontrar a soma digital-binária desta placa, você deve:
Converta o número em cada linha para binário. Portanto, temos 001, 010, 011, 100 e 101.
Adicione todos os números juntos e ignore qualquer transporte.
001 010 011 100 +101 ---- 001
Você também pode bit a bit xor cada número, e isso alcançará o mesmo resultado.
Agora, se a soma nesta configuração atual for 001, então este ainda não é um quadro vencedor. Mas você pode torná-lo um quadro vencedor! Se retirarmos um item das colunas 1, 3 ou 5, a soma será 0. Este é um tabuleiro vencedor, o que significa que, desde que você não cometa um erro, o próximo jogador a perder perderá. Portanto, você deve sempre terminar seu turno com um quadro vencedor. Digamos que você retire um item da coluna 5. Agora o quadro fica assim:
* *
* * *
* * * *
* * * * *
1 2 3 4 5
Contanto que você não estrague tudo, você tem uma vitória garantida. Não há nada que seu oponente possa fazer para impedi-lo. Vamos dizer que ele pega todos os itens da coluna 5.
*
* *
* * *
* * * *
1 2 3 4 5
Onde você iria a seguir? Não role para baixo ainda e tente descobrir por si mesmo.
No momento, a soma é 100. A melhor jogada (e a única jogada vencedora) seria pegar tudo da coluna 4. Isso deixaria o quadro assim:
*
* *
* * *
1 2 3 4 5
e a soma assim
001
010
+011
----
000
isso significa que você está em um tabuleiro vencedor! Yay!
O desafio
Você deve escrever um programa ou função que, dado um quadro nim, retorne uma jogada vencedora ou um valor falsey se não houver uma jogada vencedora.
Sua entrada:
Será o formato de lista nativa do seu idioma, onde cada item da lista corresponde ao número de itens em uma determinada coluna. Por exemplo, a entrada {4, 2, 1, 0, 3} corresponde ao seguinte quadro nim:
* * * * * * * * * * 1, 2, 3, 4, 5
(opcional) O número de linhas. (Para idiomas como C / C ++, onde isso não é conhecido na própria lista.)
Sua saída:
Pode ir para STDOUT ou retornar da função
Deve haver dois números: 1) a coluna da qual estamos removendo (lembre-se de que as colunas são indexadas em 0) e 2) o número de itens a serem removidos dessa linha. Pode ser uma matriz de dois itens, uma sequência de dois números, etc. Lembre-se de que a resposta pode ter mais de 2 dígitos, portanto, retornar a sequência "111" não é válida porque não está claro se isso significa "Remover um item da coluna onze" ou "Remover onze itens da coluna um". "1,11" ou "11,1" seriam ambos aceitáveis.
Se não houver resposta, retorne ou imprima um valor falso. Se o seu idioma puder retornar apenas um tipo de variável (novamente, como C / C ++), um número negativo para a coluna ou 0 ou menos para o número a ser removido serão valores aceitáveis de falsey.
Se o número da coluna ou o número a remover for muito grande, isso será visto como uma saída inválida.
Amostras de entradas / saídas
[1, 2, 3, 4, 5]
---> [0, 1]
ou [4, 1]
ou[2, 1]
[1, 3, 5, 6]
---> [0, 1]
ou [1, 1]
ou[2, 1]
[1, 2, 0, 0, 5]
---> [4, 2]
[1, 2, 3]
---> ERROR
Se você optar por executar uma função em vez do programa completo, deverá escrever um programa completo para demonstrar a função em ação. Isso não conta para a sua pontuação completa. Além disso, espera-se que os programas sejam executados em um período de tempo razoável. Não estou planejando inserir entradas excessivamente grandes; portanto, enquanto seu programa não estiver fazendo uma pesquisa de força bruta por toda a árvore do jogo, você deverá ficar bem.
Como de costume, isso é código-golfe, então as lacunas padrão se aplicam e as respostas são contadas em bytes.
Entre os melhores
Aqui está um snippet de pilha para gerar uma classificação regular e uma visão geral dos vencedores por idioma.
Para garantir que sua resposta seja exibida, inicie-a com um título, usando o seguinte modelo de remarcação:
# Language Name, N bytes
onde N
está o tamanho do seu envio. Se você melhorar sua pontuação, poderá manter as pontuações antigas no título, identificando-as. Por exemplo:
# Ruby, <s>104</s> <s>101</s> 96 bytes