Take the 2-minute tour ×
Programming Puzzles & Code Golf Stack Exchange is a question and answer site for programming puzzle enthusiasts and code golfers. It's 100% free, no registration required.

The Task:

Given a .txt file with frames of ASCII art each separated by a \n (see this example if you are unclear) output a motion picture with frame with 1 frame per second.

Note that there is a trailing \n on the final frame.

Each frames dimensions will be:

  • X<80
  • Y<20

The Rules

  • The Previous frame must be cleared before the next is displayed, so just printing each frame onto the terminal isn't a valid answer.
  • New You can grab the file name however you want, either from it being stored in a variable or from sys args.
  • New The images must Loop indefinitely
  • This is code golf: smallest program wins.

Example

Input

0   0
0   0
00000
0   0
0   0

00000
0
00000
0   
00000

0   0
 0 0
  0
  0
  0

Output

Example Output

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)
share|improve this question
4  
In languages that don't really support file handling (like JavaScript), is it also OK to put the input in a variable? –  ProgramFOX May 17 at 15:46
2  
@ProgramFOX I guess you can open the file in a browser and use document.body.innerText –  ace May 17 at 18:19
2  
@ProgramFOX Make's it a little unfair, the file handling aspect adds many chars in most languages –  British Colour May 17 at 23:41

14 Answers 14

Mathematica, 41 bytes

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

Expects the file name to be stored in variable f.

This is the first time Mathematica's precedence rules for @ and .~.~. are exactly the way I need them.

Btw, this snippet could go horribly wrong if the file extension is anything else than .txt (because Mathematica will try to guess how to do the import based on that), but luckily that file ending is part of the challenge specification.

share|improve this answer

Bash, 82

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

Assumes the file name of the .txt file is provided as the first argument to the script.

Note that a trailing empty line must be present at the end of the .txt file for this to work.

Special thanks to @professorfish and @DigitalTrauma.

share|improve this answer
1  
isn't $IFS blank by default? also, use for ((;;)){ ... } instead of while :;do ... done –  professorfish May 18 at 20:19
    
@professorfish IFS by default is <space><tab><newline>. Need to set it to '' so that read can read multiple consecutive spaces, as in the last line of Y –  ace May 18 at 20:44
1  
A couple of small reductions: IFS= and [ "$a" ] instead of [ -n "$a" ] –  DigitalTrauma May 19 at 19:45

Ruby, 88 86 56 55 characters

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

This program assumes the file name is given as the first argument.

Thanks a lot to Ventero for sharing great improvements!

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
}

This program reads the file, splits it into chunks, and prints each chunk separately after clearing the screen. cls only works on Windows. A variant with clear is 57 characters.

share|improve this answer
    
you can save a character or two, by using a line break instead of the first ; and omitting the parentheses when calling split. –  Martin Büttner May 17 at 17:55
2  
That depends on how you configure your editor. :P I'm using almost exclusively Windows, but my Sublime is configured to use \n anyway. Also here on code golf no one will make you add another point to your score for each line break just because you are using Windows. ;) –  Martin Büttner May 17 at 18:07
1  
$* is shorthand for ARGV, which would save two characters. In this case, you can save even more by using ARGF (or $<) though: a=$<.read.split"\n\n". a.size is also shorter than a.length. And since sleep returns its argument after returning, you can combine the last two statements in your loop into i+=sleep 1. –  Ventero May 17 at 23:45
1  
Actually, nevermind the last bit, you can completely eliminate i by using Array#cycle, which loops forever if no argument is given: a.cycle{|i|system"cls";$><<i;sleep 1}. And splitting at $/+$/ is another character shorter than "\n\n". –  Ventero May 17 at 23:47
1  
That also allows you to inline the definition of a: $<.read.split($/+$/).cycle{...} (Sorry about the triple comment, I always think of new improvements right after the comment edit period is over :) ) –  Ventero May 17 at 23:54

Awk, 53

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


New rules:

Awk, 74

BEGIN{RS=z}{a[NR]=$0}END{while(!system("sleep 1;clear"))print a[i++%NR+1]}
share|improve this answer
1  
This only loops once, but it can be shortened to BEGIN{RS=z}{system("sleep 1;clear")}1 ... In awk, "" is special as RS meaning multiline records. To support the new rule of looping indefinitely, I have this so far: BEGIN{RS=z}END{for(;!system("sleep 1;clear");)print a[i++%NR+1]}{a[NR]=$0} at 74 characters. gawk supports changing ARGV so you can do BEGIN{RS=z}{system("sleep 1;clear");ARGV[ARGC++]=ARGV[ARGC-1]}1 at 63 characters. –  laindir May 19 at 15:08
    
@laindir: Thanks, I can't come up with anything better. –  ephemient May 19 at 16:23

Dyalog APL (64)

(Can't beat Mathematica this time. It seems to have a built-in for everything.)

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

This is a function that takes the filename as its argument. It assumes the file is in Windows (\r\n) format.

Explanation:

  • ⎕ML←3: set migration level to 3 (allowing to be used as APL2's split feature)
  • M←80 ¯1⎕MAP⍵: read the file given by the right argument as an ASCII file, and store the contents in M.
  • M⊂⍨~(4/1)⍷⎕TC∊⍨M: find all occurrences of four consecutive terminal control characters, and split M on those. This gives each frame.
  • {...: for each of these...
    • ⊂⊃⍵⊂⍨~⍵∊⎕TC: split the argument (=one frame) on terminal control characters, and then turn the vector-of-vectors into a matrix (so it will display each line on a separate line, this is necessary because ⎕SM does not understand control characters.)
    • ⎕SM←1 1,⍨: then display it in the upper left of the ⎕SM window.
    • ⎕DL 1: and then wait for one second.
share|improve this answer
    
Ha, finally! And still my answer is not a lot shorter because the function names are just so damn long! :D –  Martin Büttner May 17 at 18:30
1  
Someone needs to write a Mathematica preprocessor that maps every built in function to a Unicode character –  DigitalTrauma May 17 at 20:54

Python 117

Assumes the file name is stored in 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')

Note: replace 'cls' with 'clear' if on a unix based system, adding 2 chrs.

ctl+C to quit

share|improve this answer
    
for i in F: s.addstr(y,0,i); ... if i=='': ... –  ace May 18 at 8:52
    
Use open(f).read() instead of file.read(file(f)), shorter by 4 bytes. –  nyuszika7h Jul 2 at 18:02

Groovy - 121 119 chars

Ported ProgramFOX's answer to Groovy 2.2.1. The "clear console" is weak.

edit: replaced recursive closure with simple while loop, which is shorter and no stack overflow

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 ""}
}
share|improve this answer

Perl, 40

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

run as

perl -p00 frames.pl < animation.txt

(i.e. animation file is read through STDIN). 3 bytes for p00 were added to count. It's 2 characters shorter i.e. 38 on Windows because of cls instead of clear. Or, to be portable:

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

Or, stretching rules a bit (and then 31+3=34):

seek ARGV,sleep(1)&`reset`,!eof
share|improve this answer

GNU sed, 32

1eclear
/^$/{
esleep 1;clear
d
}
share|improve this answer

Groovy, 81

This is a more groovy way:

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)
}
share|improve this answer
    
The command "cls" doesn't work on my Mac. Also, the requirements suggest that the motion picture loops. –  Michael Easter May 17 at 22:02
2  
@Michael Easter cls is for Windows I think... try clear –  ace May 18 at 8:47

C# 226

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

Un-golfed:

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

Or in LINQPAD (so C# can stay semi-competitive with 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();}

I feel a bit dirty, but hey, this is code-golf.

share|improve this answer

Rebol, 74

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


Expects the filename to be stored in variable f. Below is an ungolfed example:

f: %ascii-art.txt

forever [
    foreach s split to-string read f "^/^/" [
        call "clear"
        print s
        wait 1
    ]
]
share|improve this answer

Java, 678 characters(when golfed)

Of course with GUI, since doing stuff in console sucks with Java, especially if you want to clear the screen ...

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();
    }
}
share|improve this answer
    
Just realized there were dimensions in the author's post, but I'm too lazy to change my code now. Won't win anyway :P –  Leo Pflug May 19 at 14:05

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
share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.