Lassen Sie uns animieren!

8

Die Herausforderung

GIFs sind das am häufigsten verwendete Bildformat für Animationen und werden in den heutigen sozialen Medien ziemlich häufig verwendet. Für diese Herausforderung werde ich neu definieren, was ein GIF sein kann. Für diese Herausforderung müssen Sie ein 3D-Array aufnehmen, das eine Art Darstellung eines 2D-Bilds enthält, und diese durchlaufen und eine Animation anzeigen. Diese Animation kann überall ausgeführt werden, in einem GIF, in Ihrer Konsole, in einer GUI usw.; Die Lieferung spielt keine Rolle, solange sie animiert ist.

Die Eingabe

  • Ein 3D-Array, in dem die darin enthaltenen Daten irgendwie ein 2D-Bild darstellen.
    • Das Array kann RGB-Daten, True / False-Daten oder alles andere enthalten, was Sie für richtig halten.
    • Mir geht es auch gut, wenn Sie es auf ein 2D-Array von Zeichenfolgen oder ähnliches reduzieren, aber die Animation muss eine 2D-Animation sein .
  • Die Zeit zwischen den einzelnen Bildern in einem Format Ihrer Wahl (Sekunden, Millisekunden usw.).
    • Die Leute haben mich gefragt, ob sie die Dauer angeben müssen oder nicht. Meine Antwort lautet "meh", solange Sie Animationen anzeigen können. Ich mache mir mehr Sorgen, dass Sie sich an den Parameter "Array" halten als an diesen, was bedeutet, dass keine zufälligen Animationen vorhanden sind.

Die Ausgabe

  • Eine nahtlos iterierte Sequenz von Ausgaben, die wie eine 2D-Animation mit der richtigen Verzögerung bei jedem Übergang basierend auf der Werteingabe aussieht.

Die Regeln

  • Die Ausgabe kann sein, ist aber nicht beschränkt auf:
    • GIF-Bild.
    • GUI-Animation (mein Beispiel).
    • In-Console-Animation.
    • Ehrlich gesagt, jede "Animation", die Sie für richtig halten, solange sie den folgenden Regeln folgt.
  • Wenn Sie Ihr Bild ausgeben, müssen Sie die Konsole löschen, bevor Sie das nächste Bild anzeigen. Sie können sie nicht einfach nacheinander drucken.
    • Das Emulieren einer Konsole "clear" ist ebenfalls akzeptabel, solange sie wie eine nahtlose Animation aussieht (weitere Informationen zu meinen Begriffen finden Sie im Hinweis unter meinem Beispiel).
  • Unabhängig von der Implementierung sollte Ihre Animation für immer oder bis zum Stopp wiederholt werden.
    • Die "Schleife" kann so einfach wie while(true){}oder unendlich rekursiv sein. Sie können davon ausgehen, dass der Benutzer dieses Meisterwerk anzeigen möchte, bis er "Strg + C" drückt.
  • Sie müssen in der Lage sein, 2D-Bilder jeder Größe zu verarbeiten. Wenn Ihre Sprache durch Puffergrößen begrenzt ist, ist dies akzeptabel und Sie können dies in Ihrer Erklärung angeben.
  • Standardlücken sind nicht zulässig.

Beispiel E / A.

Eingabe (3D-Array, Verzögerung)

f([
  [[1,0,0],
   [0,0,0],
   [0,0,0]],
  [[0,0,0],
   [0,1,0],
   [0,0,0]],
  [[0,0,0],
   [0,0,0],
   [0,0,1]],
], 1)

Ausgabe (Beispiel, 2020 Bytes - Java)

import javax.swing.JFrame;
import javax.swing.JTextArea;

/**
 * Simple GIF class to animate a 3D integer array in a swing text area.
 * (Clearing the console in java isn't something you really do, so I chose
 * java on purpose to make it an extremely ungolf-able answer that someone
 * wouldn't bother to steal).
 */
public class Gif implements Runnable {
    /**
     * The output area.
     */
    private final JTextArea area;

    /**
     * The list of images.
     */
    private final int[][][] images;

    /**
     * The delay between image transitions.
     */
    private final long transitionDelay;

    /**
     * Main method, instantiates a GIF object and runs it.
     * @param args Does absolutely nothing.
     */
    public static void main(String[] args) {
        final int[][][] images = {{{1,0,0},{0,0,0},{0,0,0}},{{0,0,0},{0,1,0},{0,0,0}},{{0,0,0},{0,0,0},{0,0,1}}};
        final long transitionDelay = 1000L;
        new Thread(new Gif(images, transitionDelay)).start();
    }

    /**
     * Constructor for a GIF, takes in a 3D array of images and a transition
     * delay to wait between transitioning the images.
     * @param images The list of images.
     * @param delay The delay between each image.
     */
    public Gif(int[][][] images, long transitionDelay) {
        this.images = images;
        this.transitionDelay = transitionDelay;
        this.area = new JTextArea();
        final JFrame frame = new JFrame("It's a GIF!");
        frame.setSize(10,100);
        frame.add(area);
        frame.setVisible(true);
    }

    /**
     * When run, it will alter the area to imitate an animated GIF.
     */
    @Override
    public void run() {
        while (true) {
            for (int i = 0; i < images.length; i++) {
                final StringBuffer frame = new StringBuffer();
                for (int j = 0; j < images[i].length; j++) {
                    for (int k = 0; k < images[i][j].length; k++) {
                        frame.append("" + images[i][j][k]);
                    }
                    frame.append("\n");
                }
                this.area.setText(frame.toString());
                try{Thread.sleep(transitionDelay);}catch(Exception e){}
                this.area.setText("");
            }
        }
    }
}

Dies führt dazu, dass eine Swing-GUI angezeigt wird, die das Array animiert:

Frame One Rahmen zwei Bild drei

TIPP TIPP: Verwenden Sie eine Sprache, in der das Löschen der Konsole möglich ist, oder geben Sie an, warum das, was Sie tun, zu einem Ergebnis führt, das wie eine Animation in der von Ihnen ausgewählten Sprache aussieht. Ich denke, einige Sprachen haben Standardpuffergrößen auf ihren Konsolen. Sie können dies zu Ihrem Vorteil nutzen, aber ich erwarte eine Erklärung oder ein Beispiel. Nur weil ich meine Animation als Zeichenfolge ausgebe, müssen Sie das nicht tun. Ich hätte genauso gut 0 für Schwarz und 1 für Weiß verwenden und ein echtes GIF erstellen können.

Richten

Dies ist Code-Golf, niedrigste Byte-Anzahl gewinnt (Eingaben ausgeschlossen).
Ich werde +1 jeden, der eine Sprache auch cool oder unerwartet benutzt.

Magische Krakenurne
quelle
Wie viele Zeilen lang muss das "Klar" sein? Kann es der Anzahl der Zeichen pro Zeile entsprechen?
Riley
Ähnliche Herausforderung mit strengeren Eingaben: codegolf.stackexchange.com/questions/27101/…
luser droog
@ Riley Ich bin nicht sicher, ob ich verstehe, was du fragst. Das Klare ist im Wesentlichen, die Ausgabe auf derselben Linie zu halten; Ihr Code "löscht" möglicherweise nichts, sondern ersetzt ihn auch in der Zeile. Es ist mir egal, wie Sie die Animation erstellen, mehr als dass sie im Wesentlichen mithilfe von Frames funktioniert.
Magic Octopus Urn
@luserdroog Ich hatte das nicht gesehen, aber ich habe auch eines auf "create a snowscene" gesehen, aber ich sehe es auch nicht so nah genug, um es zu rechtfertigen, dies nicht zu veröffentlichen.
Magic Octopus Urn
1
@carusocomputing Keine Sorge, mehr als glücklich, die Grammatikprüfung durchzuführen. Ist es übrigens wichtig, welche Sprache für die Animation verwendet wird, wenn sie nicht mehr im allgemeinen Sprachgebrauch verwendet wird?
Monomeeth

Antworten:

3

MATL , 16 12 11 Bytes

`G@)D1Y.XxT

Die Eingabe ist ein Zellenarray von 2D. Zum Beispiel:

{[1 0 0; 0 0 0; 0 0 0] [0 0 0; 0 1 0; 0 0 0] [0 0 0; 0 0 0; 0 0 1]}

Die Pausenzeit ist 1im Code angegeben. Es kann in eine beliebige reelle Zahl geändert werden, z. B. .5oder `.2.

Probieren Sie es bei MATL Online aus! (Wenn es nicht funktioniert, aktualisieren Sie die Seite und drücken Sie erneut "Ausführen".)

Die Eingabe kann auch ein Zellenarray von 2D-Zeichenarrays sein. Zum Beispiel:

{['x...';'+...';'....';'....'] ['+x..';'....';'....';'....'] ['.+x.';'....';'....';'....'] ['..+x';'....';'....';'....'] ['...+';'...x';'....';'....'] ['....';'...+';'...x';'....'] ['....';'....';'...+';'...x'] ['....';'....';'....';'..x+'] ['....';'....';'....';'.x+.'] ['....';'....';'....';'x+..'] ['....';'....';'x...';'+...'] ['....';'x...';'+...';'....']}

Versuchen Sie auch dieses!

Erläuterung

`       % Do...while
  G     %   Push input: cell array
  @     %   Push iteration index
  )     %   Index to obtain that cell. This uses modular indexing,
        %   so each cell is addressed cyclically
  D     %   Display
  1     %   Push 1: number of seconds to pause
  Y.    %   Pause for that many seconds
  Xx    %   Clear screen
  T     %   True. This is used as loop condition: infinite loop
        % End. Implicitly end do...while loop  
Luis Mendo
quelle
1
Können Sie mit meinem Trick ein paar Bytes sparen? Füllen Sie die Matrix mit [0.2 0 0.2;0 0.2 0] ... und reduzieren Sie sie xxauf xund vermeiden Sie 1Gund 2G? Ich glaube, es hält sich an die Regeln. Sie müssen ein paar Bytes zu geben, um zu konvertieren 0.2zu 1, es sei denn , Sie wollen 0.2natürlich springen herum, und eine Möglichkeit , die Pausieren Wert zu speichern. Ich denke immer noch, dass es die Anzahl der Bytes reduzieren könnte :)
Stewie Griffin
1
@Weeingitfirst Danke! Nun, die Herausforderung spezifiziert zwei Eingaben: das Array und die Pause, also denke ich, dass beide benötigt werden. Warten wir trotzdem auf die Bestätigung
Luis Mendo
2
Beeindruckend. Sie haben den Auftrag perfekt befolgt und sich sogar an die Eingaben gehalten. Dies ist eine sehr beeindruckende Antwort. Auf jeden Fall wird es schwer zu schlagen sein, und im Vergleich zu Antworten, die keine Pausendauer enthielten, ist dies im Grunde genommen fehlerfrei, Bravo.
Magic Octopus Urn
1
@carusocomputing Großartig! Danke für die Information. 4 Bytes aus! Die Dauer kann noch geändert werden, es ist ziemlich offensichtlich im Code
Luis Mendo
1
Ich werde ehrlich sein, ich bezweifle, dass dies übertroffen wird, also markiere ich dies bis zu weiteren Einsendungen als beste Antwort.
Magic Octopus Urn
2

Oktave, 56 54 47 Bytes

Die Möglichkeit zur Eingabe der Pausenzeit als Teil der Eingabematrix wurde entfernt. Ich war sehr zufrieden damit, schauen Sie also in den Bearbeitungsverlauf, wenn Sie einen Blick darauf werfen möchten. Diese Lösung ist 7 Bytes kürzer.

n=input('');while(any(n=~n))spy(n);pause(1);end

n=input('');  % Takes input as a matrix of zeros and ones

k=n(1);       % maximum of the input matrix is the desired pause time. Have to store
              % this, because n is soon to be messed with
              % NOTE: k=n(1); is not needed anymore, since the pause time can be hardcoded!

any(n=~n)     % Check if there are any truthy values in `n` (there is), and at the 
              % same time negate it, thus creating a matrix where all elements
              % alternates between 1 and 0.
while(any(n=~n))   % Loop as long as there are any non-zero elements (always some)
spy(n)        % Create a spy-plot where all non-zero elements are shown as a dot
pause(1)      % Pauses for k seconds
end           % ends the loop (will never happen, since it's infinite).

Die Eingabe sieht ungefähr so ​​aus: [4 0 0 4;0 4 4 0;4 0 0 0]Dabei handelt es sich um eine Matrix mit den Abmessungen 3x4, und die gewünschte Pausenzeit beträgt 4 Sekunden.

Es zeigt ein Diagramm wie das folgende an, wechselt jedoch zwischen der Anzeige der wahren und der falschen Werte der Eingabe. So werden alle blauen Punkte in der nächsten Iteration weiß, und alle weißen Punkte werden blau.

In der folgenden Darstellung habe ich die Eingabe verwendet rand(10,10)>0.6*2. Dies bedeutet, dass es Dimensionen 10x10 hat und alle Elemente der Zufallsmatrix, die größer als 0,6 sind, wahr sind. Danach multipliziere ich es mit der gewünschten Pausenzeit von 2 Sekunden. Ich habe hier eine Zufallsmatrix verwendet, aber ich hätte die Matrix auch manuell erstellen können.

Ich habe Octave nicht auf diesem Computer installiert, daher habe ich eine geringfügige Änderung vorgenommen, damit dies in MATLAB funktioniert. Es ist genau das gleiche Prinzip, n=~nfunktioniert aber in MATLAB nicht.

Geben Sie hier die Bildbeschreibung ein

Geben Sie hier die Bildbeschreibung ein

Stewie Griffin
quelle
2
@carusocomputing, muss ich die Pausenzeit als Eingabe nehmen oder kann ich sie selbst auswählen? Zum Beispiel immer 1 Sekunde haben?
Stewie Griffin
1
@carusocomputing, auch: Ist es in Ordnung, den Benutzer die Pausenzeit auswählen zu lassen, aber nicht als separaten Parameter? Meiner nicht so bescheidenen Meinung nach gilt dies als: "eine coole oder unerwartete Art" ;-)
Stewie Griffin
1
Ja, ich stimme vollkommen zu, das qualifiziert; Solange Sie dem Benutzer erlauben, einen Parameter für die Eingabe anzugeben, und dieser nicht vollständig zufällig ist, ist er meiner Meinung nach in Ordnung. Der springende Punkt der Pause war, die Animation sehen zu können. Ich wollte keine for-Schleifen, in denen Leute sagen: "Nun, man kann es nicht sehen, aber es ist definitiv animierend."
Magic Octopus Urn
1
Ich mochte auch Ihre beiden Ideen; Der "TV Static Generator" war eine sehr einzigartige Implementierung mit Randomisierung, die ich nicht einmal in Betracht gezogen habe. Dies ist auch insofern beeindruckend, als Sie es geschafft haben, die erste Iteration durchzuführen und sich näher an den Auftrag zu halten. Großartiger Job, Mann.
Magic Octopus Urn
2

sed 141 134 90

-51 dank seshoumara

/^$/!{H;d}
:;/^$/g;s,^\n,,;s,$, ,;s,^,\d27[2J,p
:p;P;s,[^\n]*\n,,;/^ \n/!bp;N;s,[ \n]*,,;b

Eingabe: Nimmt zuerst jedes Bild, das durch eine Zeile mit einem Leerzeichen getrennt ist, und zeigt dann das nächste Bild an, nachdem jede leere Zeile empfangen wurde (sieht aus wie ein Daumenkino). Mindestens 3 Frames.

Standardmäßig hat mein System (Windows 7) beim Öffnen von Cygwin 24 Zeilen vertikal. Zwischen den Frames werden immer mindestens so viele Leerzeilen gedruckt. Dadurch wird der Bildschirm effektiv gelöscht.

Über 1/3 der Bytes stammen aus dem Löschen der Konsole. Ich bin sicher, es gibt einen besseren Weg.

Riley
quelle
1
Sie können 1 Byte reduzieren, indem Sie den ersten pBefehl als Teil von verwenden s///p, plus 6 Bytes mehr, indem Sie /^\n/!vorher entfernen P, was meiner Meinung nach nicht benötigt wird. Für die Anstrengung +1, obwohl ich mir auch sicher bin, dass es einen besseren Weg gibt.
Seshoumara
1
Nach einiger Zeit im Internet habe ich eine einfache Möglichkeit gefunden, den Cursor des Terminals zu manipulieren und damit auch einen Bildschirm zu löschen: die Verwendung von ANSI-Escape-Sequenzen. Der Mechanismus wird auch zum Drucken von Text in Farben verwendet. Bitte sehen Sie meine Antwort für Details und ein Beispiel Verwendung. Ich weiß nicht, ob sie auf Cygwin arbeiten, aber Sie können es versuchen.
Seshoumara
@seshoumara Es funktioniert in Cygwin, wenn es von kommt sed, aber aus irgendeinem Grund funktioniert es nicht mit catoder echo.
Riley
Versuchen Sie es echo -e "\e[2Jtest". Bei cat muss sich das Escape-Zeichen bereits in der Datei / Eingabe befinden. Versuchen Sie, echo -e "\e[2Jtest"|cat -nnach oben zu scrollen.
Seshoumara
@seshoumara Ich wusste, dass es so etwas sein musste. Vielen Dank!
Riley
2

GNU sed, 88 84 + 1 (n Flag) = 85 Bytes

Edit: 3 Bytes weniger dank Riley

H;1h;${:
g;s:\n.*::;H;x;s:[^\n]*\n::;x;y:,:\n:;s:^:ESC[2J:;s:ESC:\d27:gp;esleep 1
b}

Das Eingabeformat ist ein Animationsrahmen pro Zeile. Verwenden Sie für mehrere Ausgabezeilen in einem Frame Komma als Trennzeichen. Da ich das Programm in einer Linux-Konsole ausführe, hängt die maximal verfügbare Bildgröße (gemessen in Zeilen und Spalten) von der Größe des Terminalfensters ab. Die Pause zwischen zwei Frames wird mit dem Befehl sleep shell ausgeführt. um einen schnelleren Animationsanruf zu erhalten esleep 0.4(Sekunden).

100,000,000            # The timer could be read from the input as well, but that
000,010,000            #would require a lot more bytes and I understand I'm allowed
000,000,001            #to hardcode the value.

Das Beste daran ist, dass ich Farbanimationen unterstütze! Zu diesem Zweck habe ich die sogenannten ANSI-Escape-Sequenzen verwendet , um die Textschriftart, die Vordergrund- und Hintergrundfarbe sowie die Position des Cursors zu steuern und so den Bildschirm vor jedem Frame (Code ESC[2J) zu löschen . Um Farbinformationen hinzuzufügen, verwenden Sie das folgende Format in dem Eingang, der besser erklärt hier .

ESC[$FORMATm$textESC[0m     # 'ESC' is an actual string, it is then replaced
                            #in sed by the character with the ASCII value 27

Lauf:

sed -nf animate.sed input.txt

Beispiele: Für jeden Test wurden 2 Animationszyklen auf dem Bildschirm erfasst und im Bild-GIF-Format gespeichert (Entschuldigung für die niedrige Auflösung).

0,4 Sekunden Pause Alles Gute zum Geburtstag!

Standardmäßig 1 Sekunde "Pixel" -Bewegung

Erläuterung:

H;1h                           # read each line/frame and store them in hold space
${:                            # when the input was read, start a loop
   g                           # copy hold space to pattern space
   s:\n.*::                    # remove all except the first/current frame
   H                           # append frame to hold space
   x;s:[^\n]*\n::;x            # delete first frame from hold space
   y:,:\n:                     # replace all commas with a newline
   s:^:ESC[2J:;s:ESC:\d27:gp   # use an ANSI Escape Sequence to clear the screen
                               #and print frame in color
   esleep 1                    # wait 1 second
b}                             # repeat
Seshoumara
quelle
Sie könnten ein paar Bytes sparen, indem Sie sie 1h;1d;H;durchH;1h;
Riley
@ Riley Danke, ich habe den Code aktualisiert.
Seshoumara
Wow, das war ausführlicher als viele andere, ich mag die Farbunterstützung und es ist die einzige Antwort, die das macht :). Ziemlich einzigartige Verwendung von Zeilenumbrüchen. +1 für Farbunterstützung und die Eindeutigkeit der Antwort selbst. Ich hätte es ehrlich gesagt nicht geglaubt, wenn ich es nicht selbst gesehen hätte!
Magic Octopus Urn
1

Ruby, 89 45 Bytes

f=->h,t{h.cycle{|x|puts"^[[2J",x.map(&:join)}}

Das ^[ ist ein Fluchtcharakter.

Hexdump:

00000000: 663d 2d3e 682c 747b 682e 6379 636c 657b  f=->h,t{h.cycle{
00000010: 7c78 7c70 7574 7322 1b5b 324a 222c 782e  |x|puts".[2J",x.
00000020: 6d61 7028 263a 6a6f 696e 297d 7d         map(&:join)}}

Sparte eine Menge von Bytes dank @Jordan

TuxCrafting
quelle
@ DLosc Ah, ja, Fixing
TuxCrafting
Hier können Sie viele Bytes speichern. ->h,t{h.cycle{|x|puts"^[[2J",x.map(&:join)}}
Jordanien
Gute Antwort, auch als FYI wurde der Auftrag geändert, Sie müssen sich nicht mehr an die Dauer halten, die eine Eingabe ist, da dies die möglichen Sprachen einschränkt. Sie müssen nur eine Pause einlegen, damit die Animation sichtbar wird.
Magic Octopus Urn
1

Lua ( LÖVE ), 296 287 Bytes

c=0;f=1;t=10;l=love
function l.load()loadstring('i='..arg[2])()s=tonumber(arg[3])end
function l.update(d)if c>s then
c=0;f=f==#i and 1 or f+1
end;c=c+d;end
function l.draw()for K,V in pairs(i[f])do
for k,v in pairs(V)do if v>0 then l.graphics.rectangle('fill',k*t,K*t,t,t)end
end
end
end

Anwendungsbeispiel

love main.love '{{{1,0,0},{0,0,0},{0,0,0}},{{0,1,0},{0,0,0},{0,0,0}},{{0,0,1},{0,0,0},{0,0,0}},{{0,0,0},{0,0,1},{0,0,0}},{{0,0,0},{0,0,0},{0,0,1}},{{0,0,0},{0,0,0},{0,1,0}},{{0,0,0},{0,0,0},{1,0,0}},{{0,0,0},{1,0,0},{0,0,0}},{{1,0,0},{1,0,0},{0,0,0}},{{1,1,0},{1,0,0},{0,0,0}},{{1,1,1},{1,0,0},{0,0,0}},{{1,1,1},{1,0,1},{0,0,0}},{{1,1,1},{1,0,1},{0,0,1}},{{1,1,1},{1,0,1},{0,1,1}},{{1,1,1},{1,0,1},{1,1,1}},{{1,1,1},{1,1,1},{1,1,1}},{{0,0,0},{0,0,0},{0,0,0}}}' 1

Ausgabe : https://youtu.be/0kDhPbbyG9E

Master_ex
quelle
Hmm, ich hatte nicht viel Kontakt mit Lua, ich wusste nicht, dass es auch Grafikunterstützung hat, aber ich wusste, dass es eine großartige Leistung hat. Eine sehr interessante und unerwartete Antwort. Dies ist wahrscheinlich die Antwort, die dem Zulassen einer farbigen Eingabe basierend auf den übergebenen Zahlen am nächsten kommt. Auch die erste Antwort, ASCII trotz der hohen Byteanzahl nicht zu verwenden, ist ein großartiger Jobmann +1 für die Einzigartigkeit.
Magic Octopus Urn
1
@ carusocomputing Danke! LÖVE ist ein Framework für 2D-Spiele. Sie sollten es überprüfen :-)
Master_ex
Oh Mann, wirklich? Können Sie mich mit einem Ihrer anderen Arbeiter verbinden? Ich würde es absolut gerne sehen, Alter.
Magic Octopus Urn
1

SmallBasic, 167 Bytes

Definieren und setzen Sie als Parameter die globale Variable i! Leider unterstützt SmallBasic keine Parameter für eigene Subroutinen.

sub animate
for j=0 to Array.getItemCount(i)
for k=0 to Array.getItemCount(i[0])
TextWindow.writeLine(i[j][k])
endfor
Program.delay(9)
TextWindow.clear()
endfor
endsub
Roman Gräf
quelle