Mostrar fotogramas del archivo .txt

14

La tarea:

Dado un .txtarchivo con cuadros de arte ASCII, cada uno separado por un \n(vea este ejemplo si no está claro), genera una imagen en movimiento con cuadro con 1 cuadro por segundo.

Tenga en cuenta que hay un final \nen el cuadro final.

Las dimensiones de cada cuadro serán:

  • X <80
  • Y <20

Las normas

  • El fotograma anterior debe borrarse antes de que se muestre el siguiente, por lo que imprimir cada fotograma en el terminal no es una respuesta válida.
  • Nuevo Puede tomar el nombre del archivo como lo desee, ya sea almacenado en una variable o de sys args.
  • Nuevo Las imágenes deben tener un bucle indefinido
  • Este es el código de golf: el programa más pequeño gana.

Ejemplo

Entrada

0   0
0   0
00000
0   0
0   0

00000
0
00000
0   
00000

0   0
 0 0
  0
  0
  0

Salida

Salida de ejemplo

Sin golf

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
fuente
55
En lenguajes que realmente no admiten el manejo de archivos (como JavaScript), ¿también está bien poner la entrada en una variable?
ProgramFOX
2
@ProgramFOX Supongo que puedes abrir el archivo en un navegador y usarlodocument.body.innerText
user12205
3
@ProgramFOX Lo hace un poco injusto, el aspecto de manejo de archivos agrega muchos caracteres en la mayoría de los idiomas
Harry Beadle

Respuestas:

10

Mathematica, 41 bytes

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

Espera que el nombre del archivo se almacene en variable f.

Esta es la primera vez que las reglas de precedencia de Mathematica @y .~.~.son exactamente como las necesito.

Por cierto, este fragmento podría salir terriblemente mal si la extensión del archivo es otra cosa que .txt(porque Mathematica intentará adivinar cómo hacer la importación en función de eso), pero afortunadamente el final del archivo es parte de la especificación del desafío.

Martin Ender
fuente
6

Bash, 82

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

Asume que el nombre del archivo .txt se proporciona como primer argumento del script.

Tenga en cuenta que una línea vacía final debe estar presente al final del archivo .txt para que esto funcione.

Un agradecimiento especial a @professorfish y @DigitalTrauma.

usuario12205
fuente
1
no está en $IFSblanco por defecto? también, use en for ((;;)){ ... }lugar dewhile :;do ... done
@professorfish IFS por defecto es <space><tab> <newline>. Es necesario configurarlo para ''que readpueda leer múltiples espacios consecutivos, como en la última línea de Y
user12205
1
Un par de pequeñas reducciones: IFS=y en [ "$a" ]lugar de[ -n "$a" ]
Trauma digital
4

Ruby, 88 86 56 55 caracteres

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

Este programa asume que el nombre del archivo se da como primer argumento.

¡Muchas gracias a Ventero por compartir grandes mejoras!

Sin golf:

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

Este programa lee el archivo, lo divide en fragmentos e imprime cada fragmento por separado después de borrar la pantalla. clsSolo funciona en Windows. Una variante con cleares de 57 caracteres.

ProgramFOX
fuente
puede guardar un carácter o dos, utilizando un salto de línea en lugar del primero ;y omitiendo los paréntesis al llamar split.
Martin Ender
2
Eso depende de cómo configure su editor. : P Estoy usando casi exclusivamente Windows, pero mi Sublime está configurado para usar de \ntodos modos. También aquí, en el código de golf, nadie le hará agregar otro punto a su puntaje por cada salto de línea solo porque está utilizando Windows. ;)
Martin Ender
1
$*es la abreviatura de ARGV, que salvaría dos caracteres. En este caso, se puede ahorrar aún más mediante el uso ARGF(o $<) sin embargo: a=$<.read.split"\n\n". a.sizeTambién es más corto que a.length. Y dado que sleepdevuelve su argumento después de regresar, puede combinar las dos últimas declaraciones en su ciclo i+=sleep 1.
Ventero
1
En realidad, no importa el último bit, se puede eliminar por completo imediante el uso Array#cycle, que los bucles para siempre si no se da ningún argumento: a.cycle{|i|system"cls";$><<i;sleep 1}. Y dividirse en $/+$/es otro personaje más corto que "\n\n".
Ventero
1
Eso también le permite incorporar la definición de a: $<.read.split($/+$/).cycle{...}(Perdón por el triple comentario, siempre pienso en nuevas mejoras justo después de que termine el período de edición de comentarios :))
Ventero
2

Dyalog APL (64)

(No se puede vencer a Mathematica esta vez. Parece tener una función incorporada para todo).

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

Esta es una función que toma el nombre de archivo como argumento. Se supone que el archivo está en \r\nformato Windows ( ).

Explicación:

  • ⎕ML←3: establece el nivel de migración en 3 (lo que permite ser utilizado como función dividida de APL2)
  • M←80 ¯1⎕MAP⍵: lea el archivo proporcionado por el argumento correcto como un archivo ASCII y almacene el contenido en M.
  • M⊂⍨~(4/1)⍷⎕TC∊⍨M: encuentra todas las apariciones de cuatro caracteres de control de terminal consecutivos y se divide Men ellos. Esto le da a cada cuadro.
  • {... : para cada uno de estos ...
    • ⊂⊃⍵⊂⍨~⍵∊⎕TC: divide el argumento (= un cuadro) en los caracteres de control del terminal y luego convierte el vector de vectores en una matriz (para que muestre cada línea en una línea separada, esto es necesario porque ⎕SMno comprende los caracteres de control).
    • ⎕SM←1 1,⍨: luego se muestra en la esquina superior izquierda de la ⎕SM ventana.
    • ⎕DL 1: y luego espera un segundo.
marinus
fuente
Ja, por fin! ¡Y aún así mi respuesta no es mucho más corta porque los nombres de las funciones son tan largos! : D
Martin Ender
1
Alguien necesita escribir un preprocesador de Mathematica que asigne cada función incorporada a un personaje Unicode
Digital Trauma
2

Awk, 53

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


Nuevas reglas:

Awk, 74

BEGIN{RS=z}{a[NR]=$0}END{while(!system("sleep 1;clear"))print a[i++%NR+1]}
efímero
fuente
1
Esto solo se repite una vez, pero se puede acortar a BEGIN{RS=z}{system("sleep 1;clear")}1... En awk, ""es especial como RSregistros multilínea. Para apoyar la nueva regla de bucle indefinido, tengo esto hasta ahora: BEGIN{RS=z}END{for(;!system("sleep 1;clear");)print a[i++%NR+1]}{a[NR]=$0}con 74 caracteres. gawk admite cambios ARGVpara que puedas hacerlo BEGIN{RS=z}{system("sleep 1;clear");ARGV[ARGC++]=ARGV[ARGC-1]}1con 63 caracteres.
laindir
@laindir: Gracias, no se me ocurre nada mejor.
Ephemient
1

Perl, 40

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

correr como

perl -p00 frames.pl < animation.txt

(es decir, el archivo de animación se lee a través de STDIN). p00Se agregaron 3 bytes para contar. Es 2 caracteres más corto, es decir, 38 en Windows debido a en clslugar de clear. O, para ser portátil:

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

O bien, las reglas de estiramiento un poco (y luego 31 + 3 = 34 ):

seek ARGV,sleep(1)&`reset`,!eof
usuario2846289
fuente
1

Rebol, 74

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


Espera que el nombre del archivo se almacene en variable f. A continuación se muestra un ejemplo sin golf:

f: %ascii-art.txt

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

Java, 678 caracteres (cuando se juega golf)

Por supuesto con GUI, ya que hacer cosas en la consola apesta con Java, especialmente si quieres borrar la pantalla ...

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
fuente
Me acabo de dar cuenta de que había dimensiones en la publicación del autor, pero ahora soy demasiado vago para cambiar mi código. No ganará de todos modos: 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
fuente
1

Python 117

Asume que el nombre del archivo está almacenado en variable 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')

Nota: reemplazar 'cls'con'clear' if en un sistema basado en Unix, agregando 2 canales.

ctl+C abandonar

Harry Beadle
fuente
for i in F: s.addstr(y,0,i); ... if i=='': ...
user12205
Use en open(f).read()lugar de file.read(file(f)), más corto por 4 bytes.
nyuszika7h
0

Groovy - 121 119 caracteres

Respuesta portada de ProgramFOX a Groovy 2.2.1. La "consola clara" es débil.

editar : se reemplazó el cierre recursivo con un ciclo while simple, que es más corto y no se desborda la pila

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

Sin golf:

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
fuente
0

GNU sed, 32

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

Groovy, 81

Esta es una forma más maravillosa:

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

sin golf

new File(args[0]).text.split("\n\n").each{
    ["cls"].execute()
    print it
    sleep(1000)
}
khroolick
fuente
El comando "cls" no funciona en mi Mac. Además, los requisitos sugieren que la película se repite.
Michael Pascua
2
@Michael Easter clses para Windows, creo ... pruebaclear
user12205
0

C # 226

¿Por qué molestarse eh?

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

Sin golf :

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

O en LINQPAD (para que C # pueda mantenerse semi-competitivo con súper abreviaturas: 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();}

Me siento un poco sucio, pero bueno, esto es código golf.

jzm
fuente
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 debe ser el nombre del archivo

12Me21
fuente