Schreiben Sie das kürzeste Programm, um aus jedem ASCII-Kunstwerk eine animierte Schneeszene zu machen, die sich aus dem fallenden Schnee zu formen beginnt ( JavaScript-Beispiel ohne Golfspiel, zuletzt aktualisiert am 19.12.2011).
Eingabespezifikation : Ihr Programm muss beliebige Kombinationen von Leerzeichen, Sternchen und Zeilenumbrüchen akzeptieren. Die Eingabe enthält höchstens 23 Zeilen und 80 Zeichen pro Zeile. Es werden keine Leerzeilen angezeigt, die Zeilen dürfen jedoch nur aus Leerzeichen bestehen. Eine einzelne nachgestellte Zeile wird eingefügt und muss ignoriert werden.
Ausgabe : Geben Sie ASCII-Zeichen (Leerzeichen, Sternchen) und Steuercodes (Zeilenumbrüche, Zeilenvorschübe, ANSI-Escape-Codes usw.) für die Textkonsole oder den Terminal-Emulator Ihres Betriebssystems aus, bis der Benutzer das Programm manuell beendet. Sie können davon ausgehen, dass das Terminalfenster 80 x 24 Zeichen umfasst, wenn Ihr Betriebssystem diese Einstellung zulässt.
Regeln :
- Die Animation muss flüssig und schnell sein (15 fps bevorzugt).
- Die Schneedichte muss zwischen 5% und 15% liegen.
- Es darf nicht mehr als ein Schneebildschirm pro Sekunde angezeigt werden. (Das bedeutet, dass in einem Zeitraum von einer Sekunde nicht mehr als 24 Zeilen Neuschnee hinzugefügt werden dürfen.)
- Der Schnee darf kein offensichtliches Muster aufweisen, wenn er oben auf dem Bildschirm eintritt. es muss zufällig aussehen.
- Das Programm muss alle Zeilen des Bildschirms so schnell wie möglich mit Schnee füllen, wenn es startet. Das anfängliche Füllen der einzelnen Zeilen des Bildschirms darf für den Betrachter nicht offensichtlich sein.
- Die untere linke Ecke der ASCII-Eingabekunst muss sich in der unteren linken Ecke des Bildschirms befinden (Abbildung 1 zur weiteren Verdeutlichung).
- Der Bereich innerhalb oder unter der ASCII-Grafik darf nicht dauerhaft mit Sternchen ausgefüllt sein. Sternchen können (müssen aber nicht) durch diesen Bereich scrollen.
- Schnee darf sich nicht am unteren Bildschirmrand oder auf vorhandenem Schnee ansammeln, außer wie in der Eingabe angegeben.
- Die unteren Felder müssen vor den oberen ausgefüllt werden, da das Ausfüllen der Felder in umgekehrter Reihenfolge dazu führt, dass die Weihnachtsbaumanimation sich stark von der Ausgabe meines ursprünglichen Codes unterscheidet. (hinzugefügt am 20.12.2011)
Schöne Ferien!
Abbildung 1: Beschriftete Bereiche eines 80x24-Bildschirms
---------------------------New snow added on this line--------------------------
|
|
----------------------------------------------------------+ |
**** | |
Snow MUST fall Snow MAY fall ----------------> **** | |
through this through these **** **** | Snow MUST fall |
area. areas of a **** **** | through this |
completed \---------> **** ****| area. |
ASCII art scene. \ *** **** ****| |
area \ \ ******* **** ****| |
\ \ ******** *** ***| (ALL CAPS terms |
(located in \ \--> ********* *** | have standard |
lower left \ ******* ****** MAY | RFC 2119 |
corner of \ ************* ** fall | meanings.) |
screen) \ *********** here | |
*** +---> **** *** | |
*** | **************** *** | |
| Snow MUST fall *** | **************** *** | |
| through this *** +---> *** | |
| area. *** | **************** *** | |
--+---------------------+*** +---> ***+----+------------------+--
| Snow MUST NOT |****************************| Snow MUST NOT |
V accumulate here. |****************************| accumulate here. V
Beispieleingaben
Code Golf Banner
****** ******* ******** ******** ****** ******* ** ********
** ** ** ** ** ** ** ** ** ** ** ** **
** ** ** ** ** ** ** ** ** ** **
** ** ** ** ** ****** ** **** ** ** ** ******
** ** ** ** ** ** ** ** ** ** ** **
** ** ** ** ** ** ** ** ** ** ** ** **
****** ******* ******** ******** ****** ******* ******** **
Stapelüberlauf-Logo
****
****
**** ****
**** ****
**** ****
*** **** ****
******* **** ****
******** *** ***
********* ***
******* ******
************* **
***********
*** **** ***
*** **************** ***
*** **************** ***
*** ***
*** **************** ***
*** ***
****************************
****************************
Weihnachtsbäume
*
*** *
* ***** ***
*** ******* * *****
***** ********* *** *
* *********** *****
* ************* *******
* *** *************** * *
*** ***** ***************** ***
***** ******* ******************* *****
******* * ********************* *******
********* * *********
* *
Antworten:
Perl, 196/239 Zeichen
Diese Lösung unterscheidet sich von Ihrem JS-Beispiel darin, dass das Muster von oben nach unten und nicht von unten nach oben gefüllt wird. Ich gehe jedoch davon aus, dass dies in Ordnung ist, da Sie in den Regeln nichts dazu gesagt haben.
Durch Ersetzen
\e
mit einem wörtlichen ESC-Zeichen kann eine triviale 1- Zeichen -Reduzierung erzielt werden , was jedoch das Lesen und Bearbeiten des Codes erheblich erschwert.Update: Ich habe es geschafft, eine Version zu entwickeln, die das Muster von unten nach oben ausfüllt und es nicht zulässt, dass Schnee durch die gefüllten Teile des Musters fällt, wie in der JS-Beispielimplementierung, und das kostet 43 zusätzliche Zeichen:
Ersetzen
($s[$_]&=~$f[$_])
mit nur$s[$_]
würde 11 Zeichen einsparen, indem fallender Schnee durch die gefüllten Teile des Musters geleitet wird (was der Spezifikation entspricht, aber nicht der Beispielimplementierung).OK, da ich nach einer Woche immer noch an der Spitze des Rennens zu stehen scheine, sollte ich erklären, wie meine Lösung funktioniert, um mehr Wettbewerb zu fördern. (Hinweis: Diese Erklärung gilt für die Top-Down-Füllversion mit 196 Zeichen. Ich kann sie dahingehend ändern, dass sie später die andere Version enthält.)
Zunächst einmal besteht der große Trick, auf dem meine Lösung basiert, darin, dass aufgrund der Anordnung der ASCII-Zeichencodes die 1-Bits im ASCII-Code für ein Leerzeichen zufällig eine Teilmenge derjenigen im Code für ein sind Sternchen.
Somit sind die folgenden Ausdrücke wahr:
" " & "*" eq " "
und" " | "*" eq "*"
. Auf diese Weise kann ich bitweise Zeichenfolgenoperationen zum Kombinieren der statischen und sich bewegenden Teile der Szene verwenden, ohne einzelne Zeichen durchlaufen zu müssen.Lassen Sie uns nun den Code durchgehen. Hier ist eine entgolfte Version davon:
Die erste Zeile richtet die Arrays
@f
(für "fixed") und@p
(für "pattern") ein.@f
bildet den festen Teil der Anzeige und enthält zunächst nur Leerzeichen, während@p
das Eingabemuster nicht direkt angezeigt wird. Mit fortschreitender Animation werden wir immer mehr Sternchen hinzufügen,@f
bis es schließlich so aussieht@p
.Insbesondere
@f = ($" x 80) x 23
setzt@f
bis 24 Saiten 80 Räume jeweils. ($"
ist eine spezielle Perl-Variable, deren Standardwert zufällig ein Leerzeichen ist.) Wir nehmen diese Liste, hängen die Eingabezeilen mit dem readline-Operator an<>
, nehmen die letzten 24 Zeilen dieser kombinierten Liste und weisen sie zu@p
: this is Eine kompakte Möglichkeit,@p
leere Linien einzufügen, damit das Muster dort angezeigt wird, wo es sollte. Schließlich müssen wirchomp
die Eingabezeilen@p
eingeben, um alle nachgestellten Zeilen zu entfernen, damit sie später keine Probleme verursachen.Schauen wir uns nun die Hauptschleife an. Es stellt sich heraus, dass dies
{...;redo}
ein kürzerer Weg ist, eine Endlosschleife zu schreiben alswhile(1){...}
oder sogarfor(;;){...}
, besonders wenn wir das Semikolon vorher weglassen müssen,redo
weil es unmittelbar auf einenif
Block folgt .In der ersten Zeile der Hauptschleife wird das Array
@s
(natürlich für "snow") eingefügt, dem bei jeder Iteration eine zufällige 80-stellige Zeichenfolge mit 90% Leerzeichen und 10% Sternchen vorangestellt wird. (Um ein paar Zeichen zu sparen, platziere ich eigentlich nie zusätzliche Zeilen am Ende des@s
Arrays, damit es immer länger wird. Das wird das Programm schließlich zum Stillstand bringen, da das Array zu lang wird, um in den Speicher zu passen, aber das wird viel länger dauern als die meisten Menschen jemals diese Animation aufpassen würde. eine Hinzufügenpop@s;
Aussage vor demselect
hinzufügen, wird dies auf Kosten von sieben Zeichen behoben.)Der Rest der Hauptschleife wird in einen
if
Block eingeschlossen, sodass er nur ausgeführt wird, wenn das@s
Array mindestens 24 Zeilen enthält. Dies ist eine einfache Möglichkeit, die Spezifikation einzuhalten, die es erfordert, dass das gesamte Display von Anfang an mit fallendem Schnee gefüllt ist, und vereinfacht auch die bitweisen Operationen ein wenig.Als nächstes folgt eine
foreach
Schleife, die in der Golfversion eigentlich eine einzelne Anweisung mit einemfor 0..23
Modifikator ist. Da der Inhalt der Schleife wahrscheinlich eine Erklärung benötigt, werde ich ihn weiter unten etwas entpacken:Zunächst
$_
ist dies die Standardvariable für den Schleifenzähler in Perl, sofern keine andere Variable angegeben ist. Hier läuft es von 0 bis 23, also über die 24 Zeilen im Displayrahmen.$foo[$_]
bezeichnet das Element, das$_
im Array durch indiziert ist@foo
.In der ersten Zeile der entgolften Schleife drucken wir entweder eine neue Zeile (zweckmäßigerweise aus der
$/
speziellen Variablen) oder, wenn$_
gleich 0, die Zeichenfolge"\e[H"
, wobei\e
ein ESC-Zeichen bezeichnet wird. Dies ist ein ANSI-Terminal-Steuercode , mit dem der Cursor in die linke obere Ecke des Bildschirms bewegt wird. Technisch könnten wir das weglassen, wenn wir eine bestimmte Bildschirmgröße annehmen würden, aber ich habe es in dieser Version beibehalten, da dies bedeutet, dass ich die Größe meines Terminals nicht ändern muss, um die Animation auszuführen.In der
$t = $f[$_]
Zeile speichern wir nur den aktuellen Wert von$f[$_]
in einer "temporären" Variablen (daher$t
), bevor wir ihn möglicherweise in der nächsten Zeile ändern, wo$s[$_] & $p[$_]
der Schnittpunkt (bitweises UND) des fallenden Schnees und des Eingabemusters sowie die|=
Operator-ODERs angegeben werden das in die feste Ausgangsleitung$f[$_]
.In der Zeile darunter wird
$t ^ $f[$_]
das bitweise XOR des vorherigen und des aktuellen Werts von angegeben$f[$_]
, dh eine Liste der in der vorherigen Zeile geänderten Bits, falls vorhanden, und das Negieren einer der Eingabezeichenfolgen mit~
negiert die Ausgabe. Wir erhalten also eine Bitmaske, bei der alle Bits auf 1 gesetzt sind, mit Ausnahme derjenigen, die wir gerade in$f[$_]
der vorherigen Zeile hinzugefügt haben . Durch UND-Verknüpfung dieser Bitmaske werden$s[$_]
diese Bits entfernt. Tatsächlich bedeutet dies, dass eine fallende Schneeflocke, wenn sie ein Loch im festen Muster ausfüllt, aus dem Fallschnee-Array entfernt wird.Schließlich wird
print $f[$_] | $s[$_]
(was in der Golfversion durch einfaches ODER-Verknüpfen der beiden vorherigen Zeilen implementiert wird) nur die Vereinigung (bitweises ODER) der festen und sich bewegenden Schneeflocken in der aktuellen Zeile gedruckt.Eine weitere zu erklärende Sache ist die
select '', '', '', 0.1
unterhalb der inneren Schleife. Dies ist nur eine mühsame Methode, um in Perl 0,1 Sekunden zu schlafen. Aus irgendeinem dummen historischen Grund hat der Standard-Perl-sleep
Befehl eine Auflösung von einer Sekunde, und das Importieren eines besserensleep
aus demTime::HiRes
Modul erfordert mehr Zeichen als der Missbrauch von 4-Argumentenselect
.quelle
say
), und zwar zum Preis von 2 zusätzlichen Zeichen. Ich glaube jedoch nicht, dass ich die Füllreihenfolge leicht ändern kann. meine umsetzung ist eher grundlegend daran gebunden.HTML und JavaScript, 436 Zeichen
Stellen Sie es der Eingabe voran:
Sehen Sie, wie es für jedes Beispiel ausgeführt wird: Codegolf , Stack Overflow-Logo , Weihnachtsbäume . Internet Explorer-Benutzer müssen Version 9 ausführen und den "Dokumentmodus" auf "IE9-Standards" setzen (mithilfe der F12-Entwicklertools), damit diese Übermittlung ordnungsgemäß funktioniert.
quelle
Python, 299 Zeichen
Dies sollte den Regeln entsprechen, vorausgesetzt, der Zeilenumbruch ist im 80-Zeichen-Limit enthalten.
quelle
a
und so die Indizierung durcheinander bringt . Ich habe es gerade ausprobiert und es sieht so aus, als ob das Ersetzen%e
durch%e.rstrip()
Zeile 6 das Problem behebt. (Natürlich kann es auch einen kürzeren Fix geben; ich bin kein guter Python-Golfer.)Java, 625 Zeichen
Eine einfache Lösung in Java.
quelle
"\033[H"
sollte beim Drucken geschehen).