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

1
2
2
\$\begingroup\$

C++, 88 125 Bytes

#include<iostream>#include<unistd.h>
int main(){for(int c;++c<12;){char a[]="\rhello world";a[c]-=32;std::cout<<a;sleep(1);}}

Ungolfed version:

#include <iostream>
#include <unistd.h>

int main()
{
   for (int c;++c<12;)
   {
      char a[] = "\rhello world";
      a[c]-=32;
      std::cout << a;
      sleep(1);
   }
}

Compiled with TDM-GCC on a Windows 10 machine with Dev-C++.

Edit: I forgot the includes in my first version.

\$\endgroup\$
4
  • \$\begingroup\$ Hey, you're the guy that helped me with my C# answer! Your C++ approach made me realise I can actually remove that condition from my for loop by moving the carriage return to the beginning of the string.. I'll help you too: Doing for(int c=1;;c++) will save you 1 byte. \$\endgroup\$
    – Metoniem
    Feb 15, 2017 at 12:38
  • \$\begingroup\$ Also like you suggested in my C# answer, in combination with my last comment you could then do for(int c=1;;) and then a[c++]-=32; to save another byte. \$\endgroup\$
    – Metoniem
    Feb 15, 2017 at 12:44
  • \$\begingroup\$ But even with the carriage return in the beginning, it still prints a character (Ó in my case) to the output after hello world even though I'm not really sure why... \$\endgroup\$
    – Snowfire
    Feb 15, 2017 at 12:48
  • \$\begingroup\$ That's... rather strange. That shouldn't happen?! \$\endgroup\$
    – Metoniem
    Feb 15, 2017 at 12:57
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\$
2
  • 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, 2017 at 19:59
  • \$\begingroup\$ You can golf a few bytes by changing 0x20 into 32 \$\endgroup\$
    – cookie
    Mar 13, 2017 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\$
1
  • \$\begingroup\$ It can to save some bytes 0..10|%{cls;($s=[char[]]'hello world')[$_]-=32;-join$s;sleep 1} \$\endgroup\$
    – mazzy
    Jul 18, 2018 at 12:47
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\$
6
  • 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, 2017 at 21:48
  • \$\begingroup\$ Instead of delrow, can't you just print a carriage return? \$\endgroup\$ Feb 13, 2017 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, 2017 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, 2017 at 22:07
  • \$\begingroup\$ It shouldn't. And why not just do putStr "\rhello world"? \$\endgroup\$ Feb 13, 2017 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\$
1
\$\begingroup\$

Stax, 22 bytes

▒4↓σ┘«☼⌡♥Åα≡♂%Ç$K¥╞▲▓►

Run and debug it

delaying takes a lotta bytes.

\$\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\$
0
\$\begingroup\$

Haskell, 161 bytes

import Data.Char;import System.IO;main=mapM(\x->do putStr$('\b'<$z)++[(toUpper v:(v<$z))!!abs(k-x)|(v,k)<-zip"hello world"z];hWaitForInput stdin 1000)z;z=[0..10]

Unfortunately it doesn't quite work in TIO.

\$\endgroup\$
1
2

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.