Dies ist die zweite von zwei Herausforderungen zum Thema "Funktionen straffen". Hier ist die etwas einfachere Teil I .
Lassen Sie uns m Nägel an den Positionen (x 1 , y 1 ) bis (x m , y m ) in ein Brett treiben . Binden Sie ein Gummiband an das erste und letzte Band und spannen Sie es um die anderen Nägel, sodass das Band alle Nägel der Reihe nach durchquert. Beachten Sie, dass das Gummiband nun eine stückweise linear parametrisierte Funktion (x (t), y (t)) im 2D-Raum beschreibt.
Fahren Sie nun an den Positionen (x 1 , y 1 ) bis (x n , y n ) weitere n Nägel in die Platine . Wenn wir jetzt alle ursprünglichen entfernen m Nägel mit Ausnahme der ersten und letzten (die die Enden des Gummis gebunden), das Gummiband verkürzt , bis sie straff um die neuen Nägel liegend ist, wodurch man eine andere stückweise lineare Funktion.
Nehmen Sie als Beispiel m = 12 Anfangsnägel an den Positionen (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) und n = 10 weitere Nägel an den Positionen (1, 1), (3, 1), (4, 4), (1, 3), (2, 2), (5, -1), (5, 0) ), (6, 2), (7, 1), (6, 0) . Die folgenden drei Darstellungen zeigen den oben beschriebenen Prozess:
Für größere Version: Rechtsklick -> In neuem Tab öffnen
Und hier ist eine Animation der Gummibandstraffung, wenn Sie Schwierigkeiten haben, sie zu visualisieren:
Die Herausforderung
Zeichnen Sie bei zwei Listen mit "Nägeln" das gespannte Gummiband um die zweite Liste, wenn es von der Form ausgeht, die alle Nägel in der ersten Liste durchläuft.
Sie können ein Programm oder eine Funktion schreiben und Eingaben über STDIN, ARGV oder Funktionsargument vornehmen. Sie können das Ergebnis entweder auf dem Bildschirm anzeigen oder ein Bild in einer Datei speichern.
Wenn das Ergebnis gerastert wird, müssen mindestens 300 Pixel pro Seite vorhanden sein. Das endgültige Gummiband und die Nägel müssen mindestens 75% der horizontalen und vertikalen Ausdehnung des Bildes bedecken. Die Längenskalen von x und y müssen gleich sein. Sie müssen die Nägel im zweiten Satz (mit mindestens 3x3 Pixel) und den String (mindestens 1 Pixel breit) anzeigen. Sie können die Achsen einschließen oder nicht.
Sie haben die Wahl zwischen Farben, aber Sie benötigen mindestens zwei unterscheidbare Farben: eine für den Hintergrund und eine für die Nägel und die Schnur (diese können jedoch unterschiedliche Farben haben).
Sie können davon ausgehen, dass alle Nägel in der zweiten Liste mindestens 10 -5 Einheiten von der ursprünglichen Form des Gummibands entfernt sind (damit Sie sich nicht um Gleitkommaungenauigkeiten sorgen müssen).
Dies ist Codegolf, daher gewinnt die kürzeste Antwort (in Bytes).
Mehr Beispiele
Hier sind zwei weitere Beispiele:
{{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}}
Und hier ist ein Beispiel, das die Bedeutung von zwei verbleibenden Anfangsnägeln zeigt. Das Ergebnis sollte b und nicht a sein :
{{0, 0}, {0, 1}, {-1, 1}, {-1, -1}, {1, -1}, {1, 0}}
{{-0.5, 0.5}}
Vielen Dank an Ell für dieses Beispiel.
quelle
Antworten:
Python + Matplotlib, 688
Liest zwei Punktelisten aus STDIN.
Beispiel
Wie es funktioniert
Der Schlüssel zur Lösung besteht darin, in kleinen, inkrementellen Schritten zu arbeiten. Anstatt herauszufinden, was passiert, wenn wir alle Nägel auf einmal entfernen, konzentrieren wir uns auf die direkten Auswirkungen des Entfernens nur eines einzigen Nagels. Wir können dann die Nägel einzeln in einer beliebigen Reihenfolge entfernen.
Inkrementelles Arbeiten bedeutet, dass wir den Zwischenzustand des Gummibands im Auge behalten müssen. Hier ist der schwierige Teil: Es reicht nicht aus, nur nachzuverfolgen, durch welche Nägel die Band läuft. Während des Entfernens von Nägeln kann das Band um einen Nagel gewickelt und später abgewickelt werden. Wenn das Band mit einem Nagel interagiert, müssen wir daher verfolgen, wie oft und in welche Richtung es sich darum wickelt. Dazu weisen wir jedem Nagel entlang des Bandes einen Wert zu, und zwar wie folgt:
Beachten Sie, dass:
Wir fangen an zu zählen, sobald das Band den Nagel berührt, obwohl der Nagel seine Form nicht stark beeinflusst. Denken Sie daran, dass unsere Nägel im Gegensatz zur Abbildung dimensionslos sind. Deshalb, wenn die Band Tangente an einen Nagel wird können wir nicht sagen , welche Seite der Band der Nagel auf durch seine Position allein ist --- wir die Spur halten müssen , wo sie verwendet wird, um das Band zu sein relativ.
Wir behalten Nägel mit dem Wert Null bei, d. H. Nägel, die früher das Band gehalten haben, aber nicht mehr, anstatt sie sofort zu entfernen. Wenn wir dies tun, könnte dies eine unerwünschte Kettenreaktion auslösen, während wir versuchen, die Auswirkungen jedes Schritts lokalisiert zu halten. Stattdessen können Nägel mit dem Wert Null im Rahmen des größeren Prozesses entfernt werden.
Nun können wir beschreiben, was bei jedem Schritt passiert:
Wir wählen einen Nagel aus, der aus dem aktuellen Pfad der Band entfernt werden soll. Ein Nagel kann entfernt werden, wenn er Teil des ersten Satzes von Nägeln ist (abgesehen von den Endpunkten) oder wenn sein Wert Null ist.
Wir tun so, als wären die beiden benachbarten Nägel fixiert, und finden heraus, durch welche Nägel des zweiten Satzes oder der beiden Endpunkte das Band laufen wird, sobald der ausgewählte Nagel entfernt ist (wir kümmern uns nicht um den Rest der Nägel des zuerst gesetzt, da sie schließlich alle entfernt werden werden.) Wir tun es in ähnlicher Weise auf die Lösung zu Teil I . Alle diese Nägel befinden sich auf derselben Seite des Bandes, daher weisen wir ihnen je nach Seite einen Wert von 1 oder -1 zu .
Wir aktualisieren den Wert der beiden benachbarten Nägel, um die Änderungen auf dem Pfad der Band widerzuspiegeln (einfach der schwierigste Teil!)
Dieser Vorgang wird wiederholt, bis keine Nägel mehr entfernt werden müssen:
Und hier ist ein komplizierteres Beispiel, das zeigt, wie sich das Band mehrmals um einen Nagel wickelt:
quelle
Java - 1262 Bytes
Ich weiß, dass dies wahrscheinlich nicht so viel ist, wie es sein könnte.
Es scheint jedoch niemand anderes an die Tafel zu treten und diese Frage zu beantworten, also werde ich es tun.
Erstens, Klasse "T" - das ist eine Punktklasse - 57 Bytes
Und die Hauptklasse - 1205 Bytes
Beispiel:
Rufen Sie zum Ausführen die "d" -Funktion mit einer Liste von Punkten und einer Reihe von Nägeln auf (ja, ich weiß, seltsam). Was es macht:
Ich bin mir nicht sicher, ob Achsen in Pixeln in Ordnung sind. Es wird immer mehr als 75% des Platzes einnehmen, es könnte wirklich sehr, sehr klein sein.
Hier ist eine nette Animation, um zu demonstrieren, was ich hier mache:
Schließlich wird es dies, in dem sich die Punkte kaum bewegen. Dies ist, wenn ich sehe, welche Nägel es berührt:
Hier ist der ungolfed, Animationscode:
quelle