Exibir quadros do arquivo .txt


14

A tarefa:

Dado um .txtarquivo com quadros de arte ASCII, cada um separado por um \n(veja este exemplo, se você não estiver claro) emite um filme com quadro com 1 quadro por segundo.

Observe que há um rastro \nno quadro final.

As dimensões de cada quadro serão:

  • X <80
  • Y <20

As regras

  • O quadro anterior deve ser limpo antes que o próximo seja exibido, portanto, apenas imprimir cada quadro no terminal não é uma resposta válida.
  • Novo Você pode pegar o nome do arquivo como quiser, seja armazenado em uma variável ou em sys args.
  • Novo As imagens devem fazer um loop indefinidamente
  • Este é o código de golfe: o menor programa vence.

Exemplo

Entrada

0   0
0   0
00000
0   0
0   0

00000
0
00000
0   
00000

0   0
 0 0
  0
  0
  0

Resultado

Saída de exemplo

Sem golfe

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)

5
Em idiomas que realmente não suportam manipulação de arquivos (como JavaScript), também é bom colocar a entrada em uma variável?
ProgramFOX

2
@ProgramFOX Eu acho que você pode abrir o arquivo em um navegador e usar #document.body.innerText
user12205

3
@ProgramFOX Marca é um pouco injusto, o arquivo manipulação aspecto acrescenta muitos caracteres na maioria dos idiomas
Harry Beadle

Respostas:


10

Mathematica, 41 bytes

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

Espera que o nome do arquivo a ser armazenado na variável f.

Esta é a primeira vez que a precedência do Mathematica rege @e .~.~.é exatamente do jeito que eu preciso deles.

Aliás, esse trecho pode dar terrivelmente errado se a extensão do arquivo for diferente de .txt(porque o Mathematica tentará adivinhar como fazer a importação com base nisso), mas felizmente esse final do arquivo faz parte da especificação do desafio.


6

Bash, 82

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

Supõe que o nome do arquivo .txt seja fornecido como o primeiro argumento para o script.

Observe que uma linha vazia à direita deve estar presente no final do arquivo .txt para que isso funcione.

Agradecimentos especiais a @professorfish e @DigitalTrauma.


1
não está em $IFSbranco por padrão? também, use em for ((;;)){ ... }vez dewhile :;do ... done

O @professorfish IFS por padrão é <space><tab> <newline>. É necessário configurá-lo para ''que readpossa ler vários espaços consecutivos, como na última linha de Y
user12205

1
Algumas pequenas reduções: IFS=e em [ "$a" ]vez de[ -n "$a" ]
Digital Trauma

4

Ruby, 88 86 56 55 caracteres

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

Este programa assume que o nome do arquivo é fornecido como o primeiro argumento.

Muito obrigado a Ventero por compartilhar grandes melhorias!

Sem golfe:

$<.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 lê o arquivo, divide-o em partes e imprime cada parte separadamente após limpar a tela. clssó funciona no Windows. Uma variante com clear57 caracteres.


você pode salvar um ou dois caracteres usando uma quebra de linha em vez do primeiro ;e omitindo os parênteses ao chamar split.
Martin Ender

2
Isso depende de como você configura seu editor. : P Estou usando quase exclusivamente o Windows, mas meu Sublime está configurado para usar de \nqualquer maneira. Também aqui no código golf, ninguém fará você adicionar outro ponto à sua pontuação para cada quebra de linha apenas porque você está usando o Windows. ;)
Martin Ender

1
$*é uma abreviação de ARGV, o que salvaria dois caracteres. Neste caso, você pode economizar ainda mais usando ARGF(ou $<) que: a=$<.read.split"\n\n". a.sizetambém é menor que a.length. E como sleepretorna seu argumento após retornar, você pode combinar as duas últimas instruções em seu loop em i+=sleep 1.
Ventero 17/05

1
Na verdade, esquece o último bit, você pode eliminar completamente iusando Array#cycle, que loops para sempre se nenhum argumento é dado: a.cycle{|i|system"cls";$><<i;sleep 1}. E dividir em $/+$/é outro caractere menor que "\n\n".
Ventero 17/05

1
Isso também permite que você inline a definição de a: $<.read.split($/+$/).cycle{...}(Desculpe pelo comentário triplo, sempre penso em novas melhorias logo após o término do período de edição dos comentários :)) #
Ventero 17-14

2

Dyalog APL (64)

(Não é possível vencer o Mathematica desta vez. Parece ter um built-in para tudo.)

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

Essa é uma função que usa o nome do arquivo como argumento. Ele assume que o arquivo está no \r\nformato Windows ( ).

Explicação:

  • ⎕ML←3: defina o nível de migração como 3 (permitindo ser usado como recurso de divisão do APL2)
  • M←80 ¯1⎕MAP⍵: leia o arquivo fornecido pelo argumento correto como um arquivo ASCII e armazene o conteúdo em M.
  • M⊂⍨~(4/1)⍷⎕TC∊⍨M: encontre todas as ocorrências de quatro caracteres consecutivos de controle de terminal e divida M-os. Isso fornece cada quadro.
  • {... : para cada um desses ...
    • ⊂⊃⍵⊂⍨~⍵∊⎕TC: divida o argumento (= um quadro) nos caracteres de controle do terminal e transforme o vetor de vetores em uma matriz (para exibir cada linha em uma linha separada, isso é necessário porque ⎕SMnão entende os caracteres de controle).
    • ⎕SM←1 1,⍨: depois, exiba-o no canto superior esquerdo da ⎕SMjanela.
    • ⎕DL 1: e aguarde um segundo.

Ha, finalmente! E ainda assim minha resposta não é muito mais curta, porque os nomes das funções são muito longos! : D
Martin Ender

1
Alguém precisa escrever um pré-processador Mathematica que mapeia toda construída em função de um caractere Unicode
Trauma Digital

2

Awk, 53

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


Novas regras:

Awk, 74

BEGIN{RS=z}{a[NR]=$0}END{while(!system("sleep 1;clear"))print a[i++%NR+1]}

1
Isso faz um loop apenas uma vez, mas pode ser reduzido para BEGIN{RS=z}{system("sleep 1;clear")}1... No awk, ""é especial por RSsignificar registros de várias linhas. Para apoiar a nova regra de loop indefinidamente, eu tenho isso até agora: BEGIN{RS=z}END{for(;!system("sleep 1;clear");)print a[i++%NR+1]}{a[NR]=$0}com 74 caracteres. O gawk suporta alterações, ARGVpara que você possa fazer BEGIN{RS=z}{system("sleep 1;clear");ARGV[ARGC++]=ARGV[ARGC-1]}1com 63 caracteres.
Laindir

@laindir: Obrigado, não consigo encontrar nada melhor.
ephemient

1

Perl, 40

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

correr como

perl -p00 frames.pl < animation.txt

(ou seja, o arquivo de animação é lido através do STDIN). 3 bytes para p00foram adicionados à contagem. São 2 caracteres mais curtos, ou seja, 38 no Windows, em clsvez de clear. Ou, para ser portátil:

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

Ou, esticando um pouco as regras (e depois 31 + 3 = 34 ):

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

1

Rebol, 74

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


Espera que o nome do arquivo a ser armazenado na variável f. Abaixo está um exemplo não destruído:

f: %ascii-art.txt

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

1

Java, 678 caracteres (quando jogado)

Claro que com a GUI, já que fazer coisas no console é péssimo com Java, especialmente se você deseja limpar a tela ...

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

Acabei de perceber que havia dimensões na postagem do autor, mas estou com preguiça de mudar meu código agora. Não vai ganhar de qualquer maneira: 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

1

Python 117

Assume o nome do arquivo é armazenado na variável 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: substitua 'cls'por 'clear'if em um sistema baseado em unix, adicionando 2 chrs.

ctl+C para sair


for i in F: s.addstr(y,0,i); ... if i=='': ...
User12205

Use em open(f).read()vez de file.read(file(f)), menor em 4 bytes.
precisa saber é o seguinte

0

Groovy - 121 119 caracteres

Resposta do ProgramFOX portado para o Groovy 2.2.1. O "console limpo" é fraco.

edit : fechamento recursivo substituído por loop while simples, que é mais curto e sem estouro de pilha

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


0

Groovy, 81

Esta é uma maneira mais divertida:

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

destroçado

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

O comando "cls" não funciona no meu Mac. Além disso, os requisitos sugerem que o filme circule.
Michael Easter

2
@Michael Easter clsé para Windows, eu acho ... tente #clear
user12205

0

C # 226

Por que incomodar hein?

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

Sem golfe :

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

Ou no LINQPAD (para que o C # possa permanecer semi-competitivo com os 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();}

Eu me sinto um pouco suja, mas ei, isso é código-golfe.


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 deve ser o nome do arquivo

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.