Contexte
Un triangle de Pythagore est un triangle rectangle où chaque longueur de côté est un entier (c'est-à-dire que les longueurs de côté forment un triple de Pythagore ):
En utilisant les côtés de ce triangle, nous pouvons attacher deux autres triangles de Pythagore non congruents comme suit:
Nous pouvons continuer avec ce motif comme bon nous semble, tant qu'il n'y a pas deux triangles qui se chevauchent et que les côtés de connexion ont une longueur égale:
La question est, combien de triangles de Pythagore non congruents pouvons-nous tenir dans un espace donné?
L'entrée
Vous recevrez deux entiers en entrée W
et H
, via les arguments de fonction, STDIN, des chaînes ou tout ce que vous voulez. Les entiers peuvent être reçus sous forme décimale, hexadécimale, binaire, unaire (bonne chance, rétine ) ou toute autre base entière. Vous pouvez supposer cela max(W, H) <= 2^15 - 1
.
Le résultat
Votre programme ou fonction doit calculer une liste de triangles de Pythagore non congruents connectés qui ne se chevauchent pas et produire une liste d'ensembles de trois coordonnées chacun, où les coordonnées dans un ensemble forment l'un des triangles de Pythagore lorsqu'elles sont connectées par des lignes. Les coordonnées doivent être des nombres réels dans notre espace ( x
doivent être dans l'intervalle [0, W]
et y
doivent être dans l'intervalle [0, H]
), et la distance doit être précise selon la précision de la machine. L'ordre des triangles et le format exact de chaque coordonnée ne sont pas importants.
Il doit être possible de «marcher» d'un triangle à un autre en franchissant uniquement les frontières connectées.
En utilisant le diagramme ci - dessus à titre d'exemple, que notre entrée soit W = 60
, H = 60
.
Notre sortie pourrait alors être la liste de coordonnées suivante:
(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)
Maintenant, 6 triangles n'est certainement pas le meilleur que nous puissions faire étant donné notre espace. Pouvez-vous faire mieux?
Règles et notation
Votre score pour ce défi est le nombre de triangles générés par votre programme en fonction de l'entrée
W = 1000, H = 1000
. Je me réserve le droit de modifier cette entrée si je soupçonne quelqu'un de coder en dur cette affaire.Vous ne pouvez pas utiliser de commandes intégrées qui calculent des triplets de Pythagore, et vous ne pouvez pas coder en dur une liste de plus de 2 triplets de Pythagore (si vous codez en dur votre programme pour toujours commencer par un triangle (3, 4, 5) ou une autre circonstance de départ similaire, qui est correct).
Vous pouvez rédiger votre soumission dans n'importe quelle langue. La lisibilité et les commentaires sont encouragés.
Vous pouvez trouver une liste de triplets pythagoriciens ici .
Les échappatoires standard ne sont pas autorisées.
la source
Réponses:
Python 3, 109
C'était certainement un défi trompeusement difficile. Il y a eu plusieurs fois en écrivant le code que je me suis retrouvé à remettre en question mes capacités de base en géométrie. Cela étant dit, je suis assez content du résultat. Je n'ai fait aucun effort pour trouver un algorithme complexe pour placer les triangles, et à la place, mon code se contente de toujours placer le plus petit qu'il puisse trouver. J'espère pouvoir améliorer cela plus tard, ou ma réponse en repoussera d'autres pour trouver un meilleur algorithme! Dans l'ensemble, c'est un problème très amusant et cela produit des images intéressantes.
Voici le code:
Voici un graphique de la sortie pour
W = 1000
etH = 1000
avec 109 triangles:Voici
W = 10000
etH = 10000
avec 724 triangles:Appeler le
matplotlib_graph()
fonction aprèsbuild_all_triangles()
pour représenter graphiquement les triangles.Je pense que le code fonctionne assez rapidement: à
W = 1000
etH = 1000
cela prend 0,66 seconde, et àW = 10000
etH = 10000
cela prend 45 secondes en utilisant mon ordinateur portable merdique.la source
C ++, 146 triangles (partie 1/2)
Résultat comme image
Description de l'algorithme
Cela utilise une recherche en premier lieu de l'espace de la solution. À chaque étape, il commence par toutes les configurations uniques de
k
triangles qui tiennent dans la boîte et crée toutes les configurations uniques dek + 1
triangles en énumérant toutes les options d'ajout d'un triangle inutilisé à l'une des configurations.L'algorithme est essentiellement configuré pour trouver le maximum absolu avec un BFS exhaustif. Et il le fait avec succès pour les petites tailles. Par exemple, pour une boîte de 50x50, il trouve le maximum en 1 minute environ. Mais pour 1000x1000, l'espace de la solution est beaucoup trop grand. Pour lui permettre de se terminer, je coupe la liste des solutions après chaque étape. Le nombre de solutions conservées est donné par un argument de ligne de commande. Pour la solution ci-dessus, une valeur de 50 a été utilisée. Cela a entraîné un temps d'exécution d'environ 10 minutes.
Le contour des principales étapes ressemble à ceci:
Un aspect critique de l'ensemble du système est que les configurations seront généralement générées plusieurs fois, et nous ne nous intéressons qu'aux configurations uniques. Nous avons donc besoin d'une clé unique qui définit une solution, qui doit être indépendante de l'ordre des triangles utilisés lors de la génération de la solution. Par exemple, l'utilisation de coordonnées pour la clé ne fonctionnerait pas du tout, car elles peuvent être complètement différentes si nous arrivons à la même solution dans plusieurs commandes. Ce que j'ai utilisé, c'est l'ensemble des indices de triangle dans la liste globale, plus un ensemble d'objets «connecteurs» qui définissent comment les triangles sont connectés. Ainsi, la clé code uniquement la topologie, indépendamment de l'ordre de construction et de la position dans l'espace 2D.
Bien qu'il s'agisse davantage d'un aspect de mise en œuvre, une autre partie qui n'est pas entièrement triviale consiste à décider si et comment le tout s'intègre dans la boîte donnée. Si vous voulez vraiment repousser les limites, il est évidemment nécessaire de permettre une rotation pour s'adapter à l'intérieur de la boîte.
Je vais essayer d'ajouter quelques commentaires au code dans la partie 2 plus tard, au cas où quelqu'un voudrait se plonger dans les détails de la façon dont tout cela fonctionne.
Résultat au format texte officiel
Code
Voir la partie 2 pour le code. Cela a été divisé en 2 parties pour contourner les limites de taille des messages.
Le code est également disponible sur PasteBin .
la source
C ++, 146 triangles (partie 2/2)
Suite de la partie 1. Cela a été divisé en 2 parties pour contourner les limites de taille des messages.
Code
Commentaires à ajouter.
la source