46
\$\begingroup\$

Animate the text in your terminal

The goal

The goal is to "animate" the string "Hello world" in your output so that each character gets capitalised after each other.

Your program can exit after each letter has been capitalised.

For example;

# Iteration 1
Hello world

# Iteration 2
hEllo world

# Iteration 3
heLlo world

# Iteration 4
helLo world

# Iteration 5
hellO world

# Iteration 6 (note: it should capitilize the space char (ie: a break between iteration 5 and iteration 7)
hello world

# Iteration 7
hello World

# Iteration 8
hello wOrld

# Iteration 9
hello woRld

# Iteration 10
hello worLd

# Iteration 11
hello worlD

It should only animate the string once and between each state there should be a 1 second delay.

Input

No input is required, but "Hello world" must be the string that is "animated".

Output

The string "Hello world" must be animated. The output must be as 1 line to create a sort of wave animation. An empty trailing new line is allowed. Example gif;

https://i.gyazo.com/be12b693063b463540c5bf1f03d2454a.gif

I saw this on a metasploit youtube video and thought the effect was pretty cool, which is where I recorded the gif from, so it's a little laggy, but I hope it illustrates the output fine

This is , lowest byte-count will be deemed the winner.

Sandbox Link

\$\endgroup\$
10
  • \$\begingroup\$ Can it exit and stop with an error? \$\endgroup\$ Feb 13, 2017 at 12:26
  • \$\begingroup\$ @StewieGriffin as long as the animation is viewable, sure. \$\endgroup\$
    – ʰᵈˑ
    Feb 13, 2017 at 13:38
  • \$\begingroup\$ I don't think the 1 second delay adds to the challenge. We've had a bunch like that and each time it seems like the same boilerplate is added. \$\endgroup\$
    – xnor
    Feb 13, 2017 at 13:39
  • 2
    \$\begingroup\$ @xnor Do you mean the duration of the delay being 1 second explicitly, or do you mean any delay at all? Latter wouldn't make any sense since it's an animation after all.. \$\endgroup\$
    – Metoniem
    Feb 13, 2017 at 13:43
  • 1
    \$\begingroup\$ @Metoniem No, only the ones described in the goal. Unless I've misunderstood. Each letter must be capitalised once from left to right once only, starting with "H" in "hello" and ending with "D" in "world" \$\endgroup\$
    – ʰᵈˑ
    Feb 14, 2017 at 17:06

52 Answers 52

34
\$\begingroup\$

Vim 26 bytes

ihello world<ESC>qq~gsul@qq0@q

Explanation (no .gif yet):

First, we must enter the 'hello world' text. This is pretty straightforward. It's just:

ihello world<ESC>

At this point, the cursor is on the 'd' in 'world'. Next:

qq              " Start recording into register 'q'
  ~             " Swap the case of the character underneath the cursor, and move the cursor to the right
   gs           " Sleep for one second
     u          " Undo the last change (of swapping case).
      l         " Move one character to the right (Get it? 'l' == 'Right' because vim is intuitive!)
                " This will cause the error to break on the last character of the input.
       @q       " Call register 'q'
         q      " Stop recording
          0     " Move to the first character
           @q   " Call the recursive macro

There are also two other 26 byte versions I found:

ihello world<ESC>qq~gsulq011@q
ihello world<ESC>011@='~gsul'<cr>
\$\endgroup\$
4
  • \$\begingroup\$ Man that's cool! Here's the output: i.gyazo.com/52d0b9268446aed36ce7eb641c40ff6c.gif (half of it anyway, Gyazo stopped recording) \$\endgroup\$
    – ʰᵈˑ
    Feb 13, 2017 at 10:46
  • \$\begingroup\$ I don't think ~ breaks the loop. I believe it's the l that does the hard work \$\endgroup\$
    – user41805
    Feb 13, 2017 at 16:23
  • \$\begingroup\$ @KritixiLithos Ah, after testing it, it seems you're right. Good point, I'll edit that out \$\endgroup\$
    – DJMcMayhem
    Feb 13, 2017 at 16:24
  • 1
    \$\begingroup\$ Can confirm -- This works. \$\endgroup\$ Feb 13, 2017 at 19:48
15
\$\begingroup\$

Python 2, 98 94 90 bytes

for x in range(11):s='hello world';print'\r'+s[:x]+s[x:].capitalize(),;[1for y in' '*8**8]

-9 -4 bytes thanks to @ElPedro -4 bytes thanks to @JonathanAllan and @Rod

\$\endgroup\$
15
  • 3
    \$\begingroup\$ Welcome to PPCG, nice first post c: \$\endgroup\$
    – Rod
    Feb 13, 2017 at 11:24
  • 2
    \$\begingroup\$ Nice post! This seems to have a capital "H" and "W" at the same time though repl.it/Fhii - It seems to not lowercase the "H" \$\endgroup\$
    – ʰᵈˑ
    Feb 13, 2017 at 11:25
  • 1
    \$\begingroup\$ About the printing problem, you can pass -u argument and use print"\t"+s[:x]+s[x:].title(),; (note the trailing comma). And this won't change your byte count (because the argument would add +2 bytes) \$\endgroup\$
    – Rod
    Feb 13, 2017 at 11:38
  • 2
    \$\begingroup\$ @Rod The flag would count as one byte because an acceptable invocation for Python is python -c 'code here'. With the flag, the invocation would be python -uc 'code here', which is one byte different. \$\endgroup\$
    – user45941
    Feb 13, 2017 at 13:16
  • 1
    \$\begingroup\$ Pretty much your version, but 95 bytes and clears the screen (I tested with 2.7.8 on Windows 7-64). Try It Online does not give the animation, just the line by line result. \$\endgroup\$ Feb 13, 2017 at 15:02
12
\$\begingroup\$

Commodore 64, 168 162 137 133 BASIC (and tokenized) bytes used

 0s=1024:?"{control+n}{clear home}hello world":fOi=.to1:fOj=.to11:x=pE(s+j):pokes+j,x+64
 1x=pE(1023+j):pO1023+j,abs(x-64):pO1029,32:pO1035,32:fOz=.to99:i=.:nEz,j,i

You will need to use BASIC keyword abbreviations to enter this into a real C64 or emulator (or enter the program into a Commodore 128 and load it back in C64 mode, although this should work on the 128 as well). The {control+n} will only work/display after the opening quote. It is shorthand for chr$(14) and therefore saves some bytes and switches the character set to business mode or upper/lower case characters.

I have added in some abbreviations for you so you. The {clear home} character is made by pressing Shift and the CLR/HOME key after the opening quotation mark.

For illustrative purposes the unobfustcated listing may be entered as follows:

 0 let s=1024
 1 print chr$(14); chr$(147); "hello world"
 2 for i=0 to 1
 3  for j=0 to 11
 4   let x=peek(s + j)
 5   poke s + j, x + 64
 6   let x=peek(1023 + j)
 7   poke 1023 + j, abs(x - 64)
 8   poke 1029, 32
 9   poke 1035, 32
10   for z=0 to 99
11    let i=0
12   next z
13  next j
14 next i

It works by switching the PETSCII charset into business mode (upper/lower case), and writing the hello world string to the top line of the screen which is located at memory location $0400, it will then take the value at each location for the next 11 bytes from there and increase each value by 64 (the upper case equivalent). If the j counter is > 0, it calls a routine at line 2 to decrease the previous memory location by 64 again.

Line 3 is a pause, it also writes a space to to location $0405 and $040b, which is a bug fix (which could probably be removed to save some bytes).

Commodore C64 animated hello world

\$\endgroup\$
4
  • \$\begingroup\$ I should add that fori=0to1step0 ... nexti is essentially creating an infinite (goto-less) loop, kind of like while(true){...} in more modern languages. \$\endgroup\$ Feb 13, 2017 at 17:21
  • 1
    \$\begingroup\$ Why don't you just use a goto instead of an infinite loop? Even with the 2 newlines that would have to be added, it would still save bytes. Also RAM bytes isn't the same as the number of bytes in your code. \$\endgroup\$
    – MilkyWay90
    Nov 12, 2018 at 2:42
  • \$\begingroup\$ Because GO TO is banned, right ;-) One may easily work out the listing by itself by CLR before working out the remain free bytes with the broken FRE(0) function \$\endgroup\$ Nov 12, 2018 at 17:03
  • 1
    \$\begingroup\$ oh sorry about that \$\endgroup\$
    – MilkyWay90
    Nov 13, 2018 at 0:04
11
\$\begingroup\$

Powershell, 126 119 107 104 Bytes

'Hello world';$s='hello world';1..10|%{sleep 1;cls;-join($s[0..($_-1)]+[char]($s[$_]-32)+$s[++$_..11])}

enter image description here

Revisions (there will likely be many):

Change $s.Length to const 10 11

Restructured string builder, removed 1 join statement and used ++$s instead of ($s+1), to save some bytes thanks to @AdmBorkBork

AdmBorkBork points out just using the string twice is actually shorter than encapsulating and then .ToLower()'ing it - which says a lot about how verbose powershell is, -3!


basically loop through the length of the string, form an array of three parts, the pre-capitcal, capital, and post-capital, take 32 away from the middle letter, then convert back to a char to get upper case, luckily this doesn't turn space into a visible character either, I hope this is acceptable?

\$\endgroup\$
2
  • 2
    \$\begingroup\$ You can save three more bytes off the front by simply printing the string rather than saving it into $s and .ToLower()ing it. -- 'Hello world';$s='hello world'; \$\endgroup\$ Feb 13, 2017 at 14:24
  • \$\begingroup\$ 102 bytes inline-ing $s \$\endgroup\$
    – Veskah
    Jul 18, 2019 at 15:21
11
\$\begingroup\$

C#, 230 215 193 161 135 134 130 bytes

It's C# so it's long right! :-( But after some help and searching, I (and others, really) managed to remove exactly 100 bytes already.

Golfed

()=>{for(int i=1;;){var b="\rhello world".ToCharArray();b[i++]-=' ';System.Console.Write(b);System.Threading.Thread.Sleep(1000);}}

Ungolfed

class P
{
    static void Main()
    {
        for (int i = 1;;)
        {
            var b = "\rhello world".ToCharArray();
            b[i++] -= ' ';
            System.Console.Write(b);
            System.Threading.Thread.Sleep(1000);
        }
    }
}

Screenshot

Animation with 1 second delay Although it looks alot better when looping and faster..

Updates

  • Lost 15 bytes by using carriage return instead of Clear() which also allowed me to replace a using with System.Consolesomewhere inline.

  • Replaced program with lambda saving 23 bytes thanks to @devRicher

  • It became kind of a collaboration with @devRicher at this point, thanks to some of his suggestions I managed to lose another 32 bytes!
  • Thanks to 2 really smart and interesting suggestions by @Kratz I managed to replace new string(b) with b and b[i]=char.ToUpper(b[i]) with b[i]-=' ', saving me another 26 bytes!
  • 1 byte less by moving i++ thanks to @Snowfire
  • 4 bytes less by moving carriage return to the beginning of the string and removing i<11 from my for loop
\$\endgroup\$
19
  • 1
    \$\begingroup\$ Change class P{static void Main(){ ... }} to ()=>{ ... } to snip off a few bytes. PPCG accepts functions as answers, so a lambda works fine. \$\endgroup\$
    – devRicher
    Feb 13, 2017 at 12:29
  • \$\begingroup\$ @devRicher Ah I see, I never used lambas before, but that seems like a cool improvement. Thanks! \$\endgroup\$
    – Metoniem
    Feb 13, 2017 at 12:32
  • \$\begingroup\$ If you don't know how to use them (or don't want to), its still fine for a simple void g(){ ... }. \$\endgroup\$
    – devRicher
    Feb 13, 2017 at 12:33
  • \$\begingroup\$ You can access strings with array indices (char g = string j[x]), to save around 50 bytes: ()=>{var s="Hello world";for(int i=1;i<11;i++){string h = s;h[i]=char.ToUpper(s[i]);System.Console.Write(h+"\r");System.Threading.Thread.Sleep(1000);}} \$\endgroup\$
    – devRicher
    Feb 13, 2017 at 12:39
  • 1
    \$\begingroup\$ You can save another byte by removing the incrementation from the for clause and putting it in the array access like b[i++]-=' '. That would come in handy, because then you could also remove the condition in the for loop and just write for(int i=0;;). OP pointed out in the comments, that the program may exit with an error, so you can allow an IndexOutOfRangeException \$\endgroup\$
    – Snowfire
    Feb 14, 2017 at 13:15
9
\$\begingroup\$

CP-1610 assembly, 50 DECLEs = 63 bytes

This code is intended to be run on an Intellivision.

A CP-1610 opcode is encoded with a 10-bit value, known as a 'DECLE'. This program is 50 DECLEs long, starting at $4800 and ending at $4831.

                                  ROMW  10          ; use 10-bit ROM
                                  ORG   $4800       ; start program at address $4800

                          main    PROC
4800 0002                         EIS               ; enable interrupts (to enable display)

4801 0001                         SDBD              ; load pointer to string in R4
4802 02BC 0026 0048               MVII  #@@str, R4

4805 02A2                         MVI@  R4,     R2  ; R2 = length of string
4806 0091                         MOVR  R2,     R1  ; R1 = uppercase counter

4807 02BD 0214            @@loop  MVII  #$214,  R5  ; R5 = video memory pointer
4809 0093                         MOVR  R2,     R3  ; R3 = character counter

480A 02A0                 @@next  MVI@  R4,     R0  ; R0 = next character
480B 0338 0020                    SUBI  #32,    R0  ; minus 32 -> character #
480D 004C                         SLL   R0,     2   ; multiply by 8 to get the
480E 0048                         SLL   R0          ; correct GROM card
480F 03F8 0007                    XORI  #7,     R0  ; add 7 (for white)

4811 014B                         CMPR  R1,     R3  ; uppercase? ...
4812 020C 0002                    BNEQ  @@draw

4814 0338 0100                    SUBI  #256,   R0  ; ... yes: sub 32*8

4816 0268                 @@draw  MVO@  R0,     R5  ; draw character
4817 0013                         DECR  R3          ; decrement character counter
4818 022C 000F                    BNEQ  @@next      ; process next character or stop

481A 0001                         SDBD              ; R0 = spin counter to wait ~1 second
481B 02B8 0038 00D3               MVII  #$D338, R0  ;    = 54072 = 13518 * 60 / 15
                                                    ; (assuming 13518 cycles per frame)

481E 0010                 @@spin  DECR  R0          ; 6 cycles
481F 022C 0002                    BNEQ  @@spin      ; 9 cycles
                                                    ; -> 15 cycles per iteration

4821 0114                         SUBR  R2,     R4  ; reset pointer to beginning of string
4822 0011                         DECR  R1          ; decrement uppercase counter
4823 022C 001D                    BNEQ  @@loop      ; process next iteration or stop

4825 0017                         DECR  PC          ; infinite loop

4826 000B 0068 0065 006C  @@str   STRING 11, "hello world"
482A 006C 006F 0020 0077
482E 006F 0072 006C 0064
                                  ENDP

Output

enter image description here

\$\endgroup\$
7
\$\begingroup\$

MATL, 30 bytes

11:"10&Xx'hello world't@)Xk@(D

Try it at MATL Online!

11:              % Push [1 2 ... 11]
  "              % For each k in [1 2 ... 11]
  10&Xx          %   Pause for 10 tenths of a second and clear screen
  'hello world'  %   Push this string
  t              %   Duplicate
  @)             %   Get the k-th character from the duplicated string
  Xk             %   Convert to uppercase
  @(             %   Write into the k-th position of the string
  D              %   Display
                 % Implicit end
\$\endgroup\$
5
\$\begingroup\$

PHP, 76 74 71 bytes

Thank you @hd for the delay being a full second and no fraction thereof!
Thanks @user63956 for 2 bytes and @aross for 3 bytes.

for(;$c=($s="hello world")[$i];sleep(print"$s\r"))$s[$i++]=ucfirst($c);

Run with -nr.

\$\endgroup\$
2
  • 1
    \$\begingroup\$ You can save 2 bytes with sleep(print"$s\r"). \$\endgroup\$
    – user63956
    Feb 14, 2017 at 5:54
  • 1
    \$\begingroup\$ Save 3 bytes with ucfirst \$\endgroup\$
    – aross
    Feb 15, 2017 at 15:11
4
\$\begingroup\$

C, 97 withdrawn 106 bytes

with escaped characters counted as 1 byte

char*a="HELLO\0WORLD\xED";b,c;m(){for(b=0;b<156;putchar(a[c]+32*(b/12^c||c==5)))(c=b++%12)||fflush(sleep(1));}

Note: I have commented out the time delay on unlinked TIO because it waits for completion before displaying the output, it also doesn't seem to recognize carriage returns and puts new lines. Also, if you're on Windows, sleep is in milliseconds instead of seconds, so sleep(1) should become sleep(1000).

Note 2: I've withdrawn this entry for the moment until the output bugs have been ironed out.

\$\endgroup\$
4
  • \$\begingroup\$ For some reason, this doesn't output anything on my machine \$\endgroup\$
    – user41805
    Feb 13, 2017 at 12:35
  • \$\begingroup\$ If you're on windows you will have to change the delay, it will also finish on a carriage return so you may want to change 130 to 129 so it avoids printing it during the last iteration. \$\endgroup\$
    – Ahemone
    Feb 13, 2017 at 12:38
  • \$\begingroup\$ For me this program does not end at all, and it doesn't output anything. I had to manually ^C it to stop it . (also I'm on mac) \$\endgroup\$
    – user41805
    Feb 13, 2017 at 12:40
  • \$\begingroup\$ I believe it's a print buffer issue, I'll withdraw my entry for now. \$\endgroup\$
    – Ahemone
    Feb 13, 2017 at 12:57
4
\$\begingroup\$

JavaScript (ES6), 141 139 131 bytes

Saved 8B thanks to Apsillers

_=>a=setInterval("b=[...`hello world`],c.clear(b[d]=b[d].toUpperCase(++d>10&&clearInterval(a))),c.log(b.join``)",1e3,c=console,d=0)

Explanation

This creates a function with no arguments, which splits the string hello world into an array of characters and capitalises the d+1th character. d is a counter that starts as 0 and is increased every time.

Usage

f=_=>a=setInterval("b=[...`hello world`],c.clear(b[d]=b[d].toUpperCase(++d>10&&clearInterval(a))),c.log(b.join``)",1e3,c=console,d=0)
f()
\$\endgroup\$
5
  • \$\begingroup\$ Clever, I'll update it. \$\endgroup\$
    – Luke
    Feb 13, 2017 at 15:32
  • \$\begingroup\$ Also, I don't see any reason to make this a function, since it takes no input -- just run the code, right? \$\endgroup\$
    – apsillers
    Feb 13, 2017 at 15:33
  • \$\begingroup\$ The question says it's supposed to be a program, but in that case you can also submit a function. Code snippets are generally not allowed. \$\endgroup\$
    – Luke
    Feb 13, 2017 at 15:38
  • \$\begingroup\$ This is nice, gg! \$\endgroup\$
    – ʰᵈˑ
    Feb 13, 2017 at 15:45
  • \$\begingroup\$ Can you distinguish between your understanding of a disallowed "code snippet" versus an allowed "program" in this case? If you just remove the leading _=> you do have a complete program (e.g., if you stuck it in a file, Node.js would run successfully it to completion). My understanding of the prohibition against "code snippets" is against writing code that implicitly accepts some input as a variable, like "if we assume i already has the input, we can do..." which is not happening here, since there explicitly is no input. \$\endgroup\$
    – apsillers
    Feb 13, 2017 at 15:45
4
\$\begingroup\$

Noodel, 22 bytes

”<8@\|DḶ|\6þıHḶƥɲSḍsɲS

Try it:)


How it works

”<8@\|DḶ|\6þ           # Displays the string "hello¤world".
”<8@\|DḶ|\6            # Decompresses to the array ["h", "e", "l", "l", "o", "¤", "w", "o", "r", "l", "d"] and pushes it on top of the stack.
           þ           # Pushes a copy of the array to the screen which since is an array is done by reference.

            ı          # Makes the array on the top of the stack the new stack.

             HḶƥɲSḍsɲS # Loops eleven times creating the animation.
             H         # Pushes the string "H" on to the top of the stack.
              Ḷ        # Consumes the "H" that gets evaluated as a base 98 number which comes out to eleven.
               ƥ       # Move the stack pointer up one.
                ɲS     # Switch the case of the top of the stack which will show up on the screen because the array is done by reference.
                  ḍs   # Delay for one second.
                    ɲS # Switch the case back.
                       # Implicit end of the loop.

The snippet uses a 25 byte version that loops continuously.

<div id="noodel" cols="10" rows="2" code="”<8@\|DḶ|\6þıḷʠ*HḶƥɲSḍsɲS" input=""/>
<script src="https://tkellehe.github.io/noodel/release/noodel-2.5.js"></script>
<script src="https://tkellehe.github.io/noodel/ppcg.min.js"></script>

\$\endgroup\$
4
\$\begingroup\$

Bash + coreutils, 99 98 bytes

x=hello\ world
for((;n<11;)){
echo -en "\r${x:0:n}"`tr a-z A-Z<<<"${x:n:1}"`"${x:n+++1}"
sleep 1
}
\$\endgroup\$
3
\$\begingroup\$

Perl 6, 65 61 bytes

for 3..12 ->\i{sleep say "\echello world".&{S:nth(i)/./{$/.uc}/}}

(sleep say S:nth(3+$++)/./{$/.uc}/with "\echello world")xx 11

GIF: enter image description here

How it works

The ANSI escape sequence \ec clears the screen.
Each iteration, the i'th character of the hard-coded string is substituted by its upper-case version.
The say function always returns True, which is passed on to the sleep function which interprets it as 1 second.

\$\endgroup\$
3
\$\begingroup\$

Ruby, 82 81 bytes

12.times{|a|$><<?^H*11;'Hello world'.chars{|y|$><<((0!=a-=1)?y:y.upcase)};sleep 1}

^H is ascii 8 (backspace), and is only 1 byte.

\$\endgroup\$
3
\$\begingroup\$

C, 87 bytes

m(){char*f,a[]="\rhello world";for(f=a;*++f;*f&=95,printf(a),*f|=32,fflush(sleep(1)));}

Compiles and runs on Linux.

\$\endgroup\$
3
\$\begingroup\$

Mathematica, 130 128 123 110 108 bytes

Dynamic@o
s="hello world";i=1;t=StringTake;Do[o=t[s,{1,i-1}]<>Capitalize@t[s,{i}]<>t[s,{++i,11}];Pause@1,11]

Explanation: From i=1 to 11, print from the 1st to the (i-1)th character of "hello world", capitalise "hello world"[i], then print the rest of the string, incrementing i at the same time.

\$\endgroup\$
3
\$\begingroup\$

Java 215 212 204 203 bytes

interface A{static void main(String z[])throws Exception{for(int i=0;i<10;i++){char[]b="helloworld".toCharArray();b[i]=Character.toUpperCase(b[i]);System.out.println(new String(b));Thread.sleep(1000);}}}

Ungolfed:

 interface A {
 static void main(String z[]) throws Exception {
    for (int i = 0; i < 10; i++) {
        char[] b = "helloworld".toCharArray();
        b[i] = Character.toUpperCase(b[i]);
        System.out.println(new String(b));
        Thread.sleep(1000);
    }
  }
}
\$\endgroup\$
4
  • 1
    \$\begingroup\$ Shouldn't it be interface A (with a space)? Plus you can remove the space between , and Character.toUpperCase. \$\endgroup\$ Dec 7, 2017 at 21:51
  • 2
    \$\begingroup\$ Welcome to the site! \$\endgroup\$
    – DJMcMayhem
    Dec 7, 2017 at 21:53
  • \$\begingroup\$ Kudos to @NoOneIsHere for the 3 points \$\endgroup\$ Dec 7, 2017 at 21:55
  • \$\begingroup\$ Thanks @DJMcMayhem, Always liked reading through the challenges and finally got to answer one! \$\endgroup\$ Dec 7, 2017 at 22:00
3
\$\begingroup\$

R, 106 103 bytes

x=el(strsplit("hello world",""))
for(i in 1:11){y=x;y[i]=toupper(y[i]);cat('\f',y,sep='');Sys.sleep(1)}

Just a simple loop, clearing the console with cat('\f') seems somewhat system-dependent but I am not aware of a better way.

\$\endgroup\$
1
  • \$\begingroup\$ I tried outgolfing this using utf8ToInt. This did not work, the space needs to be handled as a special case. In the process I discovered that cat("\014") seemed to work better then work where cat("\f") did not.but not on TIO \$\endgroup\$
    – JayCe
    Jul 16, 2018 at 17:33
2
\$\begingroup\$

C, 122 bytes

i;f(){char s[]="Hello world\r";for(i=0;i<11;i++){s[i]=toupper(s[i]);s[i-1]=tolower(s[i-1]);printf(s);fflush(0);sleep(1);}}

Shorter than C# :D

\$\endgroup\$
1
  • 1
    \$\begingroup\$ Also for the last frame to be visible, you have to do i<11 instead of i<10 in your for-loop \$\endgroup\$
    – user41805
    Feb 13, 2017 at 11:23
2
\$\begingroup\$

Perl, 75 bytes

sleep print"\33c".("hello world"=~s/(.{$_})(.)(.*)/$1\U$2\E$3\n/r)for 0..10

Uses the ANSI code ESCc to clear the console and move the cursor to the top left at every iteration, but still needs \n at the end of the replace string to avoid having the whole animation lost in the line buffer.

A successful call to print returns a value of 1, which can be passed directly to sleep.

\$\endgroup\$
1
  • \$\begingroup\$ You can use $` and $' to save a few bytes on that (.{$_})(.)(.*) (it won't work in a terminal, but that's not a problem). It requires modifying a little bit the rest of your code though: "hello world"=~s/./sleep print"\33c$`\U$&\E$'\n"/ger. (I wrote almost this exact code, then when looking if anyone had posted a perl answer yet, I found yours). And a little detail about the bytecount : you can use a litteral newline to save a byte, and maybe some kind of litteral \33c (not too sure about that last one though). \$\endgroup\$
    – Dada
    Feb 14, 2017 at 22:12
2
\$\begingroup\$

SmileBASIC, 90 71 bytes

FOR I=0TO 10CLS?"hello world
LOCATE I,0?CHR$(CHKCHR(I,0)-32)WAIT 60NEXT
\$\endgroup\$
2
\$\begingroup\$

Jelly, 24 21 bytes

”Æ⁹Œu⁸¦ȮœS
“½,⁻⁸3»Jç€

This is a niladic link/function that prints to STDOUT. It does not work as a full program.

The code can't be tested on TIO; it uses control characters and TIO has no terminal emulator (yet).

How it works

“½,⁻⁸3»Jç€  Niladic link. No arguments.

“½,⁻⁸3»     Index into Jelly's dictionary to yield "hello world".
       J    Indices; yield [1, ..., 11].
        ç€  Apply the helper link to each index, with right arg. "hello world".


”Æ⁹Œu⁸¦ȮœS  Dyadic helper link. Left argument: i. Right argument: "hello world"

Ӯ          Set the return value to '\r'.
  ⁹         Set the return value to "hello world". Implicitly prints '\r'.
   Œu⁸¦     Uppercase the i-th letter.
       Ȯ    Print.
        œS  Sleep "hello world" seconds. (Strings are cast to Boolean.)
\$\endgroup\$
1
  • \$\begingroup\$ (Strings are cast to Boolean.) That's devious! \$\endgroup\$ May 5, 2017 at 13:35
2
\$\begingroup\$

C, 122 bytes

As an exercise, I wrote this to provide a more optimal output format than some of the other answers. Also it means the cursor sits after the most recently capitalized letter during the pauses.

main(){
    char*p=".Hello world\rH";
    write(1,p+1,13);
    do{
        sleep(1);
        *p=8;
        p[1]|=32;
        p[2]^=(p[2]>32)*32;
        write(1,p++,3);
    }while(p[4]);
}

(Newlines and indentations cosmetic and not part of byte count)

Now, some readers may note that this requires some massaging to get to run on modern machines (the magic incantation is -static -Wl,-N), but this is how real implementations of C used to behave, so I think it is valid. It also assumes the character set is ASCII, and it does not print a trailing newline.

Bonus: For an EBCDIC version, you can replace 8 with 22 and 64 with 32, and switch the logic for p[1] and p[2]. To test on a non-EBCDIC system, you can compile with -funsigned-char -fexec-charset=cp037.

Output is 43 bytes: Hello world«H‹hE‹eL‹lL‹lO‹o ‹ W‹wO‹oR‹rL‹lD

\$\endgroup\$
2
\$\begingroup\$

Scala, 92 bytes

val h="hello world"
0 to 10 map{i=>print("\b"*99+h.updated(i,h(i)toUpper))
Thread sleep 999}

Ungolfed

val h="hello world"    //declare a variable h with the string "hello world"
0 to 10                //create a range from 0 to 10
map { i=>              //loop with index i
  print(                 //print
    "\b" * 99              //99 backspace chars
    + h.updated(           //and h with
      i,                     //the i-th char
      h(i).toUpper           //replaced with the i-th char in uppercase
    )     
  )
  Thread sleep 999       //sleep 999 ms
}
\$\endgroup\$
1
  • 1
    \$\begingroup\$ +1 for h(i)toUpper \$\endgroup\$ Feb 14, 2017 at 2:48
2
\$\begingroup\$

Clojure, 116 bytes

(doseq[i(range 11)](Thread/sleep 1000)(print"\r"(apply str(update(vec"hello world")i #(char(-(int %) 32)))))(flush))

Basically a for-loop that goes over the indices of each character, updating each character in turn.

(defn -main []
  (doseq [i (range 11)] ; For the index of each character...
    (Thread/sleep 1000)
    (print "\r" ; Clear old line
           (apply str ; Turn the vector back into a string
             (update ; Update the char at index i
               (vec "hello world") ; Turn the string into a vector so it's updatable
               i ; Index to update
               #(char (- (int %) 32))))) ; Subtract 32 from the character to make uppercase
    (flush)))
\$\endgroup\$
2
\$\begingroup\$

Batch, 184 bytes

@echo off
for %%h in (Hello hEllo heLlo helLo hellO hello)do call:c %%h world
for %%w in (World wOrld woRld worLd worlD)do call:c hello %%w
exit/b
:c
timeout/t>nul 1
cls
echo %*

Curiously the command line for timeout/t>nul 1 gets corrupted if there is no trailing newline, so I can't put it at the end of the file.

\$\endgroup\$
2
\$\begingroup\$

Ruby, 108 bytes

First time, first year student. It's no eagle but I'm at least a little proud.

12.times{|i|sleep(0.1); puts "\e[H\e[2J", "hello world".sub(/(?<=.{#{Regexp.quote(i.to_s)}})./, &:upcase);}
\$\endgroup\$
2
\$\begingroup\$

Pascal, 187 152 bytes

Not exactly the most efficient or the shortest, but works quite well!

uses crt,sysutils;label R;const X:Word=1;P='hello world';begin
R:clrscr;write(P);gotoxy(X,1);write(upcase(P[X]));sleep(999);X:=X*Ord(X<11)+1;goto R
end.

Tested and works on Free Pascal Compiler 2.6+.

Thanks to @manatwork for saving 35 bytes!


I've used http://www.onlinecompiler.net/pascal to compile the file and run it on Windows.
Haven't seen any problem with it, so far.

\$\endgroup\$
3
  • \$\begingroup\$ An UpCase function exists since the old Turbo times. (There it handled only Char, but in Free Pascal also handles strings.) \$\endgroup\$
    – manatwork
    Feb 14, 2017 at 8:35
  • \$\begingroup\$ A couple of minor tweaks: is enough to declare X Word (or Byte); make P a const so it infers type from initialization value; while there, make X an initialized constant to get rid of separate var keyword (this one may not work in all Pascal variants, but certainly does in Free Pascal); use ClrScr to jump to top left corner; replace that if with a single expression: X:=X*Ord(X<11)+1. pastebin.com/FfaixkES \$\endgroup\$
    – manatwork
    Feb 14, 2017 at 8:56
  • \$\begingroup\$ I really didn't knew that const X:Word=1;P='hello world'; and that const X:Word=1;P='hello world'; were possible. I learned Pascal on Turbo Pascal 7, which may not be compatible with that. And completely forgot about upcase. Thank you a lot! \$\endgroup\$ Feb 14, 2017 at 11:58
2
\$\begingroup\$

C 120 110 104 96 bytes

f(){char *j,s[]="\rhello world";for(j=s;*++j;*j-=32,printf(s),*j+=32,fflush(0),sleep(‌​1));}

Ungolfed version

void f()
{
  char *j;
  char s[]="hello world";
  j=s; 

   for (;*j;j++)
   {
      *j-=32;  
       printf(s); // print the string and right after change the same char to lower case
       *j+=32;
      fflush(0);
      sleep(1);
   }

}

@Pakk Thanks for saving some bytes, great idea. :)

@Pakk @KarlNapf Thanks guys for your inputs.

can still be shortened!? :)

\$\endgroup\$
14
  • \$\begingroup\$ Use -= and +=. Also, a pointer variable might save the [] but i am not sure. \$\endgroup\$
    – Karl Napf
    Feb 13, 2017 at 12:33
  • 1
    \$\begingroup\$ char *j;f(){char s[]="hello world";for(j=s;*j;j++){*j-=32;printf("\r%s",s);*j+=32;fflush(0);sleep(1);}} (103 chars) \$\endgroup\$
    – user34409
    Feb 13, 2017 at 12:52
  • 1
    \$\begingroup\$ Idea behind previous comment: Make it lowercase again after the printf, then you don't have to check if j-1 exists. And use pointers to save some characters. \$\endgroup\$
    – user34409
    Feb 13, 2017 at 12:53
  • 2
    \$\begingroup\$ char *j,s[]="hello world"; to save a few more chars. \$\endgroup\$
    – user34409
    Feb 13, 2017 at 14:40
  • 1
    \$\begingroup\$ f(){char*j,s[]="\rhello world";for(j=s;*++j;*j-=32,printf(s),*j+=32,fflush(0),sleep(1));} 89 bytes. \$\endgroup\$
    – Karl Napf
    Feb 14, 2017 at 11:47
2
\$\begingroup\$

Python 2, 220 189 179 bytes

Solution without using strings and capitalize(), byte count as is:

import time,sys
from numpy import *
F=fromstring("\rhello world",int8)
for i in range(1,12):
    time.sleep(1)
    F[i]-=32
    savetxt(sys.stdout,F,fmt="%c",newline="")
    F[i]+=32

And a bit longer variant (191 chars) without case resetting:

import time,sys
from numpy import *
a=arange(11)
F=tile(fromstring("\rhello world",int8),(11,1))
F[a,a+1]-=32
for i in a:
    time.sleep(1)
    savetxt(sys.stdout,F[i],fmt="%c",newline="")
\$\endgroup\$
1
  • \$\begingroup\$ Welcome to the site! It looks like you have done extra whitespace. Particularly around your equal signs \$\endgroup\$
    – Wheat Wizard
    Feb 14, 2017 at 1:58

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

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