Wyświetl ramki z pliku .txt

14

Zadanie:

Biorąc pod uwagę .txtplik z ramkami grafiki ASCII, z których każda jest oddzielona znakiem \n(patrz ten przykład, jeśli nie jest jasne), wyślij film z ramką z 1 klatką na sekundę.

Zwróć uwagę, że \nna ostatniej klatce jest znak końcowy.

Wymiary każdej ramki będą:

  • X <80
  • Y <20

Zasady

  • Poprzednia ramka musi zostać wyczyszczona przed wyświetleniem następnej, więc samo wydrukowanie każdej ramki na terminalu nie jest prawidłową odpowiedzią.
  • Nowość Możesz pobrać nazwę pliku, jak chcesz, albo z pliku przechowywanego w zmiennej, albo z sys args.
  • Nowość Obrazy muszą się zapętlać w nieskończoność
  • To jest kod golfowy: wygrywa najmniejszy program.

Przykład

Wejście

0   0
0   0
00000
0   0
0   0

00000
0
00000
0   
00000

0   0
 0 0
  0
  0
  0

Wynik

Przykładowy wynik

Nie grał w golfa

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
źródło
5
Czy w językach, które tak naprawdę nie obsługują obsługi plików (takich jak JavaScript), można również wprowadzić dane wejściowe do zmiennej?
ProgramFOX
2
@ProgramFOX Myślę, że możesz otworzyć plik w przeglądarce i użyćdocument.body.innerText
user12205
3
@ProgramFOX Spraw, by było to trochę niesprawiedliwe, aspekt obsługi plików dodaje wiele znaków w większości języków
Harry Beadle

Odpowiedzi:

10

Mathematica, 41 bajtów

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

Oczekuje, że nazwa pliku będzie przechowywana w zmiennej f.

To pierwszy raz, kiedy Mathematica ma pierwszeństwo @i .~.~.jest dokładnie taka, jakiej potrzebuję.

Przy okazji, ten fragment kodu może pójść okropnie źle, jeśli rozszerzenie pliku jest czymś innym niż .txt(ponieważ Mathematica spróbuje zgadnąć, jak wykonać import na tej podstawie), ale na szczęście zakończenie pliku jest częścią specyfikacji wyzwania.

Martin Ender
źródło
6

Bash, 82

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

Zakłada się, że nazwa pliku .txt jest podana jako pierwszy argument skryptu.

Zauważ, że końcowy pusty wiersz musi znajdować się na końcu pliku .txt, aby to zadziałało.

Specjalne podziękowania dla @professorfish i @DigitalTrauma.

użytkownik12205
źródło
1
$IFSdomyślnie nie jest puste? także użyj for ((;;)){ ... }zamiastwhile :;do ... done
@professorfish IFS domyślnie to <space><tab> <newline>. Musisz ustawić go ''tak, aby readmógł odczytywać wiele kolejnych spacji, jak w ostatnim wierszu Y
użytkownik12205
1
Kilka małych obniżek: IFS=i [ "$a" ]zamiast[ -n "$a" ]
Cyfrowa trauma
4

Ruby, 88 86 56 55 znaków

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

Ten program zakłada, że ​​nazwa pliku jest podana jako pierwszy argument.

Bardzo dziękuję Ventero za udostępnienie wspaniałych ulepszeń!

Bez golfa:

$<.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
}

Ten program odczytuje plik, dzieli go na części i drukuje każdą część osobno po wyczyszczeniu ekranu. clsdziała tylko w systemie Windows. Wariant z clear57 znakami.

ProgramFOX
źródło
możesz zapisać jeden lub dwa znaki, używając podziału linii zamiast pierwszego ;i pomijając nawiasy podczas wywoływania split.
Martin Ender
2
To zależy od konfiguracji edytora. : P Używam prawie wyłącznie systemu Windows, ale moja Sublime jest skonfigurowana tak, aby używać \n. Również tutaj, na polu golfowym, nikt nie sprawi, że dodasz kolejny punkt do wyniku za każdą przerwę linii tylko dlatego, że używasz systemu Windows. ;)
Martin Ender
1
$*jest skrótem od ARGV, który uratowałby dwie postacie. W tym przypadku można zaoszczędzić jeszcze więcej za pomocą ARGF(lub $<), choć: a=$<.read.split"\n\n". a.sizejest również krótszy niż a.length. A ponieważ sleepzwraca argument po powrocie, możesz połączyć dwie ostatnie instrukcje w pętli i+=sleep 1.
Ventero
1
Faktycznie, pomijając ostatni bit, można całkowicie wyeliminować iza pomocą Array#cycle, których pętle na zawsze, jeśli nie podano żadnych argumentów: a.cycle{|i|system"cls";$><<i;sleep 1}. A dzielenie na $/+$/to kolejna postać krótsza niż "\n\n".
Ventero
1
Pozwala to również wstawić definicję a: $<.read.split($/+$/).cycle{...}(Przepraszam za potrójny komentarz, zawsze myślę o nowych ulepszeniach zaraz po zakończeniu edycji komentarza :))
Ventero
2

Dyalog APL (64)

(Tym razem nie można pokonać Mathematiki. Wygląda na to, że ma wbudowane wszystko).

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

Jest to funkcja, która przyjmuje nazwę pliku jako argument. Zakłada się, że plik ma \r\nformat Windows ( ).

Wyjaśnienie:

  • ⎕ML←3: ustaw poziom migracji na 3 (pozwalając na użycie jako funkcji podziału APL2)
  • M←80 ¯1⎕MAP⍵: przeczytaj plik podany przez właściwy argument jako plik ASCII i zapisz zawartość w M.
  • M⊂⍨~(4/1)⍷⎕TC∊⍨M: znajdź wszystkie wystąpienia czterech następujących po sobie znaków kontrolnych terminala i rozdziel Mje. Daje to każdą ramkę.
  • {... : dla każdego z nich ...
    • ⊂⊃⍵⊂⍨~⍵∊⎕TC: podziel argument (= jedna ramka) na znaki kontrolne terminala, a następnie zamień wektor wektorów na macierz (aby wyświetlał każdą linię w osobnej linii, jest to konieczne, ponieważ ⎕SMnie rozumie znaków kontrolnych).
    • ⎕SM←1 1,⍨: następnie wyświetl go w lewym górnym rogu ⎕SMokna.
    • ⎕DL 1: a następnie poczekaj sekundę.
marinus
źródło
Ha, w końcu! A jednak moja odpowiedź nie jest dużo krótsza, ponieważ nazwy funkcji są tak cholernie długie! : D
Martin Ender
1
Ktoś musi napisać preprocesor Mathematica, który mapuje każdą wbudowaną funkcję na znak Unicode
Digital Trauma
2

Awk, 53

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


Nowe zasady:

Awk, 74

BEGIN{RS=z}{a[NR]=$0}END{while(!system("sleep 1;clear"))print a[i++%NR+1]}
efemeryczny
źródło
1
To zapętla się tylko raz, ale można go skrócić do BEGIN{RS=z}{system("sleep 1;clear")}1... W awk ""jest wyjątkowy, ponieważ RSoznacza zapisy wielowierszowe. Aby wesprzeć nową zasadę zapętlania w nieskończoność, mam do tej pory: BEGIN{RS=z}END{for(;!system("sleep 1;clear");)print a[i++%NR+1]}{a[NR]=$0}74 znaki. gawk obsługuje zmiany, ARGVwięc możesz zrobić to BEGIN{RS=z}{system("sleep 1;clear");ARGV[ARGC++]=ARGV[ARGC-1]}1przy 63 znakach.
laindir
@laindir: Dzięki, nie mogę wymyślić nic lepszego.
ephemient
1

Perl, 40

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

Uruchom jako

perl -p00 frames.pl < animation.txt

(tzn. plik animacji jest odczytywany przez STDIN). p00Dodano 3 bajty dla zliczania. Jest o 2 znaki krótszy, tj. 38 w systemie Windows z powodu clszamiast clear. Lub, aby być przenośnym:

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

Lub rozciąganie trochę rządzi (a potem 31 + 3 = 34 ):

seek ARGV,sleep(1)&`reset`,!eof
użytkownik 2846289
źródło
1

Rebol, 74

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


Oczekuje, że nazwa pliku zostanie zapisana w zmiennej f. Poniżej znajduje się nieprzygotowany przykład:

f: %ascii-art.txt

forever [
    foreach s split to-string read f "^/^/" [
        call "clear"
        print s
        wait 1
    ]
]
draegtun
źródło
1

Java, 678 znaków (podczas gry w golfa)

Oczywiście z GUI, ponieważ robienie rzeczy w konsoli jest do kitu z Javą, szczególnie jeśli chcesz wyczyścić ekran ...

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
źródło
Właśnie zdałem sobie sprawę, że we wpisie autora są wymiary, ale jestem zbyt leniwy, by zmienić swój kod teraz. I tak nie wygra: P
Leo Pflug
1

Kobra - 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
Obrzydliwe
źródło
1

Python 117

Zakłada, że ​​nazwa pliku jest przechowywana w zmiennej 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')

Uwaga: wymienić 'cls' ze 'clear'jeśli w systemie opartym na UNIX, dodając 2 chrs.

ctl+C do wyjścia

Harry Beadle
źródło
for i in F: s.addstr(y,0,i); ... if i=='': ...
user12205
Użyj open(f).read()zamiast file.read(file(f)), krótszego o 4 bajty.
nyuszika7h
0

Groovy - 121 119 znaków

Przeniesiona odpowiedź programuFOX na Groovy 2.2.1. „Czysta konsola” jest słaba.

edycja : zastąpiono zamknięcie rekurencyjne prostą pętlą while, która jest krótsza i nie powoduje przepełnienia stosu

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 ""}}

Nie golfowany:

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
źródło
0

GNU sed, 32

1eclear
/^$/{
esleep 1;clear
d
}
Geoff Reedy
źródło
0

Groovy, 81

To jest bardziej groovy sposób:

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

bez golfa

new File(args[0]).text.split("\n\n").each{
    ["cls"].execute()
    print it
    sleep(1000)
}
Khroolick
źródło
Polecenie „cls” nie działa na moim komputerze Mac. Ponadto wymagania sugerują, że pętla filmu.
Michał Wielkanoc
2
@Michael Easter clsjest dla systemu Windows Myślę, że ... spróbujclear
user12205
0

C # 226

Po co zawracać sobie głowę?

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);}}}}

Bez golfa :

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);
            }
        }
    }
}

Lub w LINQPAD (aby C # mógł pozostać częściowo konkurencyjny z Uber Shorthand Langs: D)

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();}

Czuję się trochę brudny, ale hej, to jest golf.

jzm
źródło
0

SmileBASIC, 74 bajty

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

F powinna być nazwą pliku

12Me21
źródło