Your challenge is to make an infinite loading screen, that looks like this:

enter image description here


Or, to be more specific:

  • Take no input.
  • Output Loading..., with a trailing space, but no trailing newline.
  • Infinitely cycle through the chars |, /, - and \: every 0.25 seconds, overwrite the last one with the next in the sequence. You can overwrite just the last character, or delete and rewrite the whole line, as long Loading... remains unchanged.

Rules

  • The output text must look exactly as specified. Trailing newlines/spaces are acceptable.
  • You should not wait 0.25 seconds before initially showing output - the first frame should be printed as soon as the program is run.
  • Your program should be able to run indefinitely. For example, if you use a counter for frames, the counter should never cause an error by exceeding the maximum in your language.
  • Although the waiting period between each "frame" should be 0.25 seconds, obviously this will never be exact - an error margin of 10% or so is allowed.
  • You may submit a function, but it must print to stdout.
  • You can submit an answer in a non-console (but still text-based) environment, as long as it is capable of producing the loading animation.
  • This is , so the shortest solution (in bytes) wins. Standard code-golf loopholes apply.
  • If possible, please provide a gif of your loading screen in action.

Example

Here is the C++ code I used to create the example (ungolfed):

#include <iostream>
#include <string>
#include <thread>

using namespace std;

int main() {
    string cycle = "|/-\\";
    int i = 0;

    cout << "Loading... ";

    while (true) {
        // Print current character
        cout << cycle[i];

        // Sleep for 0.25 seconds
        this_thread::sleep_for(chrono::milliseconds(250));

        // Delete last character, then increase counter.
        cout << "\b";
        i = ++i % 4;
    }
}

May the best golfer win!

  • 3
    Can submissions wait 0.25 seconds before initially displaying output? – ETHproductions Nov 27 '16 at 20:42
  • 2
    No, but thanks for mentioning that, I'll add it to the rules @ETHproductions – FlipTack Nov 27 '16 at 20:43
  • Is a trailing newline (after the animating symbol) acceptable? – Copper Nov 27 '16 at 20:43
  • Of course :) @Copper – FlipTack Nov 27 '16 at 20:44
  • 1
    @TheBitByte it means that, theoretically, nothing inside your program will cause it to error - such as a counter overflowing or reaching maximum recursion depth. – FlipTack Dec 15 '16 at 6:57

93 Answers 93

HTML/CSS, 183 180 163 161 160 147 143 bytes

a{display:inline-flex;overflow:hidden;width:1ch}c{animation:c 1s steps(4)infinite}@keyframes c{to{margin:0-4ch
<pre>Loading... <a><c>|/-\</pre>

Edit: Saved 3 bytes thanks to @betseg. Saved 17 bytes thanks to @manatwork. Saved 1 byte thanks to @Daniel. Saved 13 bytes thanks to @Ismael Miguel. Saved 4 bytes thanks to @Fez Vrasta.

  • 4
    According to meta, CSS+HTML is fine for answering questions. Furthermore I allowed this in the challenge description. So this answer is perfectly valid :) – FlipTack Nov 27 '16 at 21:30
  • 5
    HTML+CSS is TC, so I don't see why it might be non-competing – TuxCopter Nov 27 '16 at 21:34
  • 1
    @TùxCräftîñg CSS is definitely not turing complete as you can solve the halting problem in it (If there is no infinite animation, it halts). I think the same applies for HTML (If you don't include JS). – Artyer Nov 27 '16 at 21:36
  • 4
    @Artyer stackoverflow.com/a/5239256/3273184 is something worth considering. – Mama Fun Roll Nov 27 '16 at 21:42
  • 4
    @MamaFunRoll A comment on that post mentions that that doesn't really prove it TC because it can't loop without user intervention. However, it can solve this particular challenge, so I don't see any problem with this answer. – ETHproductions Nov 28 '16 at 1:56

Vim, 43, 41 bytes

qqSLoading... |<esc>:sl250m
r/@:r-@:r\@:@qq@q

Two bytes saved thanks to @Udioica!

Here's a (slightly outdated) animation of it happening in real time!

enter image description here

And here is an explanation:

qq                              " Start recording into register 'q'
  SLoading... |<esc>            " Replace all of the text in the buffer with 'Loading... |'
                    :sl250m     " Sleep for 250 ms
r/                              " Replace the bar with a slash
  @:                            " Re-run the last ex command (sleeping)
    r-                          " Replace the slash with a dash
      @:                        " Re-run the last ex command (sleeping)
        r\                      " Replace the dash with a backslash
          @:                    " Re-run the last ex command (sleeping)
            @q                  " Run macro 'q' (the one we're recording)
              q                 " Stop recording
               @q               " Call macro 'q', which will run forever because it's recursive
  • 1
    just curios: does it violate "Your program should be able to run indefinitely"? can it eventually reach a stack overflow? :) – dan oak Nov 28 '16 at 17:11
  • 4
    @dahnoak Well, obviously I can't infinitely test it, but it doesn't allocate any extra memory, so I can't see any reason it wouldn't work indefinitely. – DJMcMayhem Nov 28 '16 at 17:14
  • 1
    If you switch i to S and move it inside the macro, you can skip r|. – udioica Nov 28 '16 at 20:46
  • 2
    @dahnoak There is no reason why the vi engine couldn't notice the tail recursion. And some implementations of recursion would do so naturally (imagine if there is a vector of commands to-be-executed, and a current execution location. Then @q would insert at-current-location the contents of register script q. No stack needed, and no memory allocated unless there are commands to run after @q within q.) – Yakk Nov 29 '16 at 14:59
  • Almost every time you post an answer to a challenge, I learn something new (in this case, @: and :sl), so thanks and keep them coming :) – Christian Rondeau Dec 4 '16 at 17:39

HTML + JS (ES6), 20 + 51 50 = 70 bytes

setInterval(_=>a.innerHTML='|/-\\'[i=-~i%4],i=250)
Loading... <a id=a>-

-1 byte (Zachary T)

Check out my 132 byte HTML/CSS answer as well.

  • Might that overflow i? – Zacharý Nov 27 '16 at 22:50
  • Yes, it eventually would. Fixed that! – darrylyeo Nov 27 '16 at 22:56
  • 1
    Could you replace i++,i%=4 with i=-~i%4 for a byte? – Zacharý Nov 27 '16 at 23:17
  • 2
    @Xufox The <pre> only ensured a monospaced font was used so that ch units would work. The rules don't mention anything about the font family used. ;) – darrylyeo Nov 30 '16 at 2:46
  • 1
    If I am not mistaken, the first character printed by JS will be the last one in the string; so you should init with - instead of /. Or init with | and loop through '-\\|/'. Nice increment though. – Titus Dec 8 '16 at 15:46

Node, 72 70 bytes

f=i=>console.log('\x1BcLoading... '+'|/-\\'[setTimeout(f,250,i=-~i%4),i])

Replace \x1B with the literal escape character to get the correct byte count. Call f() to start the animation. Here's how it looks in the ConEmu terminal emulator on my computer:

enter image description here

  • Try using \033c (replace \033 with its actual char representation). It doesn't look as good, but it saves you some bytes. – Mama Fun Roll Nov 27 '16 at 21:43
  • Won't i overflow? – Zacharý Nov 27 '16 at 23:22
  • 12
    @ZacharyT It will after 71 million years, but I can fix that if necessary – ETHproductions Nov 27 '16 at 23:54
  • 3
    "Your program should be able to run indefinitely. For example, if you use a counter for frames, the counter should never cause an error by exceeding the maximum in your language.", yes, it's necessary. – Zacharý Nov 28 '16 at 0:40
  • 3
    @Florent But then it wouldn't run on Node ;-) – ETHproductions Dec 1 '16 at 19:35

Windows Batch, 121 114 84 80 79 78 bytes

Just throwing this out for fun.

for %%b in (/ - \ ^|)do (cls
@echo Loading... %%b
ping 1.1 -n 1 -w 250>nul)
%0

I was not able to assign pipe (|) into the array, so I had to manually add it with another assignment. The delay is done with PING, which might not be accurate.

Output:

enter image description here

Edit:

  • Thanks to Roman Gräf for saving 7 bytes!
  • Thanks to Neil for saving 30 bytes! I have also mangled it a bit more to save bytes on the newlines.
  • Thanks to phyrfox for saving 4 bytes!
  • Thanks to YourDeathIsComing for saving 2 bytes!
  • 3
    You can remove @echo off and put an @ in front of every set or echo command – Roman Gräf Nov 28 '16 at 9:56
  • 1
    You don't need the array, in (/ - \ ^|) works. Also, %0 is a shorter way to loop than goto. – Neil Nov 28 '16 at 17:32
  • 2
    You should be able to use the IP address "1.1" (-4 bytes), because most platforms will auto-expand that to 1.0.0.1 for you. – phyrfox Nov 29 '16 at 16:49
  • 1
    You can save 1 byte by removing the space in front of >nul. – YourDeathIsComing Nov 30 '16 at 20:30
  • 1
    I meant the space before it, not after it. – YourDeathIsComing Dec 5 '16 at 5:31

Kotlin, 67 66 bytes

while(1>0)"|/-\\".map{print("\rLoading... $it");Thread.sleep(250)}

enter image description here

Fairly self explanatory, using \r to clear the line and taking advantage of Kotlin's awesome string interpolation.

EDIT: Saved 1 byte thanks to @mEQ5aNLrK3lqs3kfSa5HbvsTWe0nIu by changing while(true) to while(1>0)

  • 1
    You could save one byte by using while(1>0) instead of while(true) (-1) & probably should include the actual function syntax in your answer (fun a(){<code>}, +9). If you wanna be a bit cheaty, you could use store a function as a variable (val a={<code>}, +8). – F. George Nov 28 '16 at 6:13
  • 2
    @mEQ5aNLrK3lqs3kfSa5HbvsTWe0nIu Is 'full program' mode not acceptable? This can be run as a Kotlin script .kts without class or function definitions. Also, great call with while(1>0)! – Tyler MacDonell Nov 28 '16 at 14:06
  • 3
    But what if, one day, 0 becomes greater than 1???? :P – FlipTack Nov 28 '16 at 15:14
  • Great idea of using Kotlin script. @Flp.Tkc Your comment reminded me of this: codegolf.stackexchange.com/a/101131/62024. Still shuddering that this is possible. – F. George Nov 28 '16 at 20:00
  • @TylerMacDonell Really? I didn't know you could run kotlin directly as a script. Thanks for the info. – TheNumberOne Jan 6 '17 at 2:28

Vim, 35 bytes

iLoading... \-/|<Esc>qqdb:sl250m<CR>p@qq@q

The boring version. Here's a non-complying solution that's better:

Vim (1 second sleep), 27 bytes

idbgsp@@<C-U>Loading... \-/|<Esc>@.

Using gs not only is much shorter, but you don't have to hit Enter. That means the macro fits in-line, and I can save bytes by switching to @.. (Since nothing after the recursive call can ever run, I can type whatever I want.)

  • Thanks for this answer! I learned gs, @. and the @@ within @. still makes my head hurt! – Christian Rondeau Dec 14 '16 at 4:39

Pyth, 31 bytes

Wm,p+"\rLoading... "d.d.25"|/-\

Interpreter here.

Loading GIF

Explanation

Wm,p+"\rLoading... "d.d.25"|/-\
    +"\rLoading... "d              Concatenate the string "\rLoading... " and the variable d
   p                               Print the result without a newline
                     .d.25         Sleep for 0.25 seconds
  ,                                Form a two-element list with the results of the two statements above. This is only needed to execute both statements in a single lambda function.
 m                        "|/-\    Map the above statement over the characters in the string "|/-\", setting the variable d to the character for each iteration
W                                  While the result of the map statement is true, do nothing

Powershell (v4), 57 56 54 53 58 57 Bytes

Back at the Bytecount I started with!

for(){cls;"Loading... "+"|/-\"[($a=++$a%4)];sleep -m 250}

The CLI in powershell will glitch out slightly on some computers, so it doesn't look perfect, but it's as good as I can feasibly get.

Moved $a++ into the for loop to save one byte, (no ;)

Then moved it into the array indexer, for another 2 byte save, thanks to Roman for pointing that out.

Also saved 1 more byte (;) by moving the Clear screen (cls) part into the for loop..

Issue and fix pointed out by TimmyD for the infinite aspect of the question, only +5 Bytes required, changed $a++%4 into ($a=++$a%4) so it will never go above 3.

Saved another byte by leaving the for loop totally blank, thanks to 'whatever' for pointing out that this is actually possible in Powershell Version 4!

New updated gif for the (final?) version of this answer.

Loading Gif

for(;;cls){"Loading... "+"|/-\"[($a=++$a%4)];sleep -m 250}

for(;;cls){"Loading... "+"|/-\"[$a++%4];sleep -m 250}

for(;;){"Loading... "+"|/-\"[$a++%4];sleep -m 250;cls}

for(;;$a++){"Loading... "+"|/-\"[$a%4];sleep -m 250;cls}

for(;;){$a++;"Loading... "+"|/-\"[$a%4];sleep -m 250;cls}

  • 2
    for(;;){"Loading... "+"|/-\"[$a++%4];sleep -m 250;cls} (move the $a++ to the last usage of $a) – Roman Gräf Nov 28 '16 at 14:28
  • always forgetting something - thanks for that! – colsw Nov 28 '16 at 14:34
  • 2
    I'm not very adept at Powershell, but when I saw the Windows Batch entry, i thought "Could Powershell beat this?". And here it is! – Jakub Jankowski Nov 29 '16 at 20:49
  • 1
    At least on ps v4 you should be able golf another byte by keeping the for condition totally empty: for(){cls;"Loading... "+"|/-\"[($a=++$a%4)];sleep -m 250} – whatever Dec 2 '16 at 13:34
  • 1
    You're welcome. It actually seems to work for Version 2+, was just too lazy to check before ;) – whatever Dec 2 '16 at 13:54

Pyth - 36 35 bytes

#+"\033cLoading... "@"\|/-"~hZ.d.25

Doesn't work online, obviously.

  • Do you have a gif of this in action? Also, is there any counter that could overflow? – FlipTack Nov 28 '16 at 18:01
  • @Flp.Tkc the only counter is Z which is a python integer, which don't overflow. I was trying to make a gif but couldn't get it to work. If you know how to make one, you can run it with the pyth interpreter at github.com/isaacg1/pyth – Maltysen Nov 29 '16 at 2:57
  • 4
    If the integer doesn't overflow, then it'll probably grow until filling up all memory, which would make it fail at least after 10⁶⁵⁰⁰⁰⁰⁰⁰⁰ years on most 32-bit systems. Sure, the heat death of the universe will happen first, but still... – jjrv Dec 1 '16 at 10:47

Matlab, 78 75 bytes

a='\|/-';while 1;clc;disp(['Loading... ',a(1)]);a=a([2:4,1]);pause(1/4);end

enter image description here

HTML/CSS, 23 + 109 = 132 bytes

Improved upon Neil's answer.

pre{display:flex}a{overflow:hidden;animation:a 1s steps(4)infinite;width:1ch}@keyframes a{to{text-indent:-4ch
<pre>Loading... <a>|/-\

Mathematica, 74 67 Bytes

ListAnimate["Loading... "<>#&/@{"|","/","-","\\"},AnimationRate->4]

A whopping 7 bytes off thanks to @dahnoak

  • ListAnimate["Loading... "<>#&/@Characters@"|/-\\",AnimationRate->4] – dan oak Nov 28 '16 at 17:25
  • 1
    @dahnoak cheers! I didn't realise ListAnimate was a thing. It's a shame that <> is Flat not Listable otherwise 4 more bytes could be shaved off! – A Simmons Nov 28 '16 at 17:30
  • Just for fun: Dynamic["Loading... "<>{"|","/","-","\\"}[[1+Round[4Now@"Second"]~Mod~4]],UpdateInterval->.25] – shrx Dec 15 '16 at 14:58

C#, 170 133 Bytes

void X(){Console.Write("Loading...  ");for(;;){foreach(var c in "|/-\\"){Console.Write("\b"+c);System.Threading.Thread.Sleep(250);}}}

Big thanks to Roman Gräf and raznagul, who saved me 37 bytes. (Especially raznagul, who pointed out, that my original solution was invalid anyway. I kinda missed out on something there, but it's fixed now and should meet the requirements :)

pretty similar to Pete Arden's existing C# answer but with some improvements

e.g. "for(;;)" instead of "while (true)", char instead of string

I would have commented my suggestions on his answer but I don't actually have enough reputation to do that.

Ungolfed:

static void X()
{
    Console.Write("Loading...  ");
    for (;;)
    {
        foreach (var c in "|/-\\")
        {
            Console.Write("\b" + c);
            System.Threading.Thread.Sleep(250);
        }
    }
}
  • 2
    Why don't remove the first Console.Write("\b"); and change the second to Console.Write("\b"+a);? – Roman Gräf Nov 28 '16 at 15:14
  • Defining an action is unnecessary and to long using a loop like foreach(var a in"|/-\\") and add the code you currently have in the action as the body will save you ~20 Bytes. – raznagul Nov 28 '16 at 15:34
  • Also, the task is to create the required output exactly. Which is currently not the case. – raznagul Nov 28 '16 at 16:00
  • It should be the case now, I forgot '|' and the trailing space after "Loading...". – Snowfire Nov 28 '16 at 16:21
  • In your ungolfed version (since it doesn't match the golfed version), you can remove the first Console.Write() and use just one Console.Write($"Loading... {c}\r") instead of the second. – milk Nov 28 '16 at 18:38

Forth, 72, 73 bytes

EDIT:

  • Added the Gforth-only version, 69 bytes (Thanks @ninjalj !)
  • Added missing whitespace after "Loading..." (Thx @Roman Gräf !), +1 byte
  • Updated to match the rules more precisely (in the same byte count)

Golfed

: L '| '/ '- '\ begin .\" \rLoading... " 3 roll dup emit 250 ms again ; L

Gforth version

The GNU Forth-only version can be brought down to 69 bytes like this:

'| '/ '- '\ [begin] .\" \rLoading... " 3 roll dup emit 250 ms [again]

Screencast

enter image description here

Try it online !

  • 1
    Since you are using gforth, if you don't care about portability to other Forth's, you can use [begin] and [again] outside a word definition. – ninjalj Nov 30 '16 at 21:48

Python 2, 81 79 78 77 bytes

import time
i=1
while 1:print'\rLoading...','\|/-'[i%4],;i+=1;time.sleep(.25)

Quite a simple solution that sleeps using time.

I use \r (A carriage return) to go back to the start of the line and then print the message overwriting the line.

I start with i=1 to avoid double escaping the \ (It is '\|/-' instead of '|/-\\').

In the past, I had used -~i to mean i + 1 to avoid parentheses. (Thanks to @Flp.Tkc for these -2 bytes!) (It was i=(i+1)%4 vs. i=-~i%4)

Now, I am just letting the counter rise forever, as technically Python ints can't overflow. Thanks to @Zachary T for pointing that out and saving a byte!
It only stops on a machine because the machine runs out of memory, but this takes 9.7 generations with 4GB of memory for that one int.

Thanks to @Kade for the -1 byte where print a,b prints a and b space seperated, so I don't need my own space.

Here's a gif of it working on Windows:

Loading

I tested it on a Linux VM too. I couldn't test it on a Mac.

  • 1
    If I remember correctly, you can use i=-~i%4 to save the bytes for the parens :) – FlipTack Nov 27 '16 at 21:48
  • 2
    Won't replacing [i],;i=-~i%4 with [i%4],;i+=1 save a byte since it doesn't exceed the max for Python, only the maximum memory? – Zacharý Nov 27 '16 at 22:03
  • 9
    I should downvote you for logging in as Administrator... – Neil Nov 27 '16 at 22:06
  • 5
    @Neil To be totally honest, I just put the Python file in Administrator and ran it from there because the other account names are real names (Personal PC). – Artyer Nov 27 '16 at 22:07
  • 2
    I'd allow @ZacharyT 's suggestion as technically Python integers can be infinitely large, as long as the computer has memory to hold them – FlipTack Nov 27 '16 at 22:11

MATL, 36 bytes

1 byte removed using @flawr's idea of circularly shifting the string

'\-/|'`Xx1YS'Loading... 'y1)hD.25Y.T

Here is a gif recording from the offline compiler:

enter image description here

Or try it at MATL Online! If it doesn't initially run, refresh the page and press "Run" again.

How it works

'\-/|'           % Push this string
`                % Do...while
  Xx             %   Clear screen
  1YS            %   Circularly shift thr string 1 step to the right
  'Loading... '  %   Push this string
  y              %   Duplicate the string of shifting symbols
  1)             %   Get the first character
  hD             %   Concatenate the two strings and display
  .25Y.          %   Pause for 0.25 seconds
  T              %   Push "true". This is used as loop condition, to it
                 %   generates an infinite loop
                 % End loop implicitly
  • Hey Luis. well done with MATL as always. Here's a slight variation of the circular list. and display. Do you think you could translate that in an even shorter solution: a='\|/-';k=1; fprintf('Loading... -') while 1 k=mod(k,4)+1; fprintf('\b\b%c\n',a(k)); pause(.25); end – Hoki Dec 4 '16 at 10:51
  • @Hoki Thanks for the idea. Actually I initially had an increasing counter modulo 4, but it was a little longer (I then gained a byte because of the requirement of no initial pause). Also, I think clear screen and normal display is shorter than fprintf with backspaces – Luis Mendo Dec 4 '16 at 15:45

Dyalog APL, 50 bytes

This only works in the Windows version, as otherwise the ⎕SM window will not show unless ⎕SR is called.

{⎕SM←1 1,⍨⊂⊃⍵⌽'Loading... '∘,¨'|/-\'⋄∇4|⍵+⌈⎕DL÷4}1

Explanation:

  • {...}1: run the function beginning with ⍵=1
  • Loading... '∘,¨'|/-\': generate the four possible outputs
  • ⊂⊃⍵⌽: Rotate the list to put the ⍵th element first, take the first element, and enclose it
  • ⎕SM←1 1,⍨: put the string in the top-left corner of the ⎕SM window.
  • ⎕DL÷4: wait 1/4th of a second
  • 4|⍵+⌈: round up the resulting value (seconds spent waiting, so this is always 1), add it to (incrementing it), and take the mod-4 (to prevent it from eventually overflowing).
  • : run the function again with the new .

Animation

  • Somehow I knew someone would submit an answer for this challenge for Dyalog (/APL) :) – YoYoYonnY Nov 30 '16 at 18:21

C#, 187 Bytes

Golfed:

void L(){Console.Write("Loading...");Action<string>l=(a)=>{Console.SetCursorPosition(11,0);System.Threading.Thread.Sleep(250);Console.Write(a);};while(true){l("|");l("/");l("-");l("\\");}

Ungolfed:

public void L()
{
  Console.Write("Loading...");
  Action<string> l = (a) =>
  {
    Console.SetCursorPosition(11, 0);
    System.Threading.Thread.Sleep(250);
    Console.Write(a);
  };
  while (true)
  {
    l("|");
    l("/");
    l("-");
    l("\\");
  }
}

Still waiting for it to load...

enter image description here

  • Still waiting for it to display “\”… – manatwork Nov 28 '16 at 13:09
  • @manatwork Oh crap, lazy copy and pasting. Will fix it when I'm back at my desk shortly :) – Pete Arden Nov 28 '16 at 13:16
  • Sorry to see your solution getting longer due to my comment. Can't you use 1>0 instead of true to get it back to 186? – manatwork Nov 28 '16 at 13:37
  • @ErikGolferエリックゴルファー, no idea about C#, but based on the fact the language is a copy of Java and apparently confirmed by Can't cast int to bool, I thought that would not work. (BTW, if that works, maybe using the first call of l() as condition would also work?) – manatwork Nov 28 '16 at 14:00
  • 2
    @manatwork Well, it seems C# is ungolfable. – Erik the Outgolfer Nov 28 '16 at 14:01

Snap!, 8 blocks

8 blocks of Snap!

This was one of the very first algorithms I ever puzzled out on an Apple ][e

  • 1
    Show us your Applesoft BASIC :) – ropata Dec 15 '16 at 21:26
  • I would gladly do these in Hypercard. – wyldstallyns Dec 15 '16 at 22:01

reticular, noncompeting, 40 bytes

:i=@C"Loading... "o"|/-\\".iHo14%w.i1+4,

enter image description here

I forgot to commit a bunch of things, including w. Oh well.

Explanation

:i=@C"Loading... "o"|/-\\".iHo14%w.i1+4,
:i=                                       set `i` to the TOS
   @C                                     clear the screen
     "Loading... "o                       output that string
                   "|/-\\"                push that string
                          .i              get `i`
                            H             get the `i`th character of that string
                             o            and output it
                              14%         push 0.25 (1/4)
                                 w        wait that long
                                  .i      get `i`
                                    1+    increment
                                      4,  mod 4
                                          this wraps around the beginning of the program,
                                          setting i to the said value

Bash, 98 69 bytes

while s='\|/-';do
printf "\rLoading... ${s:i=++i%4:1}"
sleep .25
done

Thanks to many people for the many bytes golfed off!

  • Also you don't have to escape the backslash if you use single quotes and the arguments for echo -e -n can be combined to echo -en – Evan Chen Nov 28 '16 at 1:58
  • You can save 2 lines and 13 bytes by replacing the echo line to: echo -en "\rLoading... ${s:i=(i+1)%4:1}" – Ipor Sircer Nov 28 '16 at 2:27
  • echo -enprintf; make the assignment to s the while condition. – manatwork Nov 28 '16 at 9:28
  • use printf like manatwork said, simplify the substring, and put it directly in the while condition: while printf "\rLoading... ${s:i++%4:1}";do. 67 bytes – Dominik R Nov 28 '16 at 12:04
  • That won't work Dominik R, it would eventualy overflow. – Zacharý Nov 28 '16 at 13:33

Perl 6, 72 61 bytes

Supply.interval(1/4).tap: {print "\rLoading... ",<| / - \ >[$/++];$/%=4}
loop {print "\rLoading... ",<| / - \ >[$/++];$/%=4;sleep 1/4}

><>, 55+4 = 59 bytes

"...gnidaoL"v
l?!voc1. ^:<>
<v<>'\|/-'>^v
^<^<<<8{<<^o<

Must be run passing -t .01 as additional argument to the interpreter, that's the +4 in the byte count.

What this does is putting the four characters to be printed on the stack, printing the top one without removing it and shifting the stack by one position. Then it prints \b (backspace, character x08) and restarts the loop.

Timing is achieved by the argument passed to the interpreter, which forces to wait 0.01 second before executing each instruction. There are 23 instructions between an output and the next one (most of them simply move the instruction pointer to the next cell), so this will wait 0.23 seconds plus the time needed for executing the instructions, which fits without problem in the requested 0.25s with 10% error.

You could try it online, but that interpreter doesn't recognize the backspace character, so the output will be a bit strange there.

  • Normally flags like -n are scored as 1 byte, so I think you can score the argument as t, .01 which is 4 bytes. Nice use of the 10% rule btw :) – FlipTack Nov 28 '16 at 22:36
  • @Flp.Tkc Thank you! I wasn't sure of how to count bytes for the argument, I like this way :) – Leo Nov 29 '16 at 7:47
  • @Leo - Is there a reason for using 0.01 and not a larger tick with less instructions? I've added my version which uses a loop of 8 instructions and the tick count of 0.03; #"...gnidaoL"l?!vob0. "\|/-":o}8o51. ># – Teal pelican Dec 2 '16 at 11:14
  • @Tealpelican There is a reason, but it's not a very good one: the rules state that "You should not wait 0.25 seconds before initially showing output - the first frame should be printed as soon as the program is run.", so I didn't want to make the timer too long, while on the other hand this is code golf, so I didn't want to make it too short. In the end I decided for a 25 instruction loop taking 0.01s each to achieve the exact timing of 0.25s requested; when I implemented it, though, I realized that I lacked enough space for the full loop, so I had to resort to using the 10% rule. – Leo Dec 2 '16 at 13:48
  • I must have misread the rules. That is a perfectly good reason for the timing :) – Teal pelican Dec 2 '16 at 14:30

MS-DOS .COM file, 56 bytes

Here the file content in hexadecimal:

b4 09 ba 2c 01 cd 21 b2 2f e8 11 00 b2 2d e8 0c
00 b2 5c e8 07 00 b2 7c e8 02 00 eb ea b4 02 cd
21 b2 08 cd 21 b9 05 00 f4 e2 fd c3 4c 6f 61 64
69 6e 67 2e 2e 2e 20 24

The matching assembler code looks like this:

    mov ah, 9      ; Print "Loading... "
    mov dx, text
    int 21h
theloop:
    mov dl, '/'    ; Call "chrout" for "/", "-", "\" and "|"
    call chrout
    mov dl, '-'
    call chrout
    mov dl, '\'
    call chrout
    mov dl, '|'
    call chrout
    jmp theloop    ; Endless loop

chrout:            ; Sub-Function "chrout"
    mov ah, 2      ; Output the character
    int 21h
    mov dl, 8      ; Output backspace
    int 21h
    mov cx,5       ; Call "HLT" 5 times
timeloop:
    hlt            ; Normally HLT will wait ~55 milliseconds
                   ; (Assuming no keyboard key is pressed)
    loop timeloop
    ret            ; End of the function

text:
    ASCII "Loading... ",'$'
  • 1
    Keeping a key pressed accelerates the spinner, which can be fixed by masking interrupts other than the timer interrupt, e.g.: mov al, 0xfe / out 0x21,al – ninjalj Nov 29 '16 at 20:12
  • The comment for HLT is wrong, you probably meant that HLT wakes up at ~18.2 Hz (or, more precisely, at NTSC clock/12/65536 Hz). – ninjalj Nov 30 '16 at 21:46
  • @ninjalj Thanks. I changed the comment... – Martin Rosenau Dec 1 '16 at 6:23

NASM x86_64 - 349 283 bytes

This should be run 64 bit linux systems

built using:

nasm loading_golfed.asm -felf64 && ld loading_golfed.o

%use altreg
global _start
section .data
o:db"Loading...  "
s:db"|/-\\"
b:db`\bx`
q:dq 0,250000000
_start:mov r0,1
mov r7,1
mov r6,o
mov r2,12
syscall
mov r2,2
l:mov r7,1
mov al,[s+r8]
mov [b+1],al
mov r0,1
mov r6,b
syscall
mov r0,35
lea r7,[q]
mov r6,0
syscall
inc r8
and r8,3
jmp l

animation:

saved 65 bytes - thanks user254948

enter image description here

  • I count 349 bytes, unless there's a trailing newline/space – FlipTack Nov 29 '16 at 21:37
  • ^Flp. Tkc Thanks, there was a line with a space at the end – Samuel Nov 29 '16 at 21:40
  • @Samuel are lines 13-17 needed? It seems to work pretty much fine without those lines. As far as I can tell (Not that great in assembly I'm afraid) you print the Loading...., then the | character, then remove that character, then enter a loop where you repeat printing the | for the first time. – user254948 Dec 1 '16 at 13:44
  • @Samuel in addition xor r8,r8 -> mov r8,0 (saves 1 character), some MOV's have an extra space (mov r7, 1 -> mov r7,1). further more the instructions cmp r8,4, jl l, xor r8,r8, can be replaced by AND r8,3 (saving 15 characters). You should be down to 285 bytes then instead of 349! (in combination with the lines mentioned above) – user254948 Dec 1 '16 at 14:27

R, 85 89 bytes

repeat{if(T>4)T=1;cat("\fLoading...",c("|","/","-","\\")[T],sep="");T=T+1;Sys.sleep(.25)}

Edit: Fixed the answer such that T wont overflow by resetting the counter if greater than 4.

The only interesting aspect about this answer is the use of R's TRUTHY builtin T. It is effectively a predefined variable set to 1/TRUE which means we don't have to initialize the counter but can start incrementing T.

  • Would T eventually overflow? – FlipTack Nov 28 '16 at 8:13
  • @Flp.Tkc It wouldn't overflow but be treated as infinity past 1e+308 in which case NA is returned so I guess this answer is invalid then (didn't notice it in the rules). Will update soon – Billywob Nov 28 '16 at 8:47
  • 1
    Actually you can get it 2 bytes shorter if you don't use the built-in T: i=1;repeat{cat("\rLoading...",c("\\","|","/","-")[i]);Sys.sleep(.25);i=`if`(i>3,1,i+1)} is 87 bytes. – plannapus Nov 29 '16 at 16:15
  • Hmm ... does R only operate on vectors? Why are there no modulo or bitwise operators for atoms? is T a vector? Does T=(T+1)%%4 work? It would save another 5 bytes. – Titus Dec 4 '16 at 13:24
  • 2
    ... or T=T%%4+1: even 2 bytes shorter. – Titus Dec 8 '16 at 14:58

Haskell (GHC), 103 91 bytes

import GHC.Conc
mapM((>>threadDelay 250000).putStr)$("\rLoading... "++).pure<$>cycle"|/-\\"

Thanks @nimi for saving 12 bytes!

  • No need for a full program. mapM((threadDelay 250000>>).putStr)$("\rLoading... "++).pure<$>cycle"|/-\\". – nimi Nov 28 '16 at 13:11
  • Two bytes might be saved by using the 10% tolerance and replacing 250000 and the space before it with (4^9). – Christian Sievers Nov 29 '16 at 3:45

C (on UNIX-like systems) 88 bytes

main(_){for(;;){_%=4;printf("\rLoading... %c","\\-/|"[_++]);fflush(0);usleep(250000);}}

It starts with the wrong character, but I think it looks nicer. You can easily change the character order by modifying the "\-/|" string.

  • Could be golfed further by moving statements into for, e.g: ain(_){for(;printf("\rLoading... %c","\\-/|"[_%4]);usleep(250000))_++,fflush(0);}, then could be golfed further assuming wraparound for integer overflow: main(_){for(;printf("\rLoading... %c","\\-/|"[_++%4]);usleep(250000))fflush(0);} – ninjalj Nov 29 '16 at 0:20
  • Do you need the fflush() in there? – John U Dec 2 '16 at 11:30
  • On most systems you do need the fflush, many of them buffer based on newlines. However it is possible that it isn't necessary on some systems. – LambdaBeta Dec 2 '16 at 17:48
  • You could use fprintf(stderr,... instead, since that is not line buffered like stdout. The f...stderr, takes eight characters, while the fflush(0); takes ten, so it's a net win of two characters. – cmaster Dec 28 '16 at 10:58

Perl, 71 63 61 bytes

s//\rLoading... |/;select$\,$\,$\,y'-|\/'\/|-'/4while$|=print

Previous version:

$_="\rLoading... |";{$|=print;y#|/\-\\#/\-\\|#;select$\,$\,$\,.25;redo}

Thanx to @primo for 10 bytes.

  • 2
    Nice trick to use the select timeout rather than Time::HiRes. You can save a few bytes by using ... while$|=print, and by moving the hyphens in the transliteration to the front and the end. s//\r Loading... |/ also saves a byte over assignment. – primo Nov 28 '16 at 12:41
  • 2
    And also, if you use single quotes for the transliteration delimiter, there's no need to escape the backslash either: y'-\|/'\|/-'. – primo Nov 28 '16 at 12:48
  • It seems you have an extra space before your code. – Erik the Outgolfer Nov 28 '16 at 13:48
  • 1
    You can save another byte by using a literal \r. – ninjalj Nov 28 '16 at 19:26
  • 1
    Use y'-|\/'\/|-'/4 in place of .25 for 2 more. – primo Nov 30 '16 at 6:38

Your Answer

 

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

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