Отображать кадры из .txt файла

14

Задание:

Для .txtфайла с кадрами в формате ASCII, каждый из которых разделен символом \n(см. Этот пример, если вам неясно), выведите движущееся изображение с кадром с 1 кадром в секунду.

Обратите внимание, что \nна последнем кадре есть трейлинг .

Размеры каждого кадра будут:

  • X <80
  • У <20

Правила

  • Предыдущий кадр должен быть очищен перед отображением следующего, поэтому простая печать каждого кадра на терминале не является правильным ответом.
  • Новое Вы можете получить имя файла по своему усмотрению, либо из его сохранения в переменной, либо из sys-аргументов.
  • Новые изображения должны повторяться бесконечно
  • Это код гольф: выигрывает самая маленькая программа.

пример

вход

0   0
0   0
00000
0   0
0   0

00000
0
00000
0   
00000

0   0
 0 0
  0
  0
  0

Выход

Пример вывода

Un-golfed

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
На языках, которые на самом деле не поддерживают обработку файлов (например, JavaScript), можно ли также поместить ввод в переменную?
ProgramFOX
2
@ProgramFOX Я думаю, вы можете открыть файл в браузере и использоватьdocument.body.innerText
user12205
3
@ProgramFOX Сделайте это немного несправедливым, аспект обработки файлов добавляет много символов в большинстве языков
Гарри Бидл

Ответы:

10

Mathematica, 41 байт

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

Ожидает, что имя файла будет храниться в переменной f.

Это первый раз, когда Mathematica использует правила приоритетов @и .~.~.именно так, как они мне нужны.

Кстати, этот фрагмент может пойти ужасно неправильно, если расширение файла что-то еще, чем .txt (потому что Mathematica попытается угадать, как сделать импорт на основе этого), но, к счастью, это окончание файла является частью спецификации вызова.

Мартин Эндер
источник
6

Баш, 82

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

Предполагается, что имя файла .txt предоставляется в качестве первого аргумента сценария.

Обратите внимание, что завершающая пустая строка должна присутствовать в конце файла .txt, чтобы это работало.

Особая благодарность @professfishfish и @DigitalTrauma.

user12205
источник
1
не $IFSпусто по умолчанию? Кроме того, используйте for ((;;)){ ... }вместоwhile :;do ... done
@professfishfish IFS по умолчанию - <пробел> <tab> <новая строка>. Нужно установить его ''так, чтобы readможно было читать несколько последовательных пробелов, как в последней строке Y
user12205
1
Пара небольших сокращений: IFS=и [ "$a" ]вместо[ -n "$a" ]
Digital Trauma
4

Рубин, 88 86 56 55 символов

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

Эта программа предполагает, что имя файла задано в качестве первого аргумента.

Большое спасибо Ventero за то, что поделились отличными улучшениями!

Un-golfed:

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

Эта программа читает файл, разбивает его на части и распечатывает каждый фрагмент отдельно после очистки экрана. clsработает только на Windows. Вариант с clear- 57 символов.

ProgramFOX
источник
Вы можете сохранить один или два символа, используя разрыв строки вместо первого ;и опуская скобки при вызове split.
Мартин Эндер
2
Это зависит от того, как вы настраиваете свой редактор. : P Я использую почти исключительно Windows, но мой Sublime настроен на использование в \nлюбом случае. Также здесь, в Code Golf, никто не заставит вас добавлять еще одно очко к вашему счету за каждый разрыв строки только потому, что вы используете Windows. ;)
Мартин Эндер
1
$*является сокращением для ARGV, который будет сохранять два символа. В этом случае, вы можете сэкономить еще больше, используя ARGF(или $<) , хотя: a=$<.read.split"\n\n". a.sizeтакже короче a.length. И так как sleepвозвращает свой аргумент после возврата, вы можете объединить последние два оператора в вашем цикле в i+=sleep 1.
Вентеро
1
На самом деле, фигу последний бит, вы можете полностью устранить iс помощью Array#cycle, которая зацикливается если аргумент не задан: a.cycle{|i|system"cls";$><<i;sleep 1}. И разделение на $/+$/другой персонаж короче "\n\n".
Вентеро
1
Это также позволяет встроить определение a: $<.read.split($/+$/).cycle{...}(извините за тройной комментарий, я всегда думаю о новых улучшениях сразу после окончания периода редактирования комментариев :))
Ventero
2

Дьялог АПЛ (64)

(Не могу победить Mathematica на этот раз. Кажется, что он встроен во все.)

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

Это функция, которая принимает имя файла в качестве аргумента. Предполагается, что файл в \r\nформате Windows ( ).

Объяснение:

  • ⎕ML←3: установите уровень миграции на 3 (позволяя использовать в качестве функции разделения APL2)
  • M←80 ¯1⎕MAP⍵: прочитать файл, заданный правильным аргументом, как файл ASCII и сохранить его содержимое в M.
  • M⊂⍨~(4/1)⍷⎕TC∊⍨M: найти все вхождения четырех последовательных управляющих символов терминала и разделить Mих. Это дает каждый кадр.
  • {... : для каждого из этих ...
    • ⊂⊃⍵⊂⍨~⍵∊⎕TC: разделить аргумент (= один кадр) на управляющие символы терминала, а затем превратить вектор векторов в матрицу (чтобы каждая строка отображалась на отдельной строке, это необходимо, поскольку ⎕SMне понимает управляющие символы).
    • ⎕SM←1 1,⍨: затем отобразите его в левом верхнем углу ⎕SMокна.
    • ⎕DL 1: а затем подождите одну секунду.
Мэринус
источник
Ха, наконец-то! И все же мой ответ не намного короче, потому что имена функций просто чертовски длинные! : D
Мартин Эндер
1
Кто-то должен написать препроцессор Mathematica, который отображает каждую встроенную функцию в символ Unicode
Digital Trauma
2

Авк, 53

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


Новые правила:

Awk, 74

BEGIN{RS=z}{a[NR]=$0}END{while(!system("sleep 1;clear"))print a[i++%NR+1]}
ephemient
источник
1
Это зацикливается только один раз, но его можно сократить до BEGIN{RS=z}{system("sleep 1;clear")}1... В awk ""это особенное RSзначение многострочных записей. Чтобы поддерживать новое правило зацикливания до бесконечности, у меня есть это до сих пор: BEGIN{RS=z}END{for(;!system("sleep 1;clear");)print a[i++%NR+1]}{a[NR]=$0}в 74 символов. Gawk поддерживает изменение, ARGVтак что вы можете сделать BEGIN{RS=z}{system("sleep 1;clear");ARGV[ARGC++]=ARGV[ARGC-1]}1на 63 символов.
Laindir
@laindir: Спасибо, я не могу придумать ничего лучше.
Эфимент
1

Perl, 40

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

беги как

perl -p00 frames.pl < animation.txt

(т.е. файл анимации читается через STDIN). p00Для подсчета добавлено 3 байта . Это на 2 символа короче, то есть 38 на Windows, потому что clsвместо clear. Или, чтобы быть портативным:

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

Или немного растянуть правила (а затем 31 + 3 = 34 ):

seek ARGV,sleep(1)&`reset`,!eof
user2846289
источник
1

Реболь, 74

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


Ожидает, что имя файла будет храниться в переменной f. Ниже приведен пример без гольфа:

f: %ascii-art.txt

forever [
    foreach s split to-string read f "^/^/" [
        call "clear"
        print s
        wait 1
    ]
]
draegtun
источник
1

Java, 678 символов (при игре в гольф)

Конечно, с графическим интерфейсом, поскольку работа в консоли - отстой с Java, особенно если вы хотите очистить экран ...

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();
    }
}
Лео Пфлуг
источник
Просто осознал, что в посте автора были измерения, но мне сейчас лень менять код. В любом случае не выиграю: P
Лео Пфлуг
1

Кобра - 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
источник
1

Python 117

Предполагается, что имя файла хранится в переменной 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')

Примечание: заменить 'cls'на'clear' if в системе на основе Unix, добавив 2 chrs.

ctl+C выйти

Гарри Бидл
источник
for i in F: s.addstr(y,0,i); ... if i=='': ...
user12205
Используйте open(f).read()вместо file.read(file(f)), короче на 4 байта.
nyuszika7h
0

Groovy - 121 119 символов

Портированный ответ ProgramFOX на Groovy 2.2.1. «Чистая консоль» слабая.

edit : заменено рекурсивное закрытие на простой цикл while, который короче и не переполняется стеком

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

GNU sed, 32

1eclear
/^$/{
esleep 1;clear
d
}
Джефф Риди
источник
0

Groovy, 81

Это более отличный способ:

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
источник
Команда "cls" не работает на моем Mac. Кроме того, требования предполагают, что фильм зацикливается.
Майкл Пасха
2
@ Майкл Пасха clsдля Windows, я думаю ... попробуйтеclear
user12205
0

C # 226

Зачем?

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

Без гольфа :

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

Или в LINQPAD (таким образом, C # может оставаться полуконкурентоспособным с сокращенными именами Uber: 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();}

Я чувствую себя немного грязно, но эй, это код-гольф.

jzm
источник
0

SmileBASIC, 74 байта

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

F должно быть именем файла

12Me21
источник