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

WINNER(s)

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

up vote 6 down vote accepted

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

  • 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. – MrZander Jan 12 '12 at 0:33
  • @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. – stranac Jan 12 '12 at 1:05
  • Took it straight off Wikipedia... I'm no color expert haha. – MrZander Jan 12 '12 at 4:29
  • 2
    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. – hammar Jan 12 '12 at 4:58

Mathematica

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.

Screenshot:

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]

Screenshot

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, 261 chars

C=((255,0,0),(255,127,0),(255,255,0),(0,255,0),(0,0,255),(111,0,255),(143,0,255))
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

  • Hehe, nice. Took me an embarrassingly long moment to understand. – cemper93 Jan 7 '12 at 13:50
  • 2
    n=255;C=((n,0,0),(n,127,0),(n,n,0),(0,n,0),(0,0,n),(111,0,n),(143,0,n)) – Steven Rumbalski Jan 7 '12 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.)

Screenshot:

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:

$_=Hello_World;s/./\e[3${[(0..6)x2]}[pos]m$&/g;say

Screenshot:

Hello_World

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"

Screenshot:

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
    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. – MrZander Jan 5 '12 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.

  • That's more like it ;) – MrZander Jan 5 '12 at 1:31
  • So far, this is the lowest character count that follows all the rules to the dot. – MrZander Jan 7 '12 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
    I suppose "Times" is shorter, but ... ugh. – luser droog Sep 18 '12 at 3:20
  • Stole some of your ideas... – Thomas W. Oct 19 '12 at 23:41

Some different approaches to doing this with

PostScript

First: Shortest one (89):

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

Rendered result http://s14.postimage.org/f66u116ap/rainbow_Hello_World4.png

Un-golfed:

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
dup}for

Rendered result http://s10.postimage.org/yqdlgl4y1/rainbow_Hello_World3.png

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.

Un-golfed:

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
}for

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...

  • Oooo... +1 even with the HTML – MrZander Jan 7 '12 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.

Ruby

242 more procedural way:

require 'paint'

s = "HelloWorld"
out = ""
[
  '#FF0000',
  '#FF7F00',
  '#FFFF00',
  '#00FF00',
  "#00FFFF",
  "#5555FF",
  '#0000FF',
  '#000077',
  '#6600FF',
  '#8B00FF'
].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 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.