Die Grundlagen:
Betrachten Sie die folgenden Tetrominoes und das leere Spielfeld:
0123456789 IOZTLSJ [] [] # ## ## ### # ## # [] # ## ## # # ## # [] # ## ## [] # [] [==========]
Die Abmessungen des Spielfeldes sind festgelegt. Die Zahlen oben geben nur die Spaltennummer an (siehe auch Eingabe).
Eingang:
1 . Sie erhalten ein bestimmtes Spielfeld (basierend auf dem oben Gesagten), das bereits teilweise mit Tetrominos gefüllt werden kann (dies kann in einer separaten Datei erfolgen oder über stdin bereitgestellt werden).
Beispieleingabe:
[] [] [] [] [# # #] [## ######] [==========]
2 . Sie erhalten eine Zeichenfolge, die beschreibt (durch Leerzeichen getrennt), welches Tetromino an welcher Spalte eingefügt (und abgelegt) werden soll. Tetrominoes müssen nicht gedreht werden. Die Eingabe kann von stdin gelesen werden.
Beispieleingabe:
T2 Z6 I0 T7
Sie können davon ausgehen, dass die Eingabe "wohlgeformt" ist (oder undefiniertes Verhalten erzeugen, wenn dies nicht der Fall ist).
Ausgabe
Rendern Sie das resultierende Feld ('volle' Zeilen müssen verschwinden) und drucken Sie die Punktzahl (jede abgelegte Zeile entspricht 10 Punkten).
Beispielausgabe basierend auf der obigen Beispieleingabe:
[] [] [] [# ###] [# ###] [##### ####] [==========] 10
Gewinner:
Kürzeste Lösung (nach Anzahl der Codezeichen). Anwendungsbeispiele sind nett. Viel Spaß beim Golfen!
Bearbeiten : Es wurde eine Menge +500
Reputation hinzugefügt, um mehr Aufmerksamkeit auf die netten Bemühungen der Antwortenden zu lenken (und möglicherweise auf einige neue Lösungen für diese Frage) ...
quelle
Antworten:
GolfScript - 181 Zeichen
Zeilenumbrüche sind nicht erforderlich. Die Ausgabe erfolgt in der Standardausgabe, obwohl in stderr einige Fehler vorhanden sind.
\10
sollte durch das entsprechende ASCII-Zeichen ersetzt werden, damit das Programm 181 Zeichen enthält.Beispiel-E / A:
Tetromino-Komprimierung: Die
Teile werden als drei Basis-8-Ziffern gespeichert. Dies ist eine einfache binäre Darstellung, z
T=[7,2,0], S=[6,3,0], J=[2,2,3]
.[1]
wird für dasI
Stück in Komprimierung verwendet, dies wird jedoch explizit auf[1,1,1,1]
später gesetzt (dh das4*
im Code). Alle diese Arrays werden zu einem einzigen Array verkettet, das in eine Ganzzahl und dann in eine Zeichenfolge konvertiert wird (Basis 126, um nicht druckbare Zeichen, Länge und nicht auf utf8 zu minimieren). Diese Zeichenfolge ist sehr kurz :"R@1(XBc_"
.Die Dekomprimierung ist dann unkompliziert. Wir führen zuerst eine Basis-126-Konvertierung durch, gefolgt von einer Basis-8-Konvertierung (
"~\10"{base}/
dh durchlaufen"~\10"
und durchlaufen für jedes Element eine Basis-Konvertierung). Das resultierende Array wird in Dreiergruppen aufgeteilt, das Array fürI
ist fest (3/~4*
). Wir konvertieren dann jedes Element in Basis 2 und ersetzen (nach dem Entfernen von Nullen) jede Binärziffer durch das Zeichen dieses Index in der Zeichenfolge" #"
(2base{" #"=}%...-1%
- beachten Sie, dass wir das Array umkehren müssen, sonst2
würde es"# "
statt" #"
).Board / Piece-Format, Droping Pieces
Das Board besteht einfach aus einer Reihe von Zeichenfolgen, eine für jede Zeile. Zunächst wird daran keine Arbeit geleistet, daher können wir es mit
n/(
der Eingabe generieren . Stücke sind auch Anordnungen von Zeichenfolgen, die mit Leerzeichen links für ihre X-Position aufgefüllt sind, jedoch ohne nachgestellte Leerzeichen. Teile werden durch Voranstellen an das Array und kontinuierliches Testen, ob eine Kollision vorliegt, gelöscht.Kollisionstests werden durchgeführt, indem alle Zeichen im Stück durchlaufen und mit dem Zeichen derselben Position auf dem Brett verglichen werden. Wir wollen
#
+=
und#
+#
als Kollisionen betrachten, also testen wir, ob ((piecechar & 3) & boardchar) ungleich Null ist. Während dieser Iteration aktualisieren wir auch (eine Kopie von) der Karte mit ((piecechar & 3) | boardchar), wodurch der Wert für die Paare#
+,
+
#
,+ korrekt festgelegt wird
[
. Wir verwenden dieses aktualisierte Board, wenn es nach dem Verschieben des Teils um eine weitere Reihe zu einer Kollision kommt.Das Entfernen gefüllter Zeilen ist ganz einfach. Wir entfernen alle Zeilen, für die
"= "&
false zurückgegeben wird. Eine gefüllte Zeile hat weder noch=
noch, daher ist die Konjunktion eine leere Zeichenfolge, was false entspricht. Dann zählen wir die Anzahl der entfernten Zeilen, addieren die Anzahl zur Punktzahl und stellen so viele
"[ ... ]"
s voran . Wir erzeugen kompakt diese durch die erste Reihe des Gitters nimmt und Ersetzen#
mit.
Bonus
Da wir berechnen, wie das Brett in jeder Position des Stücks aussehen würde, wenn es fällt, können wir diese auf dem Stapel behalten, anstatt sie zu löschen! Für insgesamt drei weitere Zeichen können wir alle diese Positionen ausgeben (oder zwei Zeichen, wenn die Board-Zustände einen einfachen Abstand haben).
quelle
Perl,
586 523 483 472 427 407 404 386 387 356353 Zeichen(Benötigt Perl 5.10 für den definierten oder
//
Operator).Nimmt alle Eingaben von stdin entgegen.
Braucht noch ernsthaftes Golfen.Es ist zu beachten, dass ^ Q ASCII 17 (DC1 / XON) darstellt, ^ C ASCII 3 darstellt und ^ @ ASCII 0 (NUL) darstellt.
Kommentierte Version:
Edit 1: einige ernsthafte Golfen, Ausgabefehler behoben.
Bearbeiten 2: einige Inlining, zwei Loops zu einem zusammengeführt, um eine Nettoersparnis von (Trommelwirbel ...) 3 Zeichen zu erzielen, sonstiges Golfen.
Edit 3: einige häufige Eliminierungen von Unterausdrücken, ein wenig konstantes Zusammenführen und Optimieren eines regulären Ausdrucks.
Edit 4: Die Darstellung von Tetrominoes wurde in einen gepackten Bitvektor geändert.
Bearbeiten 5: direktere Übersetzung vom Tetromino-Buchstaben zum Array-Index, Verwendung nicht druckbarer Zeichen, sonstiges Golfen.
Edit 6: Fehlerbehebung bei der Fehlerbehebung in r3 (Edit 2), entdeckt von Nakilon. Verwenden Sie mehr nicht druckbare Zeichen.
Edit 7: Verwenden Sie diese
vec
Option, um auf Tetromino-Daten zuzugreifen. Nutzen Sie die Tatsache, dass das Spielfeld feste Abmessungen hat.if
Anweisung =>if
Modifikator, das Zusammenführen von Schleifen von Edit 2 beginnt sich auszuzahlen. Verwenden Sie//
für den Fall mit 0 Punkten.Edit 8: Ein weiterer Fehler wurde behoben, der in r6 (Edit 5) eingeführt wurde und von Nakilon entdeckt wurde.
Bearbeiten 9: Erstellen Sie beim Löschen von Linien keine neuen Referenzen, sondern verschieben Sie Referenzen einfach über das Array-Slicing. Füge zwei
map
zu einem zusammen. Intelligentere Regex. "Klüger"for
. Verschiedene Golfplätze.Edit 10: Inline Tetromino Array, kommentierte Version hinzugefügt.
quelle
Ruby -
427 408 398 369359quelle
Bash-Shell-Skript (
301304 Zeichen)UPDATE: Es wurde ein Fehler behoben, der Teile betraf, die bis in die oberste Reihe reichen. Außerdem wird die Ausgabe jetzt an den Standardausgang gesendet, und als Bonus ist es möglich, das Skript erneut auszuführen, um ein Spiel fortzusetzen (in diesem Fall müssen Sie die Gesamtpunktzahl selbst addieren).
Dies schließt nicht druckbare Zeichen ein, daher habe ich einen Hex-Dump bereitgestellt. Speichern Sie es als
tetris.txt
:Dann an der Bash-Eingabeaufforderung, vorzugsweise mit
elvis
anstattvim
installiert alsvi
:Wie es funktioniert
Der Code extrahiert sich selbst ähnlich wie ausführbare Programme, die mit dem
gzexe
Skript komprimiert wurden . Tetromino-Stücke werden als Sequenzen von vi-Editor-Befehlen dargestellt. Die Zeichenzählung wird verwendet, um Kollisionen zu erkennen, und die Linienzählung wird verwendet, um die Punktzahl zu berechnen.Der entpackte Code:
Der Originalcode vor dem Golfen:
quelle
Python:
504519 Zeichen(Python 3-Lösung)
Derzeit muss die Eingabe in dem oben gezeigten Format eingestellt werden (Eingabecode wird nicht gezählt). Ich werde später erweitern, um aus einer Datei oder einem Standard zu lesen.Funktioniert jetzt mit einer Eingabeaufforderung, fügen Sie einfach die Eingabe ein (insgesamt 8 Zeilen).Ich bin mir nicht sicher, ob ich dort viel mehr sparen kann. Bei der Umwandlung in Bitfelder gehen ziemlich viele Zeichen verloren, aber das spart viel mehr Zeichen als das Arbeiten mit den Zeichenfolgen. Ich bin mir auch nicht sicher, ob ich dort mehr Leerzeichen entfernen kann, aber ich werde es später versuchen.Wird es nicht viel mehr reduzieren können; Nachdem ich die bitfeldbasierte Lösung erhalten hatte, wechselte ich zurück zu Strings, da ich einen Weg fand, sie stärker zu komprimieren (8 Zeichen über dem Bitfeld gespeichert!). Aber da ich vergessen habe, das einzuschließen,
L
und einen Fehler mit den Punkten darin hatte, steigt meine Anzahl an Charakteren nur seufzend ... Vielleicht finde ich später etwas, um es ein bisschen mehr zu komprimieren, aber ich denke, ich bin kurz vor dem Ende. Für den ursprünglichen und kommentierten Code siehe unten:Originalfassung:
quelle
Ruby 1.9,
357355353339330310309 ZeichenBeachten Sie, dass die
\000
Escapezeichen (einschließlich der Null-Bytes in der dritten Zeile) durch ihre tatsächlichen nicht druckbaren Entsprechungen ersetzt werden sollten.Beispieleingabe:
Verwendung:
oder
quelle
?\s
.C,
727 [...] 596 581 556 517 496 471 461457 ZeichenDies ist mein erster Code Golf, ich denke, die Anzahl der Charaktere kann
vielniedriger werden. Es wäre schön, wenn erfahrene Golfer mir einige Hinweise geben könnten.Die aktuelle Version kann auch Spielfelder mit unterschiedlichen Abmessungen verarbeiten.Die Eingabe kann Zeilenumbrüche sowohl im DOS / Windows- als auch im Unix-Format aufweisen.Der Code war vor der Optimierung ziemlich einfach, die Tetrominoes werden in 4 Ganzzahlen gespeichert, die als (7 * 3) x4-Bit-Array interpretiert werden, das Spielfeld wird unverändert gespeichert, Kacheln werden gelöscht und vollständige Zeilen werden zu Beginn und nach jedem entfernt Fliesen fallen.
Ich war mir nicht sicher, wie ich Zeichen zählen sollte, also habe ich die Dateigröße des Codes verwendet, wobei alle unnötigen Zeilenumbrüche entfernt wurden.
EDIT 596 => 581: Dank KitsuneYMG, alles außer dem
%ls
Vorschlag perfekt gearbeitet, zusätzlich habe ich festgestellt ,putch
anstattputchar
verwendet werden (getch
irgendwie nicht funktioniert) und entfernt alle Klammern#define G
.EDIT 581 => 556: War mit den verbleibenden
for
und den verschachteltenF
Schleifen nicht zufrieden , daher wurden einige Schleifen zusammengeführt, geändert und entfernt, ziemlich verwirrend, aber es lohnt sich auf jeden Fall.EDIT 556 => 517: Endlich einen Weg gefunden,
a
ein int-Array zu erstellen. EinigeN;
verschmolzen mitc
, nichtbreak
mehr.EDIT 496 => 471: Spielfeldbreite und -höhe jetzt festgelegt.
EDIT 471 => 461: Kleinere Änderungen,
putchar
wieder verwendet, da diesputch
keine Standardfunktion ist.BEARBEITEN: Bugfix, vollständige Zeilen wurden vor dem Ablegen der Kacheln anstatt nach dem Entfernen entfernt , sodass am Ende vollständige Zeilen verbleiben konnten. Fix ändert die Anzahl der Zeichen nicht.
quelle
for
als#define F(x,m) for(x=0;x++<m;)
? Es funktioniert auf C # ...: PF(x,3){printf("%i",x}
druckt12
statt012
mit dieser Änderung. Könnte sich ändernfor(x=-1;x++<m;)
, aber das spart nichts :)(c=getchar())
und alle c = N Zeilen entfernen, wobei 6 Zeichen gespart werden. Wenn ich mich nicht irre, sollten Sie bis zumPython 2.6+ -
334322316 Zeichen397368366 Zeichen unkomprimiertDer einzelne Zeilenumbruch ist erforderlich, und ich habe ihn als ein Zeichen gezählt.
Mumbo-Jumbo auf der Browser-Codepage verhindert möglicherweise das erfolgreiche Kopieren und Einfügen dieses Codes, sodass Sie die Datei optional aus diesem Code generieren können:
Testen
intetris
Zeilenumbrüche müssen im Unix-Stil erfolgen (nur Zeilenvorschub). Ein nachfolgender Zeilenumbruch in der letzten Zeile ist optional.
Zu testen:
Dieser Code entpackt den Originalcode und führt ihn mit aus
exec
. Dieser dekomprimierte Code wiegt 366 Zeichen und sieht folgendermaßen aus:Zeilenumbrüche sind erforderlich und bestehen jeweils aus einem Zeichen.
Versuchen Sie nicht, diesen Code zu lesen. Die Variablennamen werden auf der Suche nach der höchsten Komprimierung buchstäblich zufällig ausgewählt (bei verschiedenen Variablennamen habe ich nach der Komprimierung bis zu 342 Zeichen gesehen). Eine verständlichere Version folgt:
Der Kern liegt in den drei kryptischen Zeilen, von denen ich sagte, dass ich sie erklären würde.
Die Form der Tetrominoes ist dort in der Hexadezimalzahl kodiert. Es wird angenommen, dass jedes Tetronimo ein 3x4-Gitter von Zellen einnimmt, wobei jede Zelle entweder leer (ein Leerzeichen) oder voll (ein Zahlenzeichen) ist. Jedes Stück wird dann mit 3 hexadezimalen Ziffern codiert, wobei jede Ziffer eine 4-Zellen-Spalte beschreibt. Die niedrigstwertigen Ziffern beschreiben die am weitesten links stehenden Spalten, und das niedrigstwertige Bit in jeder Ziffer beschreibt die oberste Zelle in jeder Spalte. Wenn ein Bit 0 ist, ist diese Zelle leer, andernfalls ist es ein '#'. Zum Beispiel wird das I- Tetronimo so codiert
00F
, dass die vier Bits der niedrigstwertigen Ziffer aktiviert sind , um die vier Zahlenzeichen in der Spalte ganz links zu codieren, und das T ist131
mit dem oberen Bit links und rechts und den beiden oberen Bits in der Mitte.Die gesamte Hexadezimalzahl wird dann um ein Bit nach links verschoben (multipliziert mit zwei). Dadurch können wir das unterste Bit ignorieren. Ich werde gleich erklären, warum.
Wenn wir also das aktuelle Stück aus der Eingabe erhalten, finden wir den Index in dieser Hexadezimalzahl, in der die 12 Bits beginnen, die seine Form beschreiben, und verschieben ihn dann nach unten, sodass die Bits 1–12 (Überspringen von Bit 0) der
bits
Variablen das aktuelle Stück beschreiben.Die Zuordnung zu
drop
bestimmt, wie viele Zeilen vom oberen Rand des Gitters das Stück fallen wird, bevor es auf anderen Stückfragmenten landet. In der ersten Zeile wird angegeben, wie viele leere Zellen sich oben in jeder Spalte des Spielfelds befinden, während in der zweiten Zeile die niedrigste belegte Zelle in jeder Spalte des Stücks angegeben wird. Diezip
Funktion gibt eine Liste von Tupeln zurück, wobei jedes Tupel aus der n- ten Zelle jedes Elements in der Eingabeliste besteht. Wenn Sie also die Sample-Eingangskarte verwenden,zip(board[:6] + [full])
wird Folgendes zurückgegeben:Wir wählen das Tupel aus dieser Liste aus, das der entsprechenden Spalte entspricht, und finden den Index des ersten
'#'
in der Spalte. Aus diesem Grund haben wir vor dem Aufruf eine "vollständige" Zeile angehängtzip
, damitindex
eine sinnvolle Rückgabe (anstatt eine Ausnahme auszulösen) erfolgt, wenn die Spalte ansonsten leer ist.Um dann das niedrigste
'#'
in jeder Spalte des Stücks zu finden, verschieben und maskieren wir die vier Bits, die diese Spalte beschreiben, und verwenden dann diebin
Funktion, um daraus eine Folge von Einsen und Nullen zu machen. Diebin
Funktion gibt nur signifikante Bits zurück, daher müssen wir nur die Länge dieser Zeichenfolge berechnen, um die niedrigste belegte Zelle (höchstwertiges gesetztes Bit) zu finden. Diebin
Funktion steht auch vor'0b'
, also müssen wir das subtrahieren. Wir ignorieren auch das niedrigstwertige Bit. Aus diesem Grund wird die Hexadezimalzahl um ein Bit nach links verschoben. Dies dient dazu, leere Spalten zu berücksichtigen, deren Zeichenfolgendarstellungen dieselbe Länge wie eine Spalte haben würden, in der nur die oberste Zelle voll ist (z. B. das T- Stück).Zum Beispiel werden die Spalten der ich erwähnt tetromino, wie früher, sind
F
,0
und0
.bin(0xF)
ist'0b1111'
. Nachdem'0b'
wir das ignoriert haben , haben wir eine Länge von 4, was richtig ist. Istbin(0x0)
aber0b0
. Nachdem'0b'
wir das ignoriert haben , haben wir immer noch eine Länge von '1, was falsch ist. Um dies zu berücksichtigen, haben wir am Ende ein zusätzliches Bit hinzugefügt, damit wir dieses unbedeutende Bit ignorieren können. Daher ist das+3
im Code dazu da, die zusätzliche Länge zu berücksichtigen, die'0b'
am Anfang und das unbedeutende Bit am Ende benötigt wird.All dies geschieht innerhalb eines Generatorausdrucks für drei Spalten (
(0,1,2)
), und wir ermittelnmin
anhand des Ergebnisses die maximale Anzahl von Zeilen, die das Stück ablegen kann, bevor es in einer der drei Spalten berührt wird.Der Rest sollte durch Lesen des Codes ziemlich leicht zu verstehen sein, aber die
for
Schleife, die diesen Zuweisungen folgt, fügt das Stück der Tafel hinzu. Danachwhile
entfernt die Schleife volle Zeilen, ersetzt sie durch leere Zeilen oben und zählt die Punktzahl. Am Ende werden die Tafel und die Partitur auf die Ausgabe gedruckt.quelle
Python, 298 Zeichen
Schlägt alle bisher nicht- esoterischen Sprachlösungen (Perl, Ruby, C, Bash ...)
... und verwendet nicht einmal Schikanen mit Code-Zipping.
Am Testbeispiel
es gibt aus
PS. Es wurde ein Fehler behoben, auf den Nakilon mit einem Preis von +5 hingewiesen hatte
quelle
Golfscript 260 Zeichen
Ich bin mir sicher, dass dies verbessert werden könnte. Ich bin ein bisschen neu in Golfscript.
Zeilenende sind relevant (es sollte keine am Ende geben). Wie auch immer, hier sind einige der Testfälle, die ich verwendet habe:
Beachten Sie, dass die Eingabedatei kein Zeilenende enthält. Ein Zeilenende würde das Skript unverändert beschädigen.
quelle
O'Caml
809782quelle
Common Lisp
667 657645 ZeichenMein erster Versuch, Code Golf zu spielen, daher gibt es wahrscheinlich viele Tricks, die ich noch nicht kenne. Ich habe dort einige Zeilenumbrüche hinterlassen, um die verbleibende "Lesbarkeit" zu gewährleisten (ich habe Zeilenumbrüche als 2 Byte gezählt, sodass durch das Entfernen von 6 unnötigen Zeilenumbrüchen 12 weitere Zeichen erhalten werden).
Geben Sie bei der Eingabe zuerst die Formen und dann das Feld ein.
Testen
quelle
Ruby
505 479 474 442 439426 ZeichenEin erster Versuch. Habe es mit IronRuby gemacht. Ich bin sicher, dass es verbessert werden kann, aber ich sollte heute wirklich etwas Arbeit erledigen!
Testen
Jetzt mit normalem Rubin bearbeiten . Habe die Wände ausgegeben ..
quelle
Ein anderer in Ruby,
: **573546 ZeichenTesten:
quelle
a.each{|x|s=a.max_by(&:size).size;x[s-=1]||=' 'while s>0}