Ausgabekoordinaten der Eckpunkte eines Würfels. Geben Sie dann eine Liste mit zwölf Dreiecken aus, die den Würfel abdecken. Jedes Dreieck ist eine Liste mit drei Scheitelpunktindizes, die konsistent ausgerichtet sind. Die Ausgabe muss eine ASCII-Zeichenfolge mit unterschiedlichen Dezimalzahlen sein. Dieser Golf hat keine Eingabe. Gewinner sind die wenigsten Zeichen, wobei der Zeichensatz Unicode ist.
Betrachten Sie als Beispiel einen 1x1x1-Würfel mit einer Ecke von 0,0,0. Die acht Eckpunkte des Würfels können durch die folgenden xyz-Koordinaten in einem kartesischen 3D-Gitter beschrieben werden:
x y z = (0,0,1) (1,0,1) (1,1,1) (0,1,1) (0,0,0) (1,0,0) (1,1,0) (0,1,0)
Jeder Scheitelpunkt kann mit einem Index versehen werden: x y z->index: 0 0 1->0, 1 0 1->1, 1 1 1->2, 0 1 1->3, 0 0 0->4, 1 0 0->5, 1 1 0->6, 0 1 0->7
Betrachten Sie nun die Oberseite, die Scheitelpunkte sind null bis drei. Die zwei Deckdreiecke können durch jeweils drei Indizes beschrieben werden:
[0,1,2] [2,3,0]
Hier ist ein Bild von dieser Oberseite, von oben gesehen über dem Würfel:
3_____2
| /|
| / |
| / |
| / |
0_____1
Und hier ist ein Blick aus einem Winkel.
3____2
/ __-/|
0/_`__1 |
| | /6
|____|/
4 5
Beachten Sie, dass die Ausrichtung oder "Wicklung" dieser beiden Dreiecke "gegen den Uhrzeigersinn" ist, wenn Sie von "außerhalb" des Würfels direkt auf das betreffende Gesicht schauen (stellen Sie sich vor, Sie besuchen jeden Scheitelpunkt wie aufgelistet, er geht gegen den Uhrzeigersinn). Stellen Sie sich nun vor, dies geschieht für alle sechs Seiten des Würfels.
vertices: (0,0,1) (1,0,1) (1,1,1) (0,1,1) (0,0,0) (1,0,0) (1,1,0) (0,1,0)
triangles as indices: [0,1,2], [2,3,0], [6,5,4], [4,7,6],
[5,2,1], [2,5,6], [0,3,4], [4,3,7], [2,6,3], [3,6,7], [0,4,1], [1,4,5]
Sie können eine beliebige Würfelgröße an beliebigen Koordinaten ausgeben. Sie können die Scheitelpunktkoordinaten beliebig nummerieren und bestellen. Indizes können auf 0 oder 1 basieren. Die Ausrichtung des Dreiecks kann von außerhalb des Würfels betrachtet entweder im oder gegen den Uhrzeigersinn erfolgen, sofern dies für alle Dreiecke konsistent ist.
Die Ausgabe kann beliebig formatiert werden, solange jede ASCII-Dezimalzahl durch mindestens ein nicht numerisches ASCII-Zeichen getrennt ist. Zum Beispiel könnte das obige Beispiel auch wie folgt ausgegeben werden:
0 0 1 1 0 1 1 1 1 0 1 1 0 0 0 1 0 0 1 1 0 0 1 0
0 1 2 2 3 0 6 5 4 4 7 6 5 2 1 2 5 6 0 3 4 4 3 7 2 6 3 3 6 7 0 4 1 1 4 5
Dieser Golf ist von verschiedenen 3D-Grafiksystemen und -formaten inspiriert, darunter OpenGL, OBJ, OFF, AMF, CGAL usw. Dieser Golf ähnelt dem Golf von Calvins Hobbys " Output a Face on a Numbered Cube" , wobei der große Unterschied darin besteht, dass Sie ihn benötigen um die xyz-Koordinaten der Eckpunkte selbst auszugeben und Dreiecksindizes auszugeben. Danke fürs Lesen.
Pro Benutzerinspiration gibt es hier ein "Helfer" -Validierungsprogramm in Python2 (nicht Golf), das für Testausgabedaten in den Variablen vertstr und idxstr "ok" oder "nicht ok" druckt. Es funktioniert nicht perfekt ... aber es kann einige Fehler auffangen.
Bearbeiten: Tippfehler im Beispiel behoben und Fehler im Validierungscode.
#vertstr = '0 0 0 0 0 1 0 1 0 0 1 1 1 0 0 1 0 1 1 1 0 1 1 1' #idxstr = '1 2 0 2 1 3 7 5 6 4 6 5 2 4 0 4 2 6 7 3 5 1 5 3 4 1 0 1 4 5 7 6 3 2 3 6' vertstr = '0 0 1 1 0 1 1 1 1 0 1 1 0 0 0 1 0 0 1 1 0 0 1 0' idxstr = '0 1 2 2 3 0 6 5 4 4 7 6 5 2 1 2 5 6 0 3 4 4 3 7 2 6 3 3 6 7 0 4 1 1 4 5' Klasse Vektor: def __init __ (self, v): self.x, self.y, self.z = v [0], v [1], v [2] def __add __ (self, v): Rückgabevektor ([self.x + vx, self.y + vy, self.z + vz]) def __sub __ (self, v): return Vector ([self.xv.x, self.yv.y, self.zv.z]) def __str __ (Selbst): return str (self.x) + ',' + str (self.y) + ',' + str (self.z) def cross (v1, v2): x = v1.y * v2.z-v2.y * v1.z. z = v1.x * v2.y-v2.x * v1.y. y = v1.z * v2.x-v2.z * v1.x. Rückgabevektor ([x, y, z]) # http://mathforum.org/library/drmath/view/55343.html & http://sympy.org def Wicklung (v1, v2, v3, obs): x1, y1, z1, x2, y2, z2, x3, y3, z3, x4, y4, z4 = v1.x, v1.y, v1.z, v2.x, v2.y, v2.z, v3. x, v3.y, v3.z, obs.x, obs.y, obs.z. d = x1 * (y2 * z3 - y2 * z4 - y3 * z2 + y3 * z4 + y4 * z2 - y4 * z3) d = d + y1 * (- x2 * z3 + x2 * z4 + x3 * z2 - x3 * z4 - x4 * z2 + x4 * z3) d = d + z1 * (x2 * y3 - x2 * y4 - x3 * y2 + x3 * y4 + x4 * y2 - x4 * y3) d = d - x2 * y3 * z4 + x2 * y4 * z3 + x3 * y2 * z4 - x3 * y4 * z2 - x4 * y2 * z3 + x4 * y3 * z2 Rückkehr d def Normalen (v1, v2, v3): va = v2-v1 vb = v3-v2 vc = v1-v3 n1 = Kreuz (va, vb) n2 = Kreuz (vb, vc) n3 = Kreuz (vc, va) return [n1, n2, n3] def verdreifachen (str): nums, triples = [], [] für num in str.split (''): nums + = [int (num)] für i im Bereich (0, len (nums), 3): Tripel + = [[nums [i], nums [i + 1], nums [i + 2]]] dreifache zurückgeben verts = verdreifachen (vertstr) Indizes = verdreifachen (idxstr) nsum = Vektor ([0,0,0]) Windsum = 0 xs, ys, zs = [], [], [] für v in verts: xs + = [v [0]] ys + = [v [1]] zs + = [v [2]] #print xs, ys, zs, len (xs) center = Vektor ([float (Summe (xs)) / len (xs), float (Summe (ys)) / len (ys), float (Summe (zs)) / len (zs)]) für Dreieck in Indizes: v1 = Vektor (verts [Dreieck [0]]) v2 = Vektor (verts [Dreieck [1]]) v3 = Vektor (verts [Dreieck [2]]) Normen = Normalen (v1, v2, v3) print v1, v2, v3, normen [0], normen [1], normen [2] für n in Normen: nsum + = n w = Wicklung (v1, v2, v3, Mitte) Druck 'Wicklung', w wenn w <0: Windsum- = 1 elif w> 0: Windsum + = 1 if abs (windsum) == 12: drucke 'Wicklung ok' sonst: drucke 'Wicklung nicht ok' if (nsum.x == 0 und nsum.y == 0 und nsum.z == 0): 'normale Summe ok' drucken sonst: drucke 'normale Summe nicht ok'
Antworten:
Pyth, 18 Zeichen
Gleiche Idee wie meine Antwort von Haskell; Drucke:
quelle
CJam, 35 Bytes
Probieren Sie es online aus
Die Ausgabe ist:
Die Dreiecksausrichtung erfolgt von außen im Uhrzeigersinn. Ich habe dies manuell überprüft und es sieht für mich korrekt aus.
Erläuterung:
quelle
JavaScript (ES6) 78
Entschuldigung, aber ich verstehe diese Herausforderungen ohne Eingabe wirklich nicht.
quelle
Ruby,
98106Fehler von Reto Koradi behoben.
Angesichts der Tatsache, dass Koordinaten erforderlich sind, schien das einzige sinnvolle Eckennummerierungsschema das zu sein, bei dem jede Ecke die binäre Darstellung ihrer Koordinaten ist. Das ist ganz anders als bei der verknüpften Frage, bei der verschiedene Nummerierungsschemata ausprobiert wurden. Am Ende habe ich beschlossen, die Koordinaten mit einem schmutzigen Hardcode zu drucken:
s
wird auf die String-Version der 24-Bit-Zahl initialisiert,000001010011100101110111
deren Dezimaldarstellung 342391 ist. Tatsächlich ist bei dieser Methode zum Drucken von Koordinaten die Nummerierung der Eckpunkte flexibel, also kann ich mach eine andere Antwort.Wenn wir den Äquator des Würfels umrunden, finden wir die Eckpunkte 1,5,4,6,2,3 und wir können ein Dreieck für jede Fläche aus 3 aufeinanderfolgenden Zahlen in dieser Liste definieren (am Ende zurück zum Anfang. ) Das andere Dreieck auf jeder Seite wird definiert, indem die Ziffern umgekehrt werden und die mittlere Ziffer durch 0 oder 7 ersetzt wird.
Dies gibt alle erforderlichen Ausgaben, jedoch ohne Trennzeichen. Um dies zu erreichen, konvertiere ich einfach in ein Array von Zeichen und drucke das Array wie folgt aus (Zeilenumbrüche eingefügt, um ein Scrollen zu verhindern):
quelle
1, 5, 4
ist CCW,5, 4, 6
ist CW.Haskell, 38 Zeichen
Druckt die richtigen Zahlen, getrennt durch eine ganze Menge Müll:
Die Diagonale des Würfels reicht von (1, 1, 1) bis (2, 2, 2).
quelle
CJam, 20 Zeichen
Gleiche Idee wie meine Antwort von Haskell; Drucke:
quelle
Ruby, Rev 1 62
Wurde das
c-6
durch Multiplizieren der magischen Zahl mit 64 los .Die Zuordnung der Koordinaten ist unten. Es ist seltsam, dass ich
100
Nummer 1 zugewiesen habe. Ich hätte ein Byte in Rev. 0 speichern können, indem ich die Achsen ausgetauscht001
und Nummer 1 zugewiesen hätte . Der Grund dafür war, dass ich ursprünglich in der Schleife gezählt hatte, was bedeutet hätte, dass ich musste alles umgekehrt in die magische Schnur setzen. Wie auch immer, mit der Änderung, die ich jetzt vorgenommen habe, müssen keine zusätzlichen Einsparungen vorgenommen werden, also lasse ich die Koordinaten so, wie sie sindRuby, Rev 0 63
Verwenden Sie die Hardcodierung der Koordinatendaten, um die Auswahl der Ecken flexibel zu gestalten. Die Ausgabe enthält 54 Stellen, was bedeutet, dass für die naive Lösung 63-54 = 9 Byte für Code verfügbar sind. Da ich mir keine Möglichkeit vorstellen kann, Leerzeichen in 9 Bytes einzufügen, glaube ich, dass dies kürzer ist als die naive Lösung.
Nummerierungsschema (angepasst aus meiner Ruby-Antwort auf die verknüpfte Frage https://codegolf.stackexchange.com/a/48867/15599 )
Ausgabe
quelle