Hiển thị khung từ tệp .txt


14

Nhiệm vụ:

Đưa ra một .txttệp có khung nghệ thuật ASCII, mỗi khung được phân tách bằng một \n(xem ví dụ này nếu bạn không rõ ràng) xuất ra một hình ảnh chuyển động với khung có 1 khung hình mỗi giây.

Lưu ý rằng có một dấu vết \ntrên khung cuối cùng.

Mỗi kích thước khung sẽ là:

  • X <80
  • Y <20

Những quy định

  • Khung trước phải được xóa trước khi khung tiếp theo được hiển thị, vì vậy chỉ cần in từng khung lên thiết bị đầu cuối không phải là câu trả lời hợp lệ.
  • Mới Bạn có thể lấy tên tệp theo cách bạn muốn, từ nó được lưu trữ trong một biến hoặc từ sys args.
  • Mới Các hình ảnh phải lặp vô thời hạn
  • Đây là mã golf: chương trình nhỏ nhất thắng.

Thí dụ

Đầu vào

0   0
0   0
00000
0   0
0   0

00000
0
00000
0   
00000

0   0
 0 0
  0
  0
  0

Đầu ra

Ví dụ đầu ra

Không chơi gôn

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
Trong các ngôn ngữ không thực sự hỗ trợ xử lý tệp (như JavaScript), bạn có thể đặt đầu vào vào một biến không?
Chương trìnhFOX

2
@ProgramFOX Tôi đoán bạn có thể mở tệp trong trình duyệt và sử dụngdocument.body.innerText
user12205

3
@ProgramFOX Làm cho nó hơi bất công, khía cạnh xử lý tệp thêm nhiều ký tự trong hầu hết các ngôn ngữ
Harry Beadle

Câu trả lời:


10

Toán học, 41 byte

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

Dự kiến ​​tên tệp sẽ được lưu trữ trong biến f.

Đây là lần đầu tiên các quy tắc ưu tiên của Mathicala dành cho @.~.~.chính xác là cách tôi cần chúng.

Btw, đoạn trích này có thể trở nên sai lầm khủng khiếp nếu phần mở rộng tệp là bất cứ điều gì khác hơn .txt(vì Mathicala sẽ cố gắng đoán cách thực hiện nhập khẩu dựa trên điều đó), nhưng may mắn là kết thúc tệp là một phần của đặc tả thử thách.


6

Bash, 82

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

Giả sử tên tệp của tệp .txt được cung cấp làm đối số đầu tiên cho tập lệnh.

Lưu ý rằng một dòng trống ở cuối phải xuất hiện ở cuối tệp .txt để làm việc này.

Đặc biệt cảm ơn @professorfish và @DigitalTrauma.


1
không $IFSmặc định trống? đồng thời, sử dụng for ((;;)){ ... }thay vìwhile :;do ... done

@professorfish IFS theo mặc định là <dấu cách> <tab> <dòng mới>. Cần phải thiết lập nó để ''sao cho readcó thể đọc nhiều không gian liên tiếp, như trong dòng cuối cùng của Y
user12205

1
Một vài mức giảm nhỏ: IFS=[ "$a" ]thay vì[ -n "$a" ]
Chấn thương kỹ thuật số

4

Ruby, 88 86 56 55 ký tự

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

Chương trình này giả định tên tệp được đưa ra làm đối số đầu tiên.

Cảm ơn rất nhiều đến Ventero vì đã chia sẻ những cải tiến tuyệt vời!

Chưa chơi gôn:

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

Chương trình này đọc tệp, chia nhỏ thành các phần và in riêng từng phần sau khi xóa màn hình. clschỉ hoạt động trên Windows. Một biến thể với clear57 ký tự.


bạn có thể lưu một hoặc hai ký tự, bằng cách sử dụng ngắt dòng thay vì đầu tiên ;và bỏ qua dấu ngoặc khi gọi split.
Martin Ender

2
Điều đó phụ thuộc vào cách bạn định cấu hình trình soạn thảo của mình. : P Tôi đang sử dụng hầu như Windows, nhưng Sublime của tôi được cấu hình để sử dụng \n. Ngoài ra ở đây trên mã golf, không ai sẽ khiến bạn thêm điểm khác vào điểm số của mình cho mỗi lần ngắt dòng chỉ vì bạn đang sử dụng Windows. ;)
Martin Ender

1
$*là tốc ký ARGV, sẽ cứu hai nhân vật. Trong trường hợp này, bạn có thể tiết kiệm nhiều hơn bằng cách sử dụng ARGF(hoặc $<) mặc dù : a=$<.read.split"\n\n". a.sizecũng ngắn hơn a.length. Và vì sleeptrả về đối số của nó sau khi trả về, bạn có thể kết hợp hai câu lệnh cuối cùng trong vòng lặp của mình vào i+=sleep 1.
Ventero

1
Trên thực tế, không bao giờ sử dụng bit cuối cùng, bạn hoàn toàn có thể loại bỏ ibằng cách sử dụng Array#cycle, vòng lặp mãi mãi nếu không có đối số nào được đưa ra : a.cycle{|i|system"cls";$><<i;sleep 1}. Và tách tại $/+$/là một nhân vật khác ngắn hơn "\n\n".
Ventero

1
Điều đó cũng cho phép bạn nội tuyến định nghĩa về a: $<.read.split($/+$/).cycle{...}(Xin lỗi về nhận xét ba, tôi luôn nghĩ về những cải tiến mới ngay sau khi thời gian chỉnh sửa nhận xét kết thúc :))
Ventero

2

Thuốc nhuộm APL (64)

(Không thể đánh bại Mathicala lần này. Nó dường như được tích hợp sẵn cho mọi thứ.)

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

Đây là một hàm lấy tên tệp làm đối số của nó. Nó giả sử tập tin ở \r\nđịnh dạng Windows ( ).

Giải trình:

  • ⎕ML←3: đặt mức di chuyển thành 3 (cho phép được sử dụng làm tính năng phân chia của APL2)
  • M←80 ¯1⎕MAP⍵: đọc tệp được cung cấp bởi đối số đúng dưới dạng tệp ASCII và lưu trữ nội dung trong M.
  • M⊂⍨~(4/1)⍷⎕TC∊⍨M: tìm tất cả các lần xuất hiện của bốn ký tự điều khiển đầu cuối liên tiếp và phân chia Mtrên các ký tự đó. Điều này cho mỗi khung hình.
  • {... : cho mỗi ...
    • ⊂⊃⍵⊂⍨~⍵∊⎕TC: chia đối số (= một khung hình) cho các ký tự điều khiển đầu cuối, sau đó biến vectơ của vectơ thành ma trận (vì vậy nó sẽ hiển thị mỗi dòng trên một dòng riêng biệt, điều này là cần thiết vì ⎕SMkhông hiểu các ký tự điều khiển.)
    • ⎕SM←1 1,⍨: sau đó hiển thị nó ở phía trên bên trái của ⎕SMcửa sổ.
    • ⎕DL 1: và sau đó chờ một giây.

Hà, cuối cùng! Và câu trả lời của tôi vẫn không ngắn hơn nhiều vì tên hàm quá dài! : D
Martin Ender

1
Ai đó cần phải viết một bộ tiền xử lý Mathicala ánh xạ mọi chức năng được xây dựng thành một ký tự Unicode
Chấn thương kỹ thuật số

2

Awk, 53

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


Luật mới:

Awk, 74

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

1
Điều này chỉ lặp lại một lần, nhưng nó có thể được rút ngắn thành BEGIN{RS=z}{system("sleep 1;clear")}1... Trong awk, ""đặc biệt RScó nghĩa là các bản ghi đa dòng. Để hỗ trợ quy tắc lặp mới vô thời hạn, tôi có điều này cho đến nay: BEGIN{RS=z}END{for(;!system("sleep 1;clear");)print a[i++%NR+1]}{a[NR]=$0}ở mức 74 ký tự. gawk hỗ trợ thay đổi ARGVđể bạn có thể làm BEGIN{RS=z}{system("sleep 1;clear");ARGV[ARGC++]=ARGV[ARGC-1]}1ở 63 ký tự.
laindir

@laindir: Cảm ơn, tôi không thể nghĩ ra thứ gì tốt hơn.
ephemient

1

Perl, 40

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

chạy như

perl -p00 frames.pl < animation.txt

(tức là tập tin hoạt hình được đọc qua STDIN). 3 byte cho p00đã được thêm vào để đếm. Nó ngắn hơn 2 ký tự, tức là 38 trên Windows vì clsthay vì clear. Hoặc, để có thể mang theo:

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

Hoặc, kéo dài quy tắc một chút (và sau đó 31 + 3 = 34 ):

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

1

Nổi loạn, 74

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


Yêu cầu tên tệp sẽ được lưu trữ trong biến f. Dưới đây là một ví dụ vô căn cứ:

f: %ascii-art.txt

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

1

Java, 678 ký tự (khi được đánh gôn)

Tất nhiên với GUI, vì việc thực hiện công cụ trong giao diện điều khiển rất tệ với Java, đặc biệt là nếu bạn muốn xóa màn hình ...

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

Chỉ nhận ra rằng có các thứ nguyên trong bài viết của tác giả, nhưng tôi quá lười để thay đổi mã của mình bây giờ. Dù sao cũng không thắng: P
Leo Pflug

1

Rắn hổ mang - 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

Con trăn 117

Giả sử tên tệp được lưu trữ trong biến 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')

Lưu ý: thay thế 'cls'bằng'clear' nếu trên hệ thống dựa trên unix, thêm 2 chrs.

ctl+C bỏ thuốc lá


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

Sử dụng open(f).read()thay vì file.read(file(f)), ngắn hơn 4 byte.
nyuszika7h

0

Groovy - 121 119 ký tự

Câu trả lời của Chương trình đã chuyển sang Groovy 2.2.1. "Bảng điều khiển rõ ràng" là yếu.

chỉnh sửa : thay thế đóng đệ quy bằng vòng lặp while đơn giản, ngắn hơn và không tràn ngăn xế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 ""}}

Ung dung:

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

Đây là một cách hấp dẫn hơn:

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

vô dụng

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

Lệnh "cls" không hoạt động trên máy Mac của tôi. Ngoài ra, các yêu cầu đề nghị rằng các vòng lặp hình ảnh chuyển động.
Michael Easter

2
@Michael Easter clsdành cho Windows Tôi nghĩ ... hãy thửclear
user12205

0

C # 226

Sao lại phiền nhỉ?

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

Chưa chơi gôn :

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

Hoặc trong LINQPAD (vì vậy C # có thể duy trì khả năng cạnh tranh với các lang shorthand 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();}

Tôi cảm thấy hơi bẩn, nhưng này, đây là môn đánh gôn.


0

SmileBASIC, 74 byte

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

F phải là tên tệp

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.