Anzeigen von Frames aus einer TXT-Datei

14

Die Aufgabe:

Bei einer .txtDatei mit ASCII-Bildern, die jeweils durch ein \n(siehe dieses Beispiel, wenn Sie nicht sicher sind) getrennt sind, wird ein Video mit einem Bild mit 1 Bild pro Sekunde ausgegeben.

Beachten Sie, dass \nder letzte Frame einen Trailing aufweist.

Die Abmessungen der einzelnen Rahmen betragen:

  • X <80
  • Y <20

Die Regeln

  • Das vorherige Bild muss gelöscht werden, bevor das nächste angezeigt wird. Daher ist es keine gültige Antwort, jedes Bild auf das Terminal zu drucken.
  • Neu Sie können den gewünschten Dateinamen entweder aus einer Variablen oder von sys args abrufen.
  • Neu Die Bilder müssen auf unbestimmte Zeit wiederholt werden
  • Das ist Codegolf: Das kleinste Programm gewinnt.

Beispiel

Eingang

0   0
0   0
00000
0   0
0   0

00000
0
00000
0   
00000

0   0
 0 0
  0
  0
  0

Ausgabe

Beispielausgabe

Nicht golfen

import curses, time

stdscr = curses.initscr()

Frames = file.read(file('Frames.txt')).split('\n')
while True:
    y = 0
    for i in range(len(Frames)):
        stdscr.addstr(y,0,Frames[i])
        stdscr.refresh()
        y += 1
        if Frames[i] == '':
            y = 0
            stdscr.clear()
            time.sleep(1)
Harry Beadle
quelle
5
Ist es in Sprachen, die die Dateiverwaltung nicht wirklich unterstützen (wie JavaScript), auch in Ordnung, die Eingabe in eine Variable zu setzen?
ProgramFOX
2
@ProgramFOX Ich denke, Sie können die Datei in einem Browser öffnen und verwendendocument.body.innerText
user12205
3
@ProgramFOX Machen Sie es ein wenig unfair, der Aspekt der Dateiverwaltung fügt viele Zeichen in den meisten Sprachen hinzu
Harry Beadle

Antworten:

10

Mathematica, 41 Bytes

Import@f~StringSplit~"\n\n"~ListAnimate~1

Erwartet, dass der Dateiname in einer Variablen gespeichert wird f.

Dies ist das erste Mal, dass Mathematica Vorrangregeln für sie erstellt @und .~.~.genau so verwendet, wie ich sie benötige.

Übrigens könnte dieses Snippet furchtbar schief gehen, wenn die Dateierweiterung etwas anderes ist als .txt(da Mathematica versuchen wird, zu erraten, wie der Import darauf basiert), aber zum Glück ist diese Dateiendung Teil der Herausforderungsspezifikation.

Martin Ender
quelle
6

Bash, 82

IFS=
clear
for((;;)){
while read a;do
[ "$a" ]&&echo $a||(sleep 1;clear)
done<$1
}

Angenommen, der Dateiname der TXT-Datei wird als erstes Argument für das Skript angegeben.

Beachten Sie, dass am Ende der TXT-Datei eine nachgestellte Leerzeile vorhanden sein muss, damit dies funktioniert.

Besonderer Dank geht an @professorfish und @DigitalTrauma.

user12205
quelle
1
ist nicht $IFSstandardmäßig leer? Verwenden Sie for ((;;)){ ... }stattdessen auchwhile :;do ... done
@professorfish IFS ist standardmäßig <Leerzeichen> <Tab> <Zeilenumbruch>. Notwendigkeit , sie zu setzen , ''so dass readmehrere aufeinander folgende Leerzeichen lesen kann, wie in der letzten Zeile der Y
user12205
1
Ein paar kleine Nachlässe: IFS=und [ "$a" ]stattdessen[ -n "$a" ]
Digitales Trauma
4

Ruby, 88 86 56 55 Zeichen

$<.read.split($/*2).cycle{|i|system'cls';$><<i;sleep 1}

Dieses Programm geht davon aus, dass der Dateiname als erstes Argument angegeben wird.

Vielen Dank an Ventero für die tollen Verbesserungen!

Nicht golfen:

$<.read.split($/*2).cycle{ |i|   # read file, split by two newlines, and loop
    system 'cls'   # clear screen
    $><<i   # print the current array item
    sleep 1   # sleep one second
}

Dieses Programm liest die Datei, teilt sie in Blöcke auf und druckt jeden Block nach dem Löschen des Bildschirms separat aus. clsFunktioniert nur unter Windows. Eine Variante mit clearist 57 Zeichen.

ProgramFOX
quelle
Sie können ein oder zwei Zeichen speichern, indem Sie anstelle des ersten einen Zeilenumbruch verwenden ;und beim Aufruf die Klammern weglassen split.
Martin Ender
2
Das hängt davon ab, wie Sie Ihren Editor konfigurieren. : P Ich verwende fast ausschließlich Windows, aber mein Sublime ist so konfiguriert, dass es \ntrotzdem verwendet wird. Auch hier beim Code-Golf bringt Sie niemand dazu, für jeden Zeilenumbruch einen weiteren Punkt zu Ihrem Ergebnis hinzuzufügen, nur weil Sie Windows verwenden. ;)
Martin Ender
1
$*ist eine Abkürzung für ARGV, die zwei Zeichen speichern würde. In diesem Fall können Sie sogar noch mehr sparen , indem Sie ARGF(oder $<) , obwohl: a=$<.read.split"\n\n". a.sizeist auch kürzer als a.length. Und da sleepdas Argument nach der Rückkehr zurückgegeben wird, können Sie die letzten beiden Anweisungen in Ihrer Schleife zu kombinieren i+=sleep 1.
Ventero
1
Eigentlich vergiss das letzte Bit, können Sie vollständig eliminieren , iindem Sie Array#cycle, was immer eine Schleife , wenn kein Argument angegeben wird: a.cycle{|i|system"cls";$><<i;sleep 1}. Und das Aufteilen auf $/+$/ist ein anderes Zeichen, das kürzer ist als "\n\n".
Ventero
1
Das erlaubt Ihnen auch, die Definition von inline zu setzen a: $<.read.split($/+$/).cycle{...}(Entschuldigung für den dreifachen Kommentar, ich denke immer an neue Verbesserungen direkt nach dem Ende der Kommentarbearbeitungsperiode :))
Ventero
2

Dyalog APL (64)

(Dieses Mal ist Mathematica nicht zu schlagen. Es scheint für alles etwas eingebaut zu haben.)

{⎕ML←3⋄{⎕SM←1 1,⍨⊂⊃⍵⊂⍨~⍵∊⎕TC⋄⎕DL 1}¨M⊂⍨~(4/1)⍷⎕TC∊⍨M←80 ¯1⎕MAP⍵}

Dies ist eine Funktion, die den Dateinamen als Argument verwendet. Es wird davon ausgegangen, dass die Datei im Windows ( \r\n) -Format vorliegt.

Erläuterung:

  • ⎕ML←3: Migrationsstufe auf 3 setzen (zulassen kann als Split-Funktion von APL2 verwendet werden)
  • M←80 ¯1⎕MAP⍵: Lies die vom richtigen Argument angegebene Datei als ASCII-Datei und speichere den Inhalt in M .
  • M⊂⍨~(4/1)⍷⎕TC∊⍨M: Finde alle Vorkommen von vier aufeinanderfolgenden Terminal-Steuerzeichen und teile sie auf M auf. Dies gibt jedem Rahmen.
  • {... : für jede dieser ...
    • ⊂⊃⍵⊂⍨~⍵∊⎕TC: Teilen Sie das Argument (= ein Frame) in Terminal-Steuerzeichen und wandeln Sie den Vektor der Vektoren in eine Matrix um (damit jede Zeile in einer separaten Zeile angezeigt wird, ist dies erforderlich, weil ⎕SM Steuerzeichen nicht verstanden werden.)
    • ⎕SM←1 1,⍨: dann oben links in der ⎕SM Fenster .
    • ⎕DL 1: und dann eine Sekunde warten.
Marinus
quelle
Ha, endlich! Und trotzdem ist meine Antwort nicht viel kürzer, weil die Funktionsnamen so verdammt lang sind! : D
Martin Ender
1
Jemand muss einen Mathematica-Präprozessor schreiben, der jede eingebaute Funktion einem Unicode-Zeichen
Digitales Trauma
2

Awk, 53

BEGIN{RS=RS RS}{system("clear")}1;{system("sleep 1")}


Neue Regeln:

Awk, 74

BEGIN{RS=z}{a[NR]=$0}END{while(!system("sleep 1;clear"))print a[i++%NR+1]}
vergänglich
quelle
1
Dies wird nur einmal wiederholt, kann aber auf BEGIN{RS=z}{system("sleep 1;clear")}1... gekürzt werden. In awk ""ist dies speziell , wenn es sich um RSmehrzeilige Datensätze handelt. Um die neue Regel des Endlosschleifens zu unterstützen, habe ich dies bisher: BEGIN{RS=z}END{for(;!system("sleep 1;clear");)print a[i++%NR+1]}{a[NR]=$0}bei 74 Zeichen. gawk unterstützt das Ändern, ARGVsodass Sie BEGIN{RS=z}{system("sleep 1;clear");ARGV[ARGC++]=ARGV[ARGC-1]}1mit 63 Zeichen arbeiten können.
Laindir
@laindir: Danke, ich kann mir nichts Besseres einfallen lassen.
Ephemient
1

Perl, 40

seek ARGV,0,!eof;sleep 1;system clear

Rennen wie

perl -p00 frames.pl < animation.txt

(dh die Animationsdatei wird über STDIN gelesen). p00Zur Zählung wurden 3 Bytes hinzugefügt. Es ist 2 Zeichen kürzer, dh 38 unter Windows wegen clsstatt clear. Oder um portabel zu sein:

seek ARGV,0,!eof;sleep 1;system$^O=~/Win/?cls:clear

Oder Dehnungsregeln ein wenig (und dann 31 + 3 = 34 ):

seek ARGV,sleep(1)&`reset`,!eof
user2846289
quelle
1

Rebol, 74

forever[foreach s split to-string read f"^/^/"[call"clear"print s wait 1]]


Erwartet, dass der Dateiname in einer Variablen gespeichert wird f. Unten ist ein ungolfed Beispiel:

f: %ascii-art.txt

forever [
    foreach s split to-string read f "^/^/" [
        call "clear"
        print s
        wait 1
    ]
]
draegtun
quelle
1

Java, 678 Zeichen (beim Golfen)

Natürlich mit GUI, da die Arbeit in der Konsole mit Java nichts bringt, vor allem, wenn Sie den Bildschirm löschen möchten ...

import java.awt.Font;
import java.io.File;
import java.util.Scanner;

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

public class G extends JFrame
{
    static JTextArea b = new JTextArea();

    G()
    {
        setSize(170, 370);

        add(b);
        b.setFont(new Font(Font.MONOSPACED, 0, 50));
    }

    public static void main(final String[] args)
    {   
        new G().setVisible(true);
        new SwingWorker()
        {
            protected Void doInBackground()
            {
                for(;;)
                {
                    try(Scanner s = new Scanner(new File(args[0])))
                    {
                        String l = null;
                        while(s.hasNextLine())
                        {                           
                            if(l == null  || (l = s.nextLine()).isEmpty())
                            {
                                Thread.sleep(1000);
                                b.setText(l == null ? (l = s.nextLine()) + '\n' : null);
                            }
                            else
                                b.setText(b.getText() + l + '\n');
                        }
                    }
                    catch(Exception i){}
                }
            }
        }.execute();
    }
}
Leo Pflug
quelle
Ich habe gerade festgestellt, dass der Beitrag des Autors Dimensionen enthält, aber ich bin zu faul, um meinen Code jetzt zu ändern. Wird sowieso nicht gewinnen: P
Leo Pflug
1

Cobra - 163

class P
    def main
        while 1
            for i in File.readAllLines("t.txt")
                print i
                if i=="",.x
            .x
    def x
        Threading.Thread.sleep(1000)
        Console.clear
Οurous
quelle
1

Python 117

Angenommen, der Dateiname ist in Variable gespeichert f.

import time,os
while 1:
 for i in file.read(file(f)).split('\n'):
  print i
  if i=='':time.sleep(1);os.system('cls')

Hinweis: ersetzen 'cls'durch'clear' wenn Sie auf einem Unix-basierten System arbeiten, und fügen Sie 2 Chrs hinzu.

ctl+C beenden

Harry Beadle
quelle
for i in F: s.addstr(y,0,i); ... if i=='': ...
user12205
Verwenden Sie open(f).read()stattdessen file.read(file(f)), um 4 Bytes kürzer.
Nyuszika7h
0

Groovy - 121 119 Zeichen

Portierte ProgramFOX-Antwort auf Groovy 2.2.1. Die "Klare Konsole" ist schwach.

edit : rekursives Schließen durch einfache while-Schleife ersetzt, die kürzer ist und keinen Stapelüberlauf verursacht

a=new File(args[0]).text.split "\n\n";i=0;p={println it};while(1){p a[i++%a.size()];Thread.sleep(1000);80.times{p ""}}

Ungolfed:

a = new File(args[0]).text.split "\n\n"
i = 0

p = { println it }

while(1) {
    p a[i++%a.size()]
    Thread.sleep(1000)
    80.times{p ""}
}
Michael Easter
quelle
0

GNU sed, 32

1eclear
/^$/{
esleep 1;clear
d
}
Geoff Reedy
quelle
0

Groovy, 81 Jahre alt

Das ist ein groovigerer Weg:

new File(args[0]).text.split("\n\n").each{["cls"].execute();print it;sleep(1000)}

ungolfed

new File(args[0]).text.split("\n\n").each{
    ["cls"].execute()
    print it
    sleep(1000)
}
khroolick
quelle
Der Befehl "cls" funktioniert auf meinem Mac nicht. Außerdem legen die Anforderungen nahe, dass der Film eine Schleife bildet.
Michael Easter
2
@ Michael Easter clsist für Windows, denke ich ... tryclear
user12205
0

C # 226

Warum eh stören?

namespace System{class P{static void Main(){for(;;)foreach(var x in Text.RegularExpressions.Regex.Split(new IO.StreamReader("f.txt").ReadToEnd(),"\n\r\n")){Console.Clear();Console.WriteLine(x);Threading.Thread.Sleep(1000);}}}}

Nicht golfen :

namespace System
{
    class P
    {
        static void Main()
        {
            for(;;)
            foreach (var x in Text.RegularExpressions.Regex.Split(new IO.StreamReader("f.txt").ReadToEnd(), "\n\r\n"))
            {
                Console.Clear();
                Console.WriteLine(x); 
                Threading.Thread.Sleep(1000);
            }
        }
    }
}

Oder in LINQPAD (damit C # mit der Kurzschrift langs: D halb konkurrenzfähig bleibt)

C # LINQPAD - 134

for(;;)foreach(var x in Regex.Split(new StreamReader("f.txt").ReadToEnd(),"\n\r\n")){x.Dump();Thread.Sleep(1000);Util.ClearResults();}

Ich fühle mich ein bisschen schmutzig, aber hey, das ist Code-Golf.

jzm
quelle
0

SmileBASIC, 74 Bytes

F=LOAD(F)@L
IF" "*!CSRX>F[I]THEN WAIT 60CLS
?F[I];
I=(I+1)MOD LEN(F)GOTO@L

F sollte der Dateiname sein

12Me21
quelle