Diese Frage ist vom Cover des Buches "Godel, Escher, Bach" inspiriert:
Die Herausforderung besteht darin, eine Funktion zu schreiben, die angibt, ob drei gegebene Buchstaben eine 3D-Skulptur erzeugen können, die von drei Seiten gelesen werden kann.
In dieser Übung können Sie nur 26 5px * 5px-Bitmaps verwenden:
Oder binär (von A bis Z):
01110 11110 01111 11110 11111 11111 11111 10001 11111 11111 10001 10000 10001 10001 01110 11110 01110 11110 01111 11111 10001 10001 10001 10001 10001 11111
10001 10001 10000 10001 10000 10000 10000 10001 00100 00100 10010 10000 11011 11001 10001 10001 10001 10001 10000 00100 10001 10001 10001 01010 01010 00010
10001 11110 10000 10001 11100 11110 10011 11111 00100 00100 11100 10000 10101 10101 10001 10001 10001 11111 01110 00100 10001 01010 10001 00100 00100 00100
11111 10001 10000 10001 10000 10000 10001 10001 00100 10100 10010 10000 10001 10011 10001 11110 10011 10010 00001 00100 10001 01010 10101 01010 00100 01000
10001 11110 01111 11110 11111 10000 11111 10001 11111 11100 10001 11111 10001 10001 01110 10000 01111 10001 11110 00100 01110 00100 01010 10001 00100 11111
Die Skulptur besteht aus drei Buchstaben in der folgenden Reihenfolge:
- beschriften sie eine auf die spitze,
- Buchstabe zwei auf der linken Seite
- Buchstabe drei rechts
- Der untere Teil des ersten Buchstabens ist an den oberen Teil des zweiten Buchstabens gebunden.
Beispiel:
Ihre Funktion akzeptiert möglicherweise drei Großbuchstaben (drei Zeichen oder drei Zeichenfolgen aus einem Buchstaben) als Eingabe und gibt einen Booleschen Wert (true / false oder 0/1) aus, der angibt, ob die entsprechende Skulptur vorhanden sein kann.
Beispiel:
f("B","E","G") // true (because if you "sculpt out" B on top + E on the left + G on the right, and watch the three sides of the sculpture, you'll see exactly B, E and G as they are defined)
f("B","G","E") // false (because if you "sculpt out" B on top + G on the left + E on the right, and watch the three sides of the sculpture, you won't see a complete G and a complete E. Their shapes bother each other)
NB: Sie können true zurückgeben, auch wenn die Skulptur "fliegende Pixel" enthält (Würfel oder eine Gruppe von Würfeln, die an nichts gebunden sind).
Es gelten Standardlücken.
Genauer gesagt, Sie können keine externen Eingaben neben den drei Buchstaben verwenden und die 17576 möglichen Antworten in Ihrem Quellcode nicht fest codieren
Kürzeste Antwort in Zeichen in einer Sprache gewinnt!
Habe Spaß :)
Antworten:
Mathematica 423
Ich habe einen Abschnitt namens "So funktioniert das Blockieren" hinzugefügt.
Ungolfed
(* Die Binärdaten des Alphabets werden als einzelne Zeichenfolge in gespeichert
s
.vars
Importiert sie und konvertiert sie in ein Array.)Beispiel
Ist der Würfel
{"B", "G", "E"}
gültig? (Werden die drei Buchstaben richtig auf die Wände projizieren?)Abbildungen
Die folgenden Abbildungen zeigen, wie BGE gerendert wird. Die obere Figurenreihe nimmt orthogonale Perspektiven ein, als ob der Betrachter in unendlichen Abständen vom Würfel positioniert wäre. Die untere Reihe zeigt, wie die Blöcke aus der Nähe aussehen würden. Die 3D-Figuren können manuell gedreht werden, um genau zu prüfen, wo die einzelnen Einheitswürfel positioniert sind.
Ein Problem tritt mit dem Buchstaben "G" auf. Es gibt nichts, was die Serife mit dem Rest des Briefes verbindet.
BEG sollte jedoch gut funktionieren.
Wie funktioniert das Blockieren?
Bitte entschuldigen Sie, wenn dies offensichtlich erscheint, aber vielleicht möchten einige Leute visualisieren, wie Buchstaben sich gegenseitig stören und ihre 3D-Pixel aufheben.
Lassen Sie uns im BGE-Cube-Rendering verfolgen, was mit dem Buchstaben G geschieht.
Wir werden dem Voxel (3D-Pixel oder Einheitswürfel) unten besondere Aufmerksamkeit schenken . Das ist das Pixel, das im BGE-Würfel verschwindet. Dies ist das Pixel, das Zeile 4, Spalte 5 im Bit-Array und im entsprechenden Array-Diagramm entspricht.
In der xy-Ebene entspricht das Pixel der grauen Scheibe am Punkt (5,2). Da wir aber in 3D arbeiten werden, müssen wir die 5 Positionen in der Welle von (5,1,2) bis (5,5,2) berücksichtigen. Wenn eines dieser Pixel die Bildhauerei durch die Buchstaben B und E überlebt, können wir das interessierende Pixel in der 3D-Projektion an der Wand sehen.
Buchstaben stören, wenn Pixel aus dem durchgehenden Block entfernt werden. Links stellt der schwarze Pfeil das Herausschneiden von Pixeln dar, das dem Bit unten rechts entspricht. es hat den Wert 0 für den Buchstaben B. Durch Herausschnitzen wird das Pixel bei (5,1,2) sowie die direkt darüber und darunter liegenden Pixel entfernt. Es müssen noch vier Pixel berücksichtigt werden.
Wie der rechte Bereich zeigt, formt der Buchstabe E die verbleibenden interessierenden Pixel (5,2,2) (5,3,2), (5,4,2) und (5,5,2) aus. (Dies ist auf die Tatsache zurückzuführen, dass der Buchstabe E in der vierten Zeile von Spalte 2 bis Spalte 5 Bits gleich 0 enthält.) Infolgedessen verbleibt kein einziges Pixel unter denjenigen, die benötigt wurden, um die Schattierung an Punkt (5) sicherzustellen , 2) an der gegenüberliegenden Wand (für den Buchstaben G). Stattdessen erscheint ein heller Fleck, der einem Loch im Buchstaben G entspricht! Der Würfel BGE ist nicht gut, weil er G falsch darstellt.
Golf 423 Zeichen
Die Funktion hatte
h
dieselbe Funktion wievalidQ
im unGolfed-Code. Die Rendering-Funktionperspective
ist nicht enthalten, da sie nicht zur Herausforderung beiträgt und von ihr nicht benötigt wird.quelle
Prolog,
440, 414Das Programm heißt so:
Prolog
schien eine gute Wahl zu sein, da es einfach ist, das Problem in der Logik erster Ordnung darzustellen. AuchProlog
bietet starke Funktionalität für diese Art von Problem zu lösen.Da der Code jedoch Golf ist, sollte ich eine Erklärung hinzufügen.
Leicht golfene Version
Die Koordinaten, die den Pixeln auf jeder Seite der Würfel entsprechen, können leicht in ein 3D-Koordinatensystem umgewandelt werden. I verwenden
T
,L
undR
für die oben (1), links (2) und die rechte (3) Seite.u
undv
werden für die Koordinaten in den Bildern verwendet:(u,v) -> (4-v, ?, u)
(u,v) -> (?, v, u)
(u,v) -> (u, v, ?)
Die Ergebnisse für jedes aktive (dh schwarze) Pixel werden zu einer Reihe von "3D-Pixeln" kombiniert, die aktiviert werden können, ohne das Aussehen des Objekts von dieser Seite aus zu verändern. Der Schnittpunkt der Sätze für jede Seite sind alle 3D-Pixel, die aktiviert werden können, ohne dass Pixel hinzugefügt werden müssen, die die Ansicht behindern würden (dh wenn Sie von mindestens einer Seite aus sehen, würde sich ein Pixel befinden, das nicht vorhanden sein sollte).
Es muss nur noch für jede Seite überprüft werden, ob sich in der Kreuzung ein Pixel befindet, das die Ansicht blockiert, sofern dies erforderlich ist.
Dies führt zu den Prädikaten im Programm:
c : Überprüft das Pixel im Bild eines Buchstabens. Die Zeichenfolge darin sieht vielleicht etwas seltsam aus, aber es ist nur eine kompakte Art, die Bilddaten zu speichern. Es ist einfach eine Zeichenfolge mit den folgenden Werten (Hex-Notation):
Jedes dieser Zeichen speichert die Daten für 3 Pixelzeilen in Buchstabenbildern (= 15 Pixel). Die Pixel werden auch neu angeordnet, damit die Daten an einem Ort gespeichert und nicht wie die Daten des OP auf mehrere Zeilen aufgeteilt werden.
Mathematische Formulierung
Eingabedaten
Umwandlung von Pixel in einem Zeichen in eine Menge von 3D-Pixeln, die die Ansicht für dieses Pixel verdecken
Pixel, die sicher hinzugefügt werden können (ohne die Ansicht an der falschen Stelle zu beeinträchtigen)
Überprüft für jede Seite, ob die Pixel, die blockiert werden müssen, sicher blockiert werden können
Scheckkombination für jede Seite
quelle
J -
223197191 charEine Funktion, die eine Drei-Zeichen-Liste als Argument verwendet.
Dieser Golf beruht in hohem Maße auf einer leistungsstarken Funktion von J namens Rank , mit der wir die Operationen "Sculpt-Out" und "Watch-Side-Of" fast kostenlos ausführen können. Um es ein wenig zu vereinfachen, bezieht sich der Rang auf die Dimensionalität eines Substantivs oder der natürlichen Argumente eines Verbs.
J hat mehrdimensionale Arrays, und es ist offensichtlich, dass ein 3D-Array beispielsweise als einzelnes 3D-Array oder als Liste von Matrizen oder als 2D-Array von Vektoren oder als 3D-Array von Skalaren interpretiert werden kann. So kann jede Operation in J ihre Anwendung so steuern, dass sie über das Argument verteilt wird. Rang 0 bedeutet, dass sie auf die Skalare angewendet werden, Rang 1 bedeutet, dass sie auf die Vektoren angewendet werden und so weiter.
Dies wird sehr effektiv, wenn Sie dyadische Funktionen (mit zwei Argumenten) einführen. Wenn die Formen der beiden Argumente (nach Berücksichtigung des Rangs) akzeptabel sind, führt J eine implizite Schleife durch:
Wenn alle Ihre Formen zufriedenstellend sind und Sie den Rang selbst festlegen können, gibt es viele Möglichkeiten, Argumente zu kombinieren. Hier zeigen wir einige Möglichkeiten, wie Sie eine 2D-Matrix und ein 3D-Array multiplizieren können.
Sie werden feststellen, dass dies nicht in die Buchstaben in der gewünschten Ausrichtung eingraviert, sondern nur eingeschrieben wird, was für die Ranglogik praktisch ist. Wenn wir die Buchstaben nicht umkehren oder drehen, bevor wir sie anwenden, funktioniert es nicht richtig. Das Korrigieren solcher Dinge würde jedoch wertvolle Zeichen in Anspruch nehmen. Stattdessen werden wir die Buchstaben so codieren, dass, wenn J sie auf natürliche Weise einschneidet, sich einige Dreifachgesichter in den richtigen Ausrichtungen und relativen Positionen befinden. Es stellt sich heraus, dass die kürzeste Lösung darin besteht, alle Briefbögen um eine Vierteldrehung gegen den Uhrzeigersinn zu drehen. Unter Berücksichtigung der dritten Dimension von J zur Darstellung der Achse von vorne nach hinten zeigt das grobe Diagramm unten, warum dieses Schema funktioniert.
Abbildung A: Die drei Seiten des Würfels, in den J schnitzt. Abbildung B: Die drei Seiten, auf denen die Buchstaben wie in der Frage dargestellt ausgerichtet sind.
Diese Wahl bei der Codierung spart 12 Zeichen gegenüber der vorherigen Methode und macht das Ganze ordentlicher. Der eigentliche Golfspieler erschafft den Würfel aus
"1
und"2
schnitzt mit etwas Funky-Logik, aufgrund einer nicht zusammenhängenden Optimierung.Dann müssen wir die Gesichter überprüfen. Da wir den Block als 1 und 0 kodieren, können wir entlang jeder Achse in der Art und Weise zusammenzufassen nur wollen wir (das sind die
+/"1
,+/"2
und+/
Bits), passen Sie auf booleans (0<
), und sie dann auf die ursprüngliche 90 ° alle direkt vergleichen - umgedrehte Buchstaben.Das Komprimierungsschema codiert jede 5px-Zeile jedes Buchstabens als die Basis 32-Darstellung einer Binärzahl. Durch Ausnutzen einer Reihe syntaktischer Zucker und Überladungen von Operatoren
".'1b',"#:
ist dies der kürzeste Weg, um die Liste der Zeichen in Basis-36-Zahlen umzuwandeln. Nun, technisch gesehen, Basis 32, aber J denkt, es ist unärgerlich, also wer zählt?Verbrauch ist unten. Beachten Sie, dass Strings Zeichen-Arrays in J sind, sodass eine Liste
'A','B','C'
mit drei Elementen'ABC'
kurz geschrieben werden kann . Auch Boolesche Werte sind 1/0.quelle
Python,
687682671Rufen Sie an mit
v
:Alles unten ist von meiner vorherigen ungolfed Version, die hilfreiche Zeichenfunktionen enthält. Fühlen Sie sich frei, es als Ausgangspunkt zu verwenden.
Rufen Sie
valid
an, um es auszuführen:Im Moment ist der Code eingerichtet, um die Gültigkeit
B E G
der resultierenden Gesichter zu testen und auszudrucken:Wenn
B G E
wir es ausführen, können wir sehen, dass das G falsch ist:quelle
g=[[0 for j in s]for i in s]
kann auf gekürzt werdeng=map(list,[[0]*5]*5)
. Sie können auch Einrücken Blöcke vermeiden , wenn sie eine einzelne Anweisung sind:if c[e]:g[e[a]][e[a-2]]=1
.Python 3 + Numpy, 327C
Diese Golflösung benötigt eine externe Bibliothek, Numpy, die sehr beliebt ist, daher denke ich, dass es in Ordnung ist, sie zu verwenden.
Die Unicode-Zeichenfolge besteht aus 41 Zeichen, während in der Prolog-Antwort von @ fabian das Gleiche gilt: 44.
Das interessanteste hier ist, dass die Indizierung von Numpy-Array. In
a[ix]
,ix
kann als eine Boolesche Array mit der gleichen Form seina
. Es ist das gleiche wie zu sagena[i, j, k] where ix[i, j, k] == True
.Ungolfed Version
Skript zum Komprimieren der Tabelle
quelle