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\$
  • \$\begingroup\$ Can it exit and stop with an error? \$\endgroup\$ – Stewie Griffin Feb 13 '17 at 12:26
  • \$\begingroup\$ @StewieGriffin as long as the animation is viewable, sure. \$\endgroup\$ – ʰᵈˑ Feb 13 '17 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 '17 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 '17 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 '17 at 17:06

50 Answers 50

2
\$\begingroup\$

Linux C, 180 bytes code, 6336 bytes binary (gcc+strip x86_64)

#include<unistd.h>
char s[]="\rhello world";
int main(){int n;for(n=1;s[n]!=0;n++){if(s[n]>0x40)s[n]^=0x20;if(n>1)if(s[n-1]>0x40)s[n-1]^=0x20;write(1,&s,sizeof(s)-1);sleep(1);};};
\$\endgroup\$
  • 1
    \$\begingroup\$ Do you mind putting the byte count and language in the header? Formatting is like this: # <Language>, <N> bytes \$\endgroup\$ – Cyoce Feb 15 '17 at 19:59
  • \$\begingroup\$ You can golf a few bytes by changing 0x20 into 32 \$\endgroup\$ – cookie Mar 13 '17 at 12:28
2
\$\begingroup\$

AWK, 123 bytes

BEGIN{s="hello world\n"
split(s,a,"")
for(L=1;L<12;L++){for(m=1;m<13;m++)printf m==L?toupper(a[m]):a[m]
system("sleep 1")}}

Fairly standard AWK but it does require the availability of sleep. On my Linux box the default argument to sleep is an integer number of seconds.

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

Java, 137 bytes

String q="HELLO WORLD";for(int x,i=0;i<132;System.out.print((char)(x>10?10:(x!=i/12?32:0)|q.charAt(x))))Thread.sleep((x=i++%12)<1?999:0);

Ungolfed and with comments:

    String q = "HELLO WORLD"; // note that the string is 11 characters long
    for (int x, i = 0;
         i < 132; // 11 rows, 12 columns (one column for newlines)
         System.out.print((char) (x > 10 ? // if this is the last column
                 10 // print newline
                 : // else:
                 (x != i / 12 ? //check if column == row
                         32 : 0) | q.charAt(x)))) // de-capitalize
        Thread.sleep((x = i++ % 12) < 1 ? 999 : 0); // if this is the first column, wait almost 1 second.
    // the above line will also update i and x

Edit: A full program would take 196 bytes

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

Common Lisp, 108 bytes

(let((a"hello world"))(dotimes(i 11)(format t"~a~c"(string-upcase a :start i :end(1+ i))#\return)(sleep 1)))

Works on a regular terminal, on tio.run does not overwrite the string.

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

PowerShell 3.0, 72 63 Bytes

-9 bytes thanks to mazzy

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

Not too shabby.

\$\endgroup\$
  • \$\begingroup\$ It can to save some bytes 0..10|%{cls;($s=[char[]]'hello world')[$_]-=32;-join$s;sleep 1} \$\endgroup\$ – mazzy Jul 18 '18 at 12:47
1
\$\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\$
1
\$\begingroup\$

Haskell 232 212 Bytes

The trickiest part was reliably implementing a delay using prelude. Control.Concurrent threadDelay could be used for a robust solution. I started with delay n= foldr seq "\&" (drop n[5.5*10^6..10^7] which works in the REPL, however does not work compiled into a .exe.

enter image description here

Golfed Version

d=[0..10]>>"\BS"
p=concat$replicate(2*10^5)" \BS"
l=zip['a'..'z']['A'..'Z']
t x=([u|(l,u)<-l,l==x]++" ")!!0
y(x:xs)e|length xs==12-e=t x:xs|1>0=x:(y xs e)
main = do mapM_ putStr$[y"hello world"x++p++d|x<-[2..12]]

Explanation:

--Create a row of backspaces. When sent to IO deletes last character
delrow= [0..10]>>"\BS"

--print beaucoup spaces and backspaces
printblank = concat $ replicate (200000)  (' ':"\BS")


--Helpers to create a caps letter
lowerandupper = zip (['a'..'z']) (['A'..'Z'])
toupper x = head ([u|(l,u)<-lowerandupper, l==x]++" ")
touppers (x:xs) elem | length xs == 12- elem = toupper x :xs
                   | 1>0 = x: (touppers xs elem)

main = do
        --use mapM_ to putStr for each element of list
        mapM_ putStr $ [touppers "hello world" x ++ printblank++delrow|x <-[2..12]]

Looking forward to comments, feedback and improvements.

@laikoni thanks for the inputs saving numerous bytes.

\$\endgroup\$
  • 1
    \$\begingroup\$ There appears to be an identifier elem in your golfed code which could be shortened. Also using line breaks instead of ; results in the same byte count but slightly better readable code. \$\endgroup\$ – Laikoni Feb 13 '17 at 21:48
  • \$\begingroup\$ Instead of delrow, can't you just print a carriage return? \$\endgroup\$ – Carcigenicate Feb 13 '17 at 21:50
  • 1
    \$\begingroup\$ (' ':"\BS") is just " \BS". You don't need parenthesis around lists. There is unnecessary whitespace in your main and I think you don't need the do. \$\endgroup\$ – Laikoni Feb 13 '17 at 21:54
  • \$\begingroup\$ @Carcigenicate I was looking at that, but carriage return will start a new line. For example, putStr "Hello world">>= \x -> (putStr "\r")>>= (\y -> putStr "Hello world") would return 2 lines: Hello world Hello world whereas putStr "Hello world">>= \x -> (putStr delrow)>>= (\y -> putStr "Hello world") returns just 1 line \$\endgroup\$ – brander Feb 13 '17 at 22:07
  • \$\begingroup\$ It shouldn't. And why not just do putStr "\rhello world"? \$\endgroup\$ – Carcigenicate Feb 13 '17 at 22:09
1
\$\begingroup\$

Rebol, 70 bytes

repeat n 11[prin[head uppercase/part at copy"hello world^M"n 1]wait 1]

Ungolfed:

repeat n 11 [
    prin [head uppercase/part at copy "hello world^M" n 1]
    wait 1
]
\$\endgroup\$
1
\$\begingroup\$

Java - 240 bytes

interface a{static void main(String[]a)throws Throwable{int x=1;char[]b="\rhello world".toCharArray();while(x<12){if(b[x]!=' ')b[x]=(char)((int)b[x]^32);System.out.print(b);Thread.sleep(1000);if(b[x]!=' ')b[x]=(char)((int)b[x]^32);x++;}}}

Ungolfed version:

interface a {
    static void main(String[] a) throws Throwable {
        int x = 1;
        char[] b = "\rhello world".toCharArray();
        while(x < 12) {
            if (b[x] != ' ')
                b[x]=(char)((int)b[x]^32);
            System.out.print(b);
            Thread.sleep(1000);
            if (b[x] != ' ')
                b[x]=(char)((int)b[x]^32);
            x++;
        }
    }
}

GIF of it

\$\endgroup\$
1
\$\begingroup\$

Scala, 139 Bytes

() => {
    val a = "\033[H\033[2J\nhello world"
    8 to 19 map{c=>
        print(a.updated(c,a(c)toUpper))
        Thread.sleep(1000)
    }
}
\$\endgroup\$
1
\$\begingroup\$

Ruby, 56 bytes

"hello world".gsub(/./){$><<?\r+$`+$&.upcase+$'
sleep 1}
\$\endgroup\$
1
\$\begingroup\$

Perl 5, 49 bytes

sleep say"chello world"^""x$_.$"x!/7/ for 2..12

Try it online! - only really works in a terminal, but you can easily copy/paste from here.

Explanation

This script uses the stringwise XOR operation to capitalise the needed letters in each iteration. First we build the string 'hello world' (which includes \x1bc as an ANSI escape sequence to clear the screen), then we XOR (^) against a string of repeating NUL bytes (repeating as needed, 2 on the first iteration and finishing with 12), followed by a space ($") on all but the 7th iteration (which would remove the space in the middle - well, set it to NUL).

Please note this script contains unprintables, here's a reversible hex dump:

00000000: 736c 6565 7020 7361 7922 1b63 6865 6c6c  sleep say".chell
00000010: 6f20 776f 726c 6422 5e22 0022 7824 5f2e  o world"^"."x$_.
00000020: 2422 7821 2f37 2f20 666f 7220 322e 2e31  $"x!/7/ for 2..1
00000030: 32                                       2
\$\endgroup\$
1
\$\begingroup\$

Small Basic, 166 bytes

Takes no input and outputs to the TextWindow.

For i=1To 11
l=0
t="hello world
p()
l=i-1
t=Text.GetSubText("HELLO WORLD",i,1)
p()
Program.Delay(1000)
EndFor
Sub p
TextWindow.CursorLeft=l
TextWindow.Write(t)
EndSub

Try it at SmallBasic.com! Requires Silverlight/IE

\$\endgroup\$
1
\$\begingroup\$

C (MinGW), 83 80 77 bytes

Only tested on Windows.

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

\$\endgroup\$
1
\$\begingroup\$

Forth (gforth), 103 bytes

: f s" hello world"11 0 do page over dup i type i + dup c@ toupper emit 1+ over i - type 1000 ms loop ;

Try it online!

Doesn't work properly in TIO, but if you copy and paste into a gforth interpreter/terminal you get a proper animation.

I overwrote page and 1000 in the tio header so the output was readable and didn't take 10+ seconds to render, but the value in the "code" box is correct

Explanation

Loops through all characters in "hello world". For each one:

  • Clear screen and set cursor to top left of terminal/window
  • Output all characters before the current one
  • Output the current character uppercase (or as-is for space)
  • Output all characters after the current one
  • Wait 1 sec (1000 milliseconds)

Code Explanation

: f                 \ start a new word definition
  s" hello world"   \ create a string containing "hello world"
  11 0              \ set up loop parameters
  do                \ loop from 0 to 10 inclusive
    page            \ clear the screen/terminal and set cursor to top left
    over            \ get the string's starting address
    dup i type      \ output the first i characters of the string
    i + dup c@      \ get the value at the address of the current character
    toupper emit    \ convert to uppercase and output
    1+ over i -     \ add 1 to address, subtract current index from string length
    type            \ output end of string
    1000 ms         \ wait 1 seconds
  loop              \ end loop
;                   \ end word definition
\$\endgroup\$
1
\$\begingroup\$

x86 opcode(.COM), 48 bytes

  org 100h
  mov ax, 0x0900
  mov bx, -34
  out 0x70,al
  mov dx, stri
  int 0x21
  push 0xa802
  pop ds
r:in  al,0x71
  cmp al,cl
  jz  r
  xchg ax,cx
  xor [bx],dword 0x200020
  add bx, 2
  jnz r
  stri db 'hello world$'  
\$\endgroup\$
0
\$\begingroup\$

PowerShell, 76 bytes

$b= # The solution is the next line
{$a=[char[]]$_;1..$a.length|%{$a[--$_]-=32;cls;-join$a;$a[$_]-=-32;sleep 1}}
'hello world'|% $b
\$\endgroup\$
0
\$\begingroup\$

ES2015, 126 bytes

Based on this answer.

c=console;d=0;t=_=>setTimeout(_=>{a=[...`hello world`];a[d]?c.clear(a[d]=a[d++].toUpperCase())|t(c.log(a.join``)):a},1e3);t()

\$\endgroup\$
0
\$\begingroup\$

Mathematica, 104 bytes

Monitor[Do[s=y=Characters@"hello world";s=s~Delete~i;Pause@1,{i,11}],""<>Insert[s,Capitalize[y][[i]],i]]
\$\endgroup\$
0
\$\begingroup\$

C# (Visual C# Compiler), 217 bytes

using u=System.Console;class P{static string a="hello world";static void Main(){for(int i=0;i<11;i++){u.Clear();u.WriteLine(a.Substring(0,i)+char.ToUpper(a[i])+a.Substring(i+1));System.Threading.Thread.Sleep(1000);}}}

Try it online!

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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