Відобразити кадри з файлу .txt


14

Завдання:

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

Зауважте, що \nна кінцевому кадрі є кінцевий кадр.

Кожен розмір кадру буде:

  • X <80
  • Y <20

Правила

  • Попередній кадр повинен бути очищений до появи наступного, тому просто друк кожного кадру на терміналі не є коректною відповіддю.
  • Нове Ви можете захопити ім'я файлу, як вам завгодно, або з того, що воно зберігається у змінній, або з sys arg.
  • Нові Зображення повинні циклічно фіксуватися нескінченно
  • Це код гольфу: виграє найменша програма.

Приклад

Вхідні дані

0   0
0   0
00000
0   0
0   0

00000
0
00000
0   
00000

0   0
 0 0
  0
  0
  0

Вихідні дані

Приклад Вихід

Без гольфу

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 Зробити це трохи несправедливо, аспект обробки файлів додає багато символів на більшості мов
Harry Beadle

Відповіді:


10

Математика, 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, щоб це працювало.

Особлива подяка @professorfish та @DigitalTrauma.


1
$IFSза замовчуванням не порожній? також використовуйте for ((;;)){ ... }замістьwhile :;do ... done

@professorfish IFS за замовчуванням <space><tab> <newline>. Потрібно встановити його ''так, щоб він 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}

Ця програма передбачає, що ім'я файлу вказано в якості першого аргументу.

Дякую Вентеро за те, що поділилися великими вдосконаленнями!

Без гольфу:

$<.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 символів.


ви можете зберегти символ або два, скориставшись розривом рядка замість першого ;та опустивши круглі дужки під час виклику split.
Мартін Ендер

2
Це залежить від налаштування редактора. : P Я використовую майже виключно Windows, але мій Sublime налаштований для використання в \nбудь-якому випадку. Також тут на коді гольфу ніхто не змусить вас додавати ще один бал до своєї оцінки за кожен розрив рядка лише тому, що ви використовуєте 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{...}(Вибачте за потрійний коментар, я завжди думаю про нові вдосконалення одразу після закінчення періоду редагування коментарів :))
Вентеро,

2

Діалог APL (64)

(Наразі не вдається перемогти Mathematica. Здається, у всьому є вбудований.)

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

Це функція, яка приймає ім'я файлу як аргумент. Він передбачає, що файл знаходиться в Windows (\r\n форматі ).

Пояснення:

  • ⎕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

Awk, 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]}

1
Це лише петлі один раз, але його можна скоротити до BEGIN{RS=z}{system("sleep 1;clear")}1... Швидше за все, ""це особливе 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

Перл, 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

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
    ]
]

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

1

Пітон 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=='': ...
користувач12205

Використовуйте open(f).read()замість file.read(file(f)), коротший на 4 байти.
nyuszika7h

0

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

Перенесена відповідь ProgramFOX на Groovy 2.2.1. "Ясна консоль" слабка.

редагувати : замінено рекурсивне закриття простим циклом 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 ""}}

Безголівки:

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

Гровий, 81

Це більш плавкий спосіб:

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

неозорий

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

Команда "cls" не працює на моєму Mac. Також вимоги передбачають, що кінофільм циклічно.
Михайло Пасха

2
@Michael Великдень 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();}

Я відчуваю себе трохи брудно, але ей, це код-гольф.


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 має бути ім'ям файлу

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.