Introdução
Esse desafio é semelhante aos problemas do Project Euler . Eu o criei porque estava jogando um jogo de tabuleiro enganosamente simples e não consegui encontrar uma solução eficiente para responder a uma pergunta simples sobre sua mecânica.
Quarto é uma variante divertida de 4 em uma fileira. É jogado em um tabuleiro 4 por 4 com 16 peças únicas (nenhuma peça é duplicada). A cada turno, cada jogador coloca 1 peça no tabuleiro. Cada peça possui 4 características binárias (baixa / alta, preta / branca, quadrada / circular, oca / sólida). O objetivo é fazer quatro em linha, horizontalmente, verticalmente ou ao longo das 2 diagonais, para qualquer uma das quatro características! Então, 4 peças pretas, 4 peças brancas, 4 peças altas, 4 peças curtas, 4 peças quadradas, 4 peças circulares, 4 peças ocas ou 4 peças sólidas.
A imagem acima mostra um jogo terminado, há quatro em sequência por causa de quatro peças quadradas.
Desafio
No Quarto, alguns jogos podem terminar empatados.
O número total de posições finais possíveis é de 16!
cerca de 20 trilhões.
Quantas dessas posições finais são empates?
Regras
A solução deve ser um programa que calcule e produz o número total de posições finais que são desenhadas. A resposta correta é
414298141056
Você só pode usar informações das regras do jogo que foram deduzidas manualmente (nenhuma prova assistida por computador).
Simplificações matemáticas do problema são permitidas, mas devem ser explicadas e comprovadas (manualmente) na sua solução.
O vencedor é aquele com a solução mais ideal em termos de tempo de execução da CPU.
Para determinar o vencedor, executarei todas as soluções com um tempo de execução relatado menor que 30m em um MacBook Pro 2,5 GHz Intel Core i7 com 16 GB de RAM .
Não há pontos de bônus por encontrar uma solução que também funcione com outros tamanhos de tabuleiro. Mesmo que isso seria legal.
Se aplicável, seu programa deve compilar dentro de 1 minuto no hardware mencionado acima (para evitar abuso de otimização do compilador)
As brechas padrão não são permitidas
Submissões
Por favor, poste:
- O código ou um link do github / bitbucket para o código.
- A saída do código.
- Seu tempo de execução medido localmente
- Uma explicação da sua abordagem.
Data limite
O prazo final para as inscrições é 1 de março, portanto, ainda há bastante tempo.
Respostas:
C: 414298141056 empates encontrados em cerca de
52,5 minutos.Pesquisa simples e profunda com uma tabela de transposição com reconhecimento de simetria. Utilizamos a simetria dos atributos sob permutação e a simetria diédrica de 8 vezes do quadro.
Pontuação medida (@wvdz):
Pontuação (usuário + sistema): 1m35.727s
fonte
-O3 -march=native
e consegui 1m48s na minha máquina. (CC @wvdz)Java, 414298141056 empates, 23m42.272s
Espero que não seja desagradável postar uma solução para o próprio desafio, mas a razão pela qual eu publiquei esse desafio foi que me enlouqueceu por não ter conseguido encontrar uma solução eficiente. Minha melhor tentativa levaria dias para ser concluída.
Depois de estudar a resposta do usuário1502040 , consegui modificar meu código para rodar dentro de um prazo razoável. Minha solução ainda é significativamente diferente, mas roubei algumas idéias:
A principal diferença entre essa solução e a de user1502040 é que não uso uma tabela Zobrist, mas uma representação canônica de uma placa, na qual considero que cada placa possui 48 transposições possíveis sobre as características (2 * 4!). Não giro ou transpo o tabuleiro inteiro, mas apenas as características das peças.
Este é o melhor que eu poderia inventar. Idéias para otimizações óbvias ou menos óbvias são bem-vindas!
Pontuação medida:
Pontuação (usuário + sistema): 23m42.272s
fonte