Il s'agit du deuxième des deux défis liés à la "traction des fonctions". Voici la partie I légèrement plus simple .
Insérons m clous dans une planche aux positions (x 1 , y 1 ) à (x m , y m ) . Attachez une bande de caoutchouc au premier et au dernier de ceux-ci et étirez-vous autour des autres ongles, de sorte que la bande traverse tous les ongles dans l'ordre. Notez que l'élastique décrit maintenant une fonction paramétrée linéaire par morceaux (x (t), y (t)) dans l'espace 2D.
Maintenant , un autre disque n clous dans la plaque, à des positions (x 1 , y 1 ) à (x n , y n ) . Si nous retirons maintenant tous les originaux m clous , sauf le premier et le dernier (dont les extrémités du caoutchouc est liée à), la bande de caoutchouc raccourcira jusqu'à ce qu'il soit allongé tendu autour des nouveaux clous, ce qui donne une autre linéaire par morceaux fonction.
Par exemple, prenez m = 12 clous initiaux aux positions (0, 0), (2, -1), (3/2, 4/3), (7/2, 1/3), (11/2, 16/3), (1, 16/3), (0, 1), (7, -2), (3, 4), (8, 1), (3, -1), (11, 0) , et n = 10 autres clous aux positions (1, 1), (3, 1), (4, 4), (1, 3), (2, 2), (5, -1), (5, 0 ), (6, 2), (7, 1), (6, 0) . Les trois graphiques suivants montrent le processus décrit ci-dessus:
Pour une version plus grande: clic droit -> Ouvrir dans un nouvel onglet
Et voici une animation du serrage de l'élastique si vous avez du mal à le visualiser:
Le défi
Étant donné deux listes de "clous", tracez l'élastique tendu autour de la deuxième liste s'il part de la forme traversant tous les clous de la première liste.
Vous pouvez écrire un programme ou une fonction et prendre une entrée via STDIN, ARGV ou un argument de fonction. Vous pouvez soit afficher le résultat à l'écran, soit enregistrer une image dans un fichier.
Si le résultat est tramé, il doit être d'au moins 300 pixels de chaque côté. L'élastique final et les clous doivent couvrir au moins 75% de l'étendue horizontale et verticale de l'image. Les échelles de longueur de x et y doivent être les mêmes. Vous devez montrer les clous dans le deuxième ensemble (en utilisant au moins 3x3 pixels) et la chaîne (au moins 1 pixel de large). Vous pouvez ou non inclure les axes.
Les couleurs sont votre choix, mais vous avez besoin d'au moins deux couleurs distinctes: une pour l'arrière-plan et une pour les ongles et la chaîne (celles-ci peuvent cependant avoir des couleurs différentes).
Vous pouvez supposer que tous les clous de la deuxième liste sont à au moins 10 à 5 unités de la forme initiale de l'élastique (de sorte que vous n'avez pas à vous soucier de l'inexactitude en virgule flottante).
Il s'agit du code golf, donc la réponse la plus courte (en octets) l'emporte.
Plus d'exemples
Voici deux autres exemples:
{{1, 1}, {3, 3}, {2, 4}, {1, 3}, {4, 0}, {3, -1}, {2, 0}, {4, 2}}
{{2, 1}, {3, 2}, {1, 2}, {4, 1}}
{{1, 1}, {3, 1}, {3, 3}, {1, 3}, {1, 5}, {3, 5}, {-1, 3}, {-1, 0}, {3, 4}, {5, 1}, {5, -1}, {7, -1}, {3, 7}, {7, 5}}
{{0, 0}, {0, 2}, {0, 4}, {0, 6}, {2, 0}, {2, 2}, {2, 4}, {2, 6}, {4, 0}, {4, 2}, {4, 4}, {4, 6}, {6, 0}, {6, 2}, {6, 4}, {6, 6}}
Et voici un exemple qui montre l'importance de deux des premiers clous restants. Le résultat doit être b et non a :
{{0, 0}, {0, 1}, {-1, 1}, {-1, -1}, {1, -1}, {1, 0}}
{{-0.5, 0.5}}
Merci à Ell d'avoir fourni cet exemple.
la source
Réponses:
Python + matplotlib, 688
Lit deux listes de points depuis STDIN.
Exemple
Comment ça fonctionne
La clé de la solution est de travailler par petites étapes incrémentielles. Au lieu d'essayer de comprendre ce qui se passe lorsque nous retirons tous les ongles à la fois, nous nous concentrons sur les effets directs de la suppression d'un seul ongle. Nous pouvons ensuite retirer les clous un par un dans un ordre arbitraire.
Travailler progressivement signifie que nous devons garder une trace de l'état intermédiaire de l'élastique. Voici la partie délicate: il ne suffit pas de garder une trace des clous traversés par le groupe. Pendant le processus de retrait des ongles, la bande peut être enroulée et ensuite enroulée autour d'un ongle. Par conséquent, lorsque le groupe interagit avec un clou, nous devons garder une trace du nombre de fois et dans quelle direction il s'enroule autour de lui. Nous le faisons en attribuant une valeur à chaque ongle le long de la bande comme suit:
Notez que:
Nous commençons à compter dès que la bande est tangente à l'ongle, même si l'ongle n'affecte pas strictement sa forme. Rappelons que, contrairement à l'illustration, nos ongles sont sans dimension. Par conséquent, si la bande devient tangente à un clou, nous ne pouvons pas dire de quel côté de la bande le clou est sur sa seule position --- nous devons garder une trace de l'endroit où il était par rapport à la bande.
Nous gardons autour des ongles avec une valeur de zéro, c'est-à-dire des ongles qui autrefois, mais ne tiennent plus la bande, au lieu de les retirer tout de suite. Si nous le faisions, cela pourrait déclencher une réaction en chaîne indésirable, alors que nous essayons de garder les effets de chaque étape localisés. Au lieu de cela, les clous d'une valeur de zéro sont considérés comme éligibles à être retirés dans le cadre d'un processus plus vaste.
Nous pouvons maintenant décrire ce qui se passe à chaque étape:
Nous sélectionnons un clou à retirer du chemin actuel du groupe. Un clou peut être retiré s'il fait partie du premier ensemble de clous (sauf pour les points de terminaison) ou si sa valeur est nulle.
Prétendant que les deux clous voisins sont fixes, nous déterminons quels clous du deuxième ensemble ou la paire de points d'extrémité que la bande traversera une fois le clou sélectionné retiré (nous ne nous soucions pas du reste des clous du premier set, car ils finiront par être tous supprimés.) Nous le faisons de façon similaire à la solution à la partie I . Tous ces clous sont du même côté de la bande, nous attribuons donc à chacun d'eux une valeur de 1 ou -1 , selon le côté.
Nous mettons à jour la valeur des deux clous voisins pour refléter les changements de chemin du groupe (facilement la partie la plus délicate!)
Ce processus est répété jusqu'à ce qu'il n'y ait plus de clous à retirer:
Et voici un exemple plus compliqué illustrant plusieurs fois la bande enroulée autour d'un clou:
la source
Java - 1262 octets
Je sais que ce n'est probablement pas autant joué au golf.
Cependant, personne d'autre ne semble intervenir et répondre à cette question, alors je le ferai.
Tout d'abord, la classe "T" - qui est une classe de points - 57 octets
Et la classe principale - 1205 octets
Exemple:
Pour exécuter, appelez la fonction "d" avec une liste de points et un tableau de clous (ouais, je sais, bizarre). Ce qu'il fait:
Je ne sais pas si les axes en pixels sont corrects. Il occupera toujours plus de 75% de l'espace, il pourrait être vraiment très petit.
Voici une belle animation pour montrer ce que je fais ici:
Finalement, cela devient cela, dans lequel les points bougent à peine. C'est à ce moment-là que je vois quels ongles il touche:
Voici le code d'animation non golfé:
la source