Dealing with colors in non-markup languages often complicates things. I would like to see some variations of how color is used in different languages.

The object of this competition is to output 'Hello World' in the seven colors of the rainbow.

According to Wikipedia, these are the 7 colors.

Red      #FF0000 (RGB: 255, 0, 0)
Orange   #FF7F00 (RGB: 255, 127, 0)
Yellow   #FFFF00 (RGB: 255, 255, 0)
Green    #00FF00 (RGB: 0, 255, 0)
Blue     #0000FF (RGB: 0, 0, 255)
Indigo   #6600FF (RGB: 111, 0, 255)
Violet   #8B00FF (RGB: 143, 0, 255)

The rules

  1. The program must output 'Hello World'. (Doesn't necessarily need to be text, but it must be distiguishable as 'Hello World')
  2. Each letter must be a different color.
  3. The colors can be in any order.
  4. You must use each of the seven colors at least once. (You may use more than the given colors)
  5. No use of markup languages in any case.

The winner is whoever has the lowest amount of characters AND follows the rules

Bonus -1 character if it is written in DART

I will pick the winner on Jan 11 (if I remember ;D).

Good luck


I made a mistake D:, updated winners.

1st. stranac - Python, 60 chars

2nd. Ilmari - Karonen Perl + GD, 146 chars

Shortest length with all rules adhered to.

Brownie points to JiminP for the DART answer.


13 Answers 13



ImageMultiply[ColorNegate[Graphics[Text[Style["Hello World",30]],ImageSize->190]],ColorData["Rainbow","Image"]]

I know, I know, it doesn't comply with the rules.. but I had to try playing with Mathematica's image processing functions.


Hello World!!!!!!!


Haskell, 88 characters

f(c,n)=putStr$"\27["++show n++"m"++[c]
main=mapM_ f$zip"Hello World\n"$35:cycle[31..36]


Note that this uses ANSI terminal colors, of which there are only 6 and they might not match the exact ones given (it depends on terminal settings), so I'm bending the rules a little here.

Slightly longer version with almost correct colors, 107 characters

This version uses xterm colors instead of ANSI ones. This does not rely on any custom palettes, and uses the closest colors I could find in the 256-color xterm palette.

f(c,n)=putStr$"\27[38;5;"++show n++"m"++[c]
main=mapM_ f$zip"Hello World\n"$cycle[196,208,226,46,21,57,93]

enter image description here


Python, 60 chars

Now using 7 colors, and the "correct" ones.

Uses ansi escape sequences. The underscore is there just so it's not an invisible space.

This version prints some extra spaces, because of the way python's print works, but those spaces save quite a few chars, so I'm fine with them being there.

for p in zip(range(7)*2,'Hello_World'):print'\033[3%im%s'%p,

And a screenshot, as required by MrZander: enter image description here

  • \$\begingroup\$ Have I made an error? Please post a screenshot proving that you used all colors properly. "8 Colors from black to white" doesn't sound like it used the 7 required colors. \$\endgroup\$
    – MrZander
    Jan 12, 2012 at 0:33
  • \$\begingroup\$ @MrZander: I have updated my answer, and hope it now pleases you. Btw, are you sure the 6th color you provided is correct? It is pretty much the same as the 7th. \$\endgroup\$
    – stranac
    Jan 12, 2012 at 1:05
  • \$\begingroup\$ Took it straight off Wikipedia... I'm no color expert haha. \$\endgroup\$
    – MrZander
    Jan 12, 2012 at 4:29
  • 2
    \$\begingroup\$ This relies on a custom palette to work. For example, the H is printed using the escape code for black, so it's not visible on most terminals. \$\endgroup\$
    – hammar
    Jan 12, 2012 at 4:58

Python, 261 chars

print'P3 67 5 255'
for i in range(335):print'%d %d %d'%(C+C[2:])[i%67/6]if 0x4f7c938a00e7df7d12208a8aa0220820a34413d154044105f7e8828a28808820828cf04f39100e0417d1>>i&1 else'0 0 0'

Implements the spec exactly, generating a ppm image. Here is the result, converted to gif and scaled up by a factor of 4:

enter image description here

  • \$\begingroup\$ Hehe, nice. Took me an embarrassingly long moment to understand. \$\endgroup\$
    – cemper93
    Jan 7, 2012 at 13:50
  • 2
    \$\begingroup\$ n=255;C=((n,0,0),(n,127,0),(n,n,0),(0,n,0),(0,0,n),(111,0,n),(143,0,n)) \$\endgroup\$ Jan 7, 2012 at 16:06

Perl -> ANSI terminal, 53 chars

s//Hello World/;s/./\e[3${[5,(1..6)x2]}[pos]m$&/g;say

This produces the exact same output as Hammar's Haskell solution. It uses say, so needs perl 5.10+ and the -M5.010 (or -E) switch. For older perls, replace say with print. A trivial one-character reduction could be achieved by replacing \e with a literal ESC character, but that would make the code much harder to read and edit.

Edit: Added two chars to match Hammar's output exactly, and to actually show all six possible terminal colors. (In the earlier version, the only character printed in color 6 = cyan was the space.)


Hello World

Edit 2: If using a custom terminal palette (and an underscore for the space) is allowed, then I can easily reproduce the exact colors given in the spec with just 50 chars:





Perl -> HTML, 99 chars

@c=(("00")x5,77,(ff)x5,77)x2;print"<font color=#",@c[$i+8,$i+4,$i++],">$_"for split//,"Hello World"


Hello World

The HTML probably won't pass any validators, but should be understood by just about all browsers. This code doesn't produce the exact RGB colors you listed, but it does get very close. Specifically, the colors of the letters are:

H  Red           #FF0000
e  Orange        #FF7700
l  Yellow        #FFFF00      
l  Chartreuse    #77FF00
o  Green         #00FF00
  (Spring green  #00FF77)
W  Cyan          #00FFFF
o  Sky blue      #0077FF
r  Blue          #0000FF
l  Indigo        #7700FF
d  Violet        #FF00FF

The output looks a lot nicer on a black background, but explicitly printing a <body bgcolor=black> would've cost me 28 extra characters. You may adjust your browser settings to achieve the same effect instead. :-)

  • 3
    \$\begingroup\$ I may not have been specific enough with rule 5. I didn't want to see markup used in conjunction with another language either. But in any case, very creative code. \$\endgroup\$
    – MrZander
    Jan 5, 2012 at 0:10

Perl + GD, 146 chars

Per the comments to my other answer, here's a solution that directly produces an image file using the GD library:

use GD'Simple;move{$m=new GD'Simple 70,12}2,12;s//Hello World/;s/./fgcolor$m(((0)x5,127,(255)x5,127)x2)[$i+8,$i+4,$i++];string$m$&/eg;print$m->png

And here's the output:

Hello World

Again, using a black background would look better, but would cost me 29 characters ($m->bgcolor(0,0,0);$m->clear;).

Edit: Figured out how to shave off 20 chars by (ab)using indirect object notation and a few other tweaks. The new code emits a warning, but still runs fine.

  • \$\begingroup\$ That's more like it ;) \$\endgroup\$
    – MrZander
    Jan 5, 2012 at 1:31
  • \$\begingroup\$ So far, this is the lowest character count that follows all the rules to the dot. \$\endgroup\$
    – MrZander
    Jan 7, 2012 at 2:54

Postscript 155 143

This relies on Ghostscript's ability to "figure-out" that Palatino is short for Palatino-Roman.

/h{c 1 1 sethsbcolor}def/c 0 def
200 400 moveto/Palatino 36 selectfont
h{32 ne{/c c .14 add dup 1 gt{1 sub}if def}if pop
h}(Hello World!)kshow
  • 1
    \$\begingroup\$ I suppose "Times" is shorter, but ... ugh. \$\endgroup\$ Sep 18, 2012 at 3:20
  • \$\begingroup\$ Stole some of your ideas... \$\endgroup\$
    – Thomas W.
    Oct 19, 2012 at 23:41

Some different approaches to doing this with


First: Shortest one (89):

9 9 moveto/Courier 9 selectfont
0{pop pop 
dup 1 1 sethsbcolor
.07 add}( Hello World)kshow

Rendered result


9 9 moveto
/Courier 9 selectfont
0                       % hue
{                       % hue c1 c2
  pop pop               % hue
  dup 1 1 sethsbcolor   % hue
  .07 add               % newHue
}( Hello World)kshow

This is continuously changing colour in x direction using the hsb color space. (Idea to use hsb colors and kshow are credited to luser droog - see his entry!) It does not use the exact seven colors given by MrZander.

When restricting myself to MrZander's colors, I get there using 141 chars:

9 9 moveto/Courier 9 selectfont(H e*l4l4oI  WIosrsl{d~)dup
0 2 20{2 copy
1 add get 32 sub 166 div 1 1 sethsbcolor
1 getinterval show

Rendered result

This encodes the hue value of MrZander's colors as one byte in the printable ASCII range. This byte is translated to a hue value in the range between 0 and 1 by subtracting 32 and dividing by 166. Each character of the "Hello World" string is followed by its encoded hue value.


9 9 moveto
/Courier 9 selectfont
(H e*l4l4oI  WIosrsl{d~)dup     % string string
0 2 20{                         % string string index
  2 copy                        % string string index string index
  1 add get                     % string string index hueChar
  32 sub 166 div                % string string index hueValue
  1 1 sethsbcolor               % string string index 
  1 getinterval                 % string substring
  show                          % string
  dup                           % string string

TODO: Something isn't quite right with the colors.


Some cheating but solve the problem

Bash + Ruby (needs lolcat gem)

echo Hello World | lolcat -p 0.25

Rainbow Hello World


Dart to HTML, 135 134-1 = 133

main(){for(var s="Hello World",i=0;i<11;print("<font color=#${'F00F60FB0FF06F00F00B606B00F60F90F'.substring(i*3,i*3+3)}>${s[i++]}"));}

Is there any way to color texts without using markup language? I can't test canvases...

  • \$\begingroup\$ Oooo... +1 even with the HTML \$\endgroup\$
    – MrZander
    Jan 7, 2012 at 17:30

I know it says "no markup in any case", but I'd like to submit this CSS one in 468 characters:

<style>b{font-weight:normal}i{font-style:normal}u{text-decoration:none}b:after{content:'e';color:orange}b:before{content:'H';color:red}i:after,i:before{content:'l'}i:before{color:#ff0}i:after{color:#0f0}u:before{content:'o ';color:#66f}u:after{content:'W';color:blue}s{text-decoration:none}s:before{content:'o';color:#006}s:after{content:'r';color:#60f}p{display:inline}p:before{content:'l';color:#8b00ff}p:after{content:'d'}</style><b></b><i></i><u></u><s></s><p></p>

None of the styling is done with the markup.



242 more procedural way:

require 'paint'

s = "HelloWorld"
out = ""
].each_with_index { |c, i| out << "#{Paint[s[i], c.dup]}" }
puts out

If i manage to think of a better way to generate the colours i will. A few of the middle ones i just did some trial and error for getting the colours close.


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.