fundo
Um triângulo pitagórico é um triângulo retângulo em que cada comprimento lateral é um número inteiro (ou seja, os comprimentos laterais formam um triplo pitagórico ):
Usando os lados deste triângulo, podemos anexar mais dois triângulos pitagóricos não congruentes da seguinte maneira:
Podemos continuar com esse padrão como acharmos melhor, desde que não haja dois triângulos sobrepostos e os lados de conexão tenham o mesmo comprimento:
A questão é: quantos triângulos pitagóricos não congruentes podemos encaixar em um determinado espaço?
A entrada
Você receberá dois números inteiros como entrada W
e H
, através de argumentos de função, STDIN, strings ou o que quiser. Os números inteiros podem ser recebidos como decimal, hexadecimal, binário, unário (boa sorte, retina ) ou qualquer outra base inteira. Você pode assumir isso max(W, H) <= 2^15 - 1
.
A saída
Seu programa ou função deve calcular uma lista de triângulos pitagóricos não congruentes não sobrepostos e gerar uma lista de conjuntos de três coordenadas cada, em que as coordenadas de um conjunto formam um dos triângulos pitagóricos quando conectados por linhas. As coordenadas devem ser números reais em nosso espaço ( x
devem estar no intervalo [0, W]
e y
devem estar no intervalo [0, H]
) e a distância deve ser precisa para a precisão da máquina. A ordem dos triângulos e o formato exato de cada coordenada não são importantes.
Deve ser possível "caminhar" de um triângulo para outro, apenas passando por cima dos limites conectados.
Usando o diagrama acima, como um exemplo, deixar a entrada ser W = 60
, H = 60
.
Nossa saída pode ser a seguinte lista de coordenadas:
(0, 15), (0, 21), (8, 15)
(0, 21), (14.4, 40.2), (8, 15)
(0, 15), (8, 0), (8, 15)
(8, 0), (8, 15), (28, 15)
(8, 15), (28, 15), (28, 36)
(28, 15), (28, 36), (56, 36)
Agora, 6 triângulos certamente não é o melhor que podemos fazer, dado o nosso espaço. Você pode fazer melhor?
Regras e Pontuação
Sua pontuação para este desafio é o número de triângulos que seu programa gera, considerando a entrada de
W = 1000, H = 1000
. Reservo-me o direito de alterar essa entrada se suspeitar que alguém codifique esse caso.Você não pode usar componentes internos que calculam triplos pitagóricos e não pode codificar uma lista com mais de 2 triplos pitagóricos (se você codifica seu programa para sempre começar com um triângulo (3, 4, 5) ou alguma circunstância inicial semelhante, que esta bem).
Você pode escrever sua submissão em qualquer idioma. Legibilidade e comentários são incentivados.
Você pode encontrar uma lista de triplos pitagóricos aqui .
As brechas padrão não são permitidas.
fonte
Respostas:
Python 3, 109
Este foi certamente um desafio enganosamente difícil. Muitas vezes, escrevendo o código, me vi questionando minhas habilidades básicas de geometria. Dito isto, estou muito feliz com o resultado. Não faço nenhum esforço para criar um algoritmo complexo para a colocação dos triângulos, e, em vez disso, meu código simplesmente falha sempre colocando o menor que pode encontrar. Espero poder melhorar isso mais tarde, ou minha resposta rejeitará outras pessoas a encontrar um algoritmo melhor! Em suma, um problema muito divertido, e produz algumas fotos interessantes.
Aqui está o código:
Aqui está um gráfico da saída para
W = 1000
eH = 1000
com 109 triângulos:Aqui está
W = 10000
eH = 10000
com 724 triângulos:Chame a
matplotlib_graph()
função depoisbuild_all_triangles()
para representar graficamente os triângulos.Eu acho que o código corre razoavelmente rápido: em
W = 1000
eH = 1000
leva 0,66 segundos, e emW = 10000
eH = 10000
leva 45 segundos usando meu laptop de baixa qualidade.fonte
C ++, 146 triângulos (parte 1/2)
Resultado como imagem
Descrição do algoritmo
Isso usa uma pesquisa abrangente do espaço da solução. Em cada etapa, ele começa com todas as configurações exclusivas de
k
triângulos que cabem na caixa e cria todas as configurações exclusivas dek + 1
triângulos, enumerando todas as opções de adição de um triângulo não utilizado a qualquer uma das configurações.O algoritmo é basicamente configurado para encontrar o máximo absoluto com um BFS exaustivo. E faz isso com sucesso para tamanhos menores. Por exemplo, para uma caixa de 50x50, encontra o máximo em cerca de 1 minuto. Mas para 1000 x 1000, o espaço da solução é muito grande. Para permitir que ele termine, aparei a lista de soluções após cada etapa. O número de soluções mantidas é fornecido por um argumento de linha de comando. Para a solução acima, foi utilizado um valor de 50. Isso resultou em um tempo de execução de cerca de 10 minutos.
O esboço das etapas principais é semelhante a este:
Um aspecto crítico em todo o esquema é que as configurações geralmente são geradas várias vezes, e estamos interessados apenas em configurações exclusivas. Portanto, precisamos de uma chave exclusiva que defina uma solução, que deve ser independente da ordem dos triângulos usados ao gerar a solução. Por exemplo, o uso de coordenadas para a chave não funcionaria, pois elas podem ser completamente diferentes se chegarmos à mesma solução em vários pedidos. O que eu usei é o conjunto de índices de triângulo na lista global, além de um conjunto de objetos "conector" que definem como os triângulos são conectados. Portanto, a chave codifica apenas a topologia, independentemente da ordem e posição da construção no espaço 2D.
Embora seja um aspecto de implementação, outra parte que não é inteiramente trivial é decidir se e como a coisa toda se encaixa na caixa especificada. Se você realmente deseja ultrapassar os limites, é obviamente necessário permitir que a rotação caiba dentro da caixa.
Tentarei adicionar alguns comentários ao código na parte 2 mais tarde, caso alguém queira mergulhar nos detalhes de como tudo isso funciona.
Resultado em formato de texto oficial
Código
Veja a parte 2 para o código. Isso foi dividido em duas partes para solucionar os limites de tamanho da postagem.
O código também está disponível no PasteBin .
fonte
C ++, 146 triângulos (parte 2/2)
Continuação da parte 1. Isso foi dividido em duas partes para solucionar os limites de tamanho da postagem.
Código
Comentários a serem adicionados.
fonte