Nehmen Sie ein zweidimensionales Gitter und zeichnen Sie eine Reihe von Liniensegmenten darauf, um Spiegel darzustellen. Wählen Sie nun einen Punkt, um einen theoretischen Laser zu platzieren, und einen Winkel, um die Richtung zu definieren, in die er zeigt. Die Frage ist: Wenn Sie dem Laserstrahlverlauf für eine bestimmte Entfernung folgen, an welchem Koordinatenpunkt befinden Sie sich?
Beispiel:
In diesem Bild L
ist der Ort des Lasers, t
ist es der Winkel (von der positiven X - Achse gemessen) M1
, M2
und M3
sind alle Liniensegment Spiegel und E
ist der Punkt , auf dem Laser-Strahlengang nach D = d1 + d2 + d3 + d4
Einheiten, ausgehend von L
.
Tor
Schreibt das kürzeste Programm (in Bytes) , die Ausgänge E
gegeben L
, t
, D
, und eine Liste von Spiegeln.
(Verwenden Sie http://mothereff.in/byte-counter, um Bytes zu zählen.)
Eingabeformat
Die Eingabe erfolgt von stdin im Format:
Lx Ly t D M1x1 M1y1 M1x2 M1y2 M2x1 M2y1 M2x2 M2y2 ...
- Alle Werte werden Punkte schweben diese Regex übereinstimmt , gefunden
[-+]?[0-9]*\.?[0-9]+
. - Zwischen jeder Zahl steht immer genau ein Leerzeichen.
- Anführungszeichen für die Eingabe sind zulässig.
t
ist in Grad, aber nicht unbedingt im[0, 360)
Bereich. (Wenn Sie es vorziehen, können Sie stattdessen Radianten verwenden, sagen Sie dies einfach in Ihrer Antwort.)D
kann negativ sein und den Laser effektiv um 180 Grad drehen.D
kann auch 0 sein.- Es kann beliebig viele Spiegel geben (einschließlich überhaupt keiner).
- Die Reihenfolge der Spiegel sollte keine Rolle spielen.
- Sie können davon ausgehen, dass die Eingabe in Vielfachen von 4 Zahlen erfolgt. zB
Lx Ly t
oderLx Ly t D M1x1
sind ungültig und werden nicht getestet. Keine Eingabe ist auch ungültig.
Das obige Layout könnte wie folgt eingegeben werden:
1 1 430 17 4.8 6.3 6.2 5.3 1.5 4.8 3.5 6 6.3 1.8 7.1 3
(Beachten Sie, dass das Bild freihändig gezeichnet wurde und diese Werte nur Näherungswerte sind. Martin Büttners Eingabewerte von
1 1 430 17 4.8 5.3 6.2 4.3 1.5 4.8 3.5 6 6.3 1.8 7.1 3
wird mehr Kollisionen geben, obwohl sie nicht mit der Skizze übereinstimmen.)
Ausgabeformat
Die Ausgabe sollte im Format stdout erfolgen:
Ex Ey
Dies sind auch Schwimmer und können exponentiell sein.
Anmerkungen
- Spiegel können sich überschneiden.
- Beide Seiten der Spiegel reflektieren.
- Der Strahl kann mehrmals auf denselben Spiegel treffen.
- Der Strahl geht für immer weiter.
Undefinierte Fälle
Sie können davon ausgehen, dass die Fälle, in denen
- Der Laser startet auf einem Spiegelliniensegment
- Der Laserstrahl trifft auf den Endpunkt eines Spiegels
- Der Laserstrahl trifft auf den Schnittpunkt zweier Spiegel
sind undefiniert und werden nicht getestet. Ihr Programm kann in solchen Fällen alles Mögliche tun, auch einen Fehler auslösen.
Bonus
Nur zum Spaß werde ich 200 Kopfgeldpunkte für die am höchsten bewertete Einsendung vergeben, die eine grafische Darstellung des Problems ausgibt (Sie können sogar ein interaktives Skript schreiben). Diese Bonus-Einreichung muss nicht gespielt werden und kann im Hinblick auf den Umgang mit Input und Output nachlässig sein. Sie unterscheiden sich von den tatsächlichen Einsendungen, sollten jedoch beide in derselben Antwort eingereicht werden .
Hinweis: Nur die Übermittlung einer Bonusantwort ist in Ordnung. Sie werden einfach nicht als Antwort akzeptiert. Um akzeptiert zu werden, müssen Sie die Eingabe- / Ausgabespezifikation genau befolgen (z. B. Ausgabe bezieht Ex Ey
nur Bilder ein, nicht Bilder) und die kürzeste sein.
Antworten:
Ruby, 327 Bytes
(nach unten scrollen)
Mathematica, Bonusantwort
Ich werde jetzt nur die grafische Einreichung vornehmen. Ich könnte das später auf Ruby portieren und Golf spielen, wenn ich Lust dazu habe.
Du kannst es so nennen
Dadurch erhalten Sie eine Animation in Mathematica und können auch ein GIF exportieren (das für diese Eingabe oben stehende). Ich habe das OPs-Beispiel dazu etwas erweitert, um es ein bisschen interessanter zu machen.
Mehr Beispiele
Eine Röhre mit leicht divergierenden Wänden, aber einem geschlossenen Ende:
Ein gleichseitiges Dreieck und eine Anfangsrichtung, die fast parallel zu einer der Seiten verläuft.
Einer noch:
Ruby, Golf Antwort
Dies ist im Grunde eine direkte Übersetzung der Mathematica-Lösung nach Ruby, plus ein wenig Golfspielen und sicherstellen, dass sie die I / O-Kriterien erfüllt.
quelle
Python 3 (
421C 390C366C)Verwenden Sie
builtin.complex
als 2D-Vektor. SoUm die 368C Ruby-Lösung zu übertreffen, habe ich eine recht kompakte Methode zur Berechnung der Punktreflexion entlang eines Spiegels gefunden. Und auch einige komplexe Algebra verwendet, um mehr Zeichen zu reduzieren. Diese sind leicht im Code zu finden.
Hier ist die Golfversion.
Ungolfed
Bonus: HTML, Coffeescript, Echtzeitanpassung & Berechnung
Das heißt, Sie ziehen beliebige Endpunkte (oder Lazer, Mirros), dann wird die Spur gerendert. Es werden auch zwei Arten von Eingaben unterstützt, die in der Frage beschriebene und die von @Martin Büttner verwendete.
Die Skalierung wird ebenfalls automatisch angepasst.
Im Moment hat es keine Animation. Vielleicht verbessere ich es später. Wenn Sie jedoch die weißen Punkte ziehen, wird eine andere Art von Animation angezeigt. Probieren Sie es online hier selbst, es ist lustig!
Das gesamte Projekt finden Sie hier
Aktualisieren
Hier stelle ich einen interessanten Fall vor:
Und das Ergebnis ist:
quelle
HTML JavaScript,
10,543,947889Ich habe einen Fehler behoben und sichergestellt, dass die Ausgabe der Fragenspezifikation entspricht. Die Webseite unten hat die Golfversion und auch die grafische Bonusversion. Ich habe auch einen Fehler behoben, auf den @Ray hingewiesen hat und der 58 Zeichen sparte. (Danke Ray.) Sie können den Code auch in einer JavaScript-Konsole ausführen. (Jetzt benutze ich einen 2mW grünen Laser.)
Golf Code
Eingang
Ausgabe
Sie können es hier testen: http://goo.gl/wKgIKD
Erläuterung
Der Code auf der Webseite ist kommentiert. Grundsätzlich berechne ich den Schnittpunkt des Lasers mit jedem Spiegel unter der Annahme, dass der Laser und die Spiegel unendlich lang sind. Dann überprüfe ich, ob der Schnittpunkt innerhalb der endlichen Länge des Spiegels und des Lasers liegt. Dann nehme ich die nächstgelegene Kreuzung, bewege den Laser zu diesem Punkt und fahre fort, bis der Laser alle Spiegel verfehlt.
Sehr lustiges Projekt. Danke, dass Sie diese Frage gestellt haben!
Lesbarer Code
quelle
0 0 0.4 100 1 1 1 -1 1 -1 -1 -1 -1 -1 -1 1 -1 1 1 1
.Python - 765
Gute Herausforderung. Dies ist meine Lösung, die Eingaben von stdin und Ausgaben von stdout erhält. Am Beispiel von @Martin Büttner:
Hier ist der Golfcode:
Und hier ist der ungolfed Code mit einer Bonuszahl
quelle
sys.argv
nicht stdin ist.Matlab (388)
Handlung
Konzepte
Reflexionspunkte
Für die Berechnung der Reflexionspunkte müssen grundsätzlich zwei Geraden geschnitten werden. Einer mit dem Punkt p0 und dem Vektor v, der andere zwischen den beiden Punkten p1, p2. Die zu lösende Gleichung lautet also (s, t sind Parameter): p0 + t v = s p1 + (1-s) * p2.
Der Parameter s ist dann eine Schwerpunktskoordinate des Spiegels also wenn 0
Spiegeln
Das Spiegeln von v ist ziemlich einfach. Nehmen wir an, dass || v || = || n || = 1 wobei n der Normalenvektor des Stromspiegels ist. Dann können Sie einfach die Formel v: = v-2 ** n verwenden, wobei <,> das Skalarprodukt ist.
Gültigkeit des Schritts
Bei der Berechnung des nächsten "gültigen" Spiegels müssen einige Kriterien berücksichtigt werden, die ihn gültig machen. Zuerst muss der Abfangpunkt des Spiegels zwischen den beiden Endpunkten liegen, also muss er 0 sein
Programm
Leicht golfen (388)
quelle