# Draw the rainbow

The challenge is simple: Draw a rainbow in as few bytes as possible

The specs for the rainbow are as follows:

• The figure must be exactly 400 pixels wide and 200 pixels high (optionally 401x201 if you want a single center pixel)
• The red ring should touch all borders of the figure (outer radius = 200 pixels)
• All rings shall have the same width (10 pixels)
• The violet ring shall have an inner radius of 130 pixels
• The bow should be the upper half of a perfect circle
• The background shall be white (transparent is also accepted)
• The figure shall not have borders, (exception is made if the border can't be suppressed)
• Builtin rainbow making functions are not allowed!

The following colors are to be used in the rainbow:

This is code golf, so the shortest code in bytes win!

Example:

Related, but different!

• Builtin rainbow making functions are not allowed As I'm sure Mathematica has one Mar 11, 2016 at 23:05
• How imperfect may the rainbow be? From not anti-aliased to tearing? Consider the images in this answer Mar 15, 2016 at 15:53
• @aross: it should look like the sample rainbow (some pixels may vary due to inaccurate calculations). The two last rainbows are too "messy", while the first one looks ok. I don't have a perfect rule, so use you best judgement :-) Mar 15, 2016 at 16:12
• @StewieGriffin Reason I'm asking is because apparently PHP graphics is pretty buggy, while the solution is correct in theory. Well, the second one is, the third one would be with anti-aliasing (which also doesn't work well) Mar 15, 2016 at 16:16
• Are vector graphics not allowed? edit: never mind—I see that there's already a TikZ answer, so I gather they are. Apr 23, 2017 at 16:52

# Piet, 838 codels, several thousand pixels

If you save this image you can try it online!

The actual Piet program is only the top ~125 pixels, which I created using a Python program I wrote.

Editing this afterwards really hurt my vision, I'll be tripping for days!

This outputs the image in an SVG format, because SVG really is (in my opinion) the simplest way to do this. I shamelessly stole Doorknob's SVG code. Outputs:

well, this really:

<svg viewBox='0 0 400 200'><circle cx='200' cy='200' r='200' fill='red'/><circle cx='200' cy='200' r='190' fill='#ff7f00'/><circle cx='200' cy='200' r='180' fill='yellow'/><circle cx='200' cy='200' r='170' fill='lime'/><circle cx='200' cy='200' r='160' fill='blue'/><circle cx='200' cy='200' r='150' fill='indigo'/><circle cx='200' cy='200' r='140' fill='#8f00ff'/><circle cx='200' cy='200' r='130' fill='white'/></svg>

Good luck beating this answer, non-Esolang users!

• Is this python script public? I'm asking for a friend, who is very lazy....
– NaCl
Mar 13, 2016 at 22:45
• Erm, it takes literally ~2 minutes to implement xD You can find an old version here and adjust it if necessary: mediafire.com/download/0isocsb81n7r2cv/piet.py (note: I made this when I was 10, the code is embarrassing to say the least) - it needs PyPNG installed. Mar 14, 2016 at 18:05

# MATL, 10795928784 83 bytes

-200:200 0:200!PYyq10/k12-t8<*t0>*Q7B.561FTh.295Oh.51h4BPFTF6Bl.5hOh4B8$v255*k5M/YG This works in current release (14.0.0) of the language/compiler. EDIT (July 6, 2017): You can try it at MATL Online!. To check that the colors are correct, remove the last five characters (you need to wait for a few seconds and scroll down to the end of the output). ### Explanation The code has three main steps: Step 1: Generate a 201x401 matrix with numbers from 1 to 8. Pixels with value 1 are background (white), pixels with values 2, ..., 8 represent each band of the rainbow. Horizontal coordinates range from -200 to 200 left to right, and vertical coordinates range from 0 to 200 bottom to top. So the origin (0,0) is bottom center, the upper left corner is (-200,200), etc. The different bands of the rainbow are generated by computing the distance from each pixel to the origin and quantizing in steps of 10 pixels. Step 2: Generate an 8x3 matrix defining the colormap. Each row is one of the necessary colors (white and the seven colors of the rainbow). Each value of the previous 201x401 matrix will be interpreted as an index to a row of this colormap. We generate the colormap matrix using values between 0 and 1 for each color component, and then multiplying by 255 and rounding down. This way most values are initially 0 and 1, which will later become 0 and 255. Intermediate values are coded as values between 0 and 1 with 2 or 3 decimals, chosen so that when multiplied and rounded give the exact desired value. Step 3: Display the image with that colormap. % STEP 1: CREATE MATRIX DEFINING THE RAINBOW BANDS -200:200 % row vector [-200, -199, ..., 200] 0:200 % row vector [0, 1, ..., 200] !P % transpose and flip: convert into column vector [200; 199; ...; 0] Yy % hypotenuse function with broadcast: distance from each point to (0,0) q10/k % subtract 1, divide by 10, floor (round down). Gives 20 circular bands % 10 pixels wide, with values from 0 to 19 12- % subtract 12 t8<* % values larger than 7 are set to 0 t0>* % values less than 0 are set to 0. We now have 7 bands with values % 1, ..., 7, and the white background with value 0 Q % add 1: white becomes 1, bands become 2, ..., 8 % STEP 2: CREATE MATRIX DEFINING THE COLORMAP 7B % first row: [1 1 1] (7 converted to binary: color white) .561FTh % second row (light purple) .295Oh.51h % third row (dark purple) 4BP % fourth row: [0 0 1] (4 converted to binary and flipped: blue) FTF % fifth row (green) 6B % sixth row: [1 1 0] (6 converted to binary: yellow) l.5hOh % seventh row: orange 4B % eigth row: [1 0 0] (4 converted to binary: red) 8$v            % vertically concatenate the 8 eight rows
255*k          % multiply by 255 and round down. Gives exact color values
5M/            % push 255 again and divide. This is needed because colors in MATL are
% defined between 0 and 1, not between 0 and 255

% STEP 3: DISPLAY
YG             % display image with that colormap

# Minecraft 1.10 (almost), 2677 characters one-command, 868 blytes

Well I sure picked a verbose language.

summon FallingSand ~ ~1 ~ {Block:log,Time:1,Passengers:[{id:FallingSand,Block:redstone_block,Time:1,Passengers:[{id:FallingSand,Block:activator_rail,Time:1,Passengers:[{id:MinecartCommandBlock,Command:"summon ArmorStand ~ ~ ~ {Tags:[\"b\"]}"},{id:MinecartCommandBlock,Command:"summon Pig ~ ~ ~ {NoAI:1b}"},{id:MinecartCommandBlock,Command:setblock ~-1 ~-2 ~6 chain_command_block 3 replace {auto:1,Command:"execute @e[tag=b] ~ ~ ~ execute @e[rm=200] ~ ~ ~ tp @e[c=1] ~ -99 ~"}},{id:MinecartCommandBlock,Command:setblock ~-1 ~-2 ~5 chain_command_block 3 replace {auto:1,Command:"execute @e[tag=b] ~ ~ ~ execute @e[rm=190,r=200] ~ ~ ~ setblock ~ ~ ~ wool 14"}},{id:MinecartCommandBlock,Command:setblock ~-1 ~-2 ~4 chain_command_block 3 replace {auto:1,Command:"execute @e[tag=b] ~ ~ ~ execute @e[rm=180,r=190] ~ ~ ~ setblock ~ ~ ~ wool 1"}},{id:MinecartCommandBlock,Command:setblock ~ ~-2 ~4 chain_command_block 4 replace {auto:1,Command:"execute @e[tag=b] ~ ~ ~ execute @e[rm=170,r=180] ~ ~ ~ setblock ~ ~ ~ wool 4"}},{id:MinecartCommandBlock,Command:setblock ~ ~-2 ~5 chain_command_block 2 replace {auto:1,Command:"execute @e[tag=b] ~ ~ ~ execute @e[rm=160,r=170] ~ ~ ~ setblock ~ ~ ~ wool 13"}},{id:MinecartCommandBlock,Command:setblock ~ ~-2 ~6 chain_command_block 2 replace {auto:1,Command:"execute @e[tag=b] ~ ~ ~ execute @e[rm=150,r=160] ~ ~ ~ setblock ~ ~ ~ wool 11"}},{id:MinecartCommandBlock,Command:setblock ~ ~-2 ~7 chain_command_block 2 replace {auto:1,Command:"execute @e[tag=b] ~ ~ ~ execute @e[rm=140,r=150] ~ ~ ~ setblock ~ ~ ~ wool 10"}},{id:MinecartCommandBlock,Command:setblock ~ ~-2 ~8 chain_command_block 2 replace {auto:1,Command:"execute @e[tag=b] ~ ~ ~ execute @e[rm=130,r=140] ~ ~ ~ setblock ~ ~ ~ wool 2"}},{id:MinecartCommandBlock,Command:setblock ~1 ~-2 ~8 chain_command_block 4 replace {auto:1,Command:"tp @e[type=Cow] ~1 ~ ~"}},{id:MinecartCommandBlock,Command:setblock ~1 ~-2 ~7 chain_command_block 3 replace {auto:1,Command:"tp @e[type=Bat] ~-1 ~ ~"}},{id:MinecartCommandBlock,Command:setblock ~1 ~-2 ~6 chain_command_block 3 replace {auto:1,Command:"execute @e[type=Pig] ~ ~ ~ summon Bat ~ ~ ~ {NoAI:1b}"}},{id:MinecartCommandBlock,Command:setblock ~1 ~-2 ~5 chain_command_block 3 replace {auto:1,Command:"execute @e[type=Pig] ~ ~ ~ summon Cow ~ ~ ~ {NoAI:1b}"}},{id:MinecartCommandBlock,Command:setblock ~1 ~-2 ~4 repeating_command_block 3 replace {auto:1,Command:"tp @e[type=Pig] ~ ~1 ~"}},{id:MinecartCommandBlock,Command:setblock ~ ~ ~1 command_block 0 replace {Command:fill ~ ~-3 ~-1 ~ ~ ~ air}},{id:MinecartCommandBlock,Command:setblock ~ ~-1 ~1 redstone_block},{id:MinecartCommandBlock,Command:kill @e[type=MinecartCommandBlock,r=1]}]}]}]}

Make a new Superflat world, paste that mess into an Impulse command block, set your render distance fairly high, and run it. Break the armor stand when your computer stops lagging.

The result is 400 blocks across and 200 blocks tall, as requested.

I used MrGarretto's one command generator to pack everything together, and then modified the result of that a little bit to save a couple more bytes. Here's the input to it:

INIT:summon ArmorStand ~ ~ ~ {Tags:["b"]}
INIT:summon Pig ~ ~ ~ {NoAI:1b}
tp @e[type=Pig] ~ ~1 ~
execute @e[type=Pig] ~ ~ ~ summon Cow ~ ~ ~ {NoAI:1b}
execute @e[type=Pig] ~ ~ ~ summon Bat ~ ~ ~ {NoAI:1b}
tp @e[type=Bat] ~-1 ~ ~
tp @e[type=Cow] ~1 ~ ~
execute @e[tag=b] ~ ~ ~ execute @e[rm=130,r=140] ~ ~ ~ setblock ~ ~ ~ wool 2
execute @e[tag=b] ~ ~ ~ execute @e[rm=140,r=150] ~ ~ ~ setblock ~ ~ ~ wool 10
execute @e[tag=b] ~ ~ ~ execute @e[rm=150,r=160] ~ ~ ~ setblock ~ ~ ~ wool 11
execute @e[tag=b] ~ ~ ~ execute @e[rm=160,r=170] ~ ~ ~ setblock ~ ~ ~ wool 13
execute @e[tag=b] ~ ~ ~ execute @e[rm=170,r=180] ~ ~ ~ setblock ~ ~ ~ wool 4
execute @e[tag=b] ~ ~ ~ execute @e[rm=180,r=190] ~ ~ ~ setblock ~ ~ ~ wool 1
execute @e[tag=b] ~ ~ ~ execute @e[rm=190,r=200] ~ ~ ~ setblock ~ ~ ~ wool 14
execute @e[tag=b] ~ ~ ~ execute @e[rm=200] ~ ~ ~ tp @e[c=1] ~ -99 ~

That's a total of 15 1.9+ command blocks, and 838 bytes, so 15*2 + 838 = 868 blytes.

Here's the (almost) part, it's missing a corner and edge. It logically shouldn't - Minecraft bug? Would be exactly 400x200 blocks if it wasn't for that. Not much I can do.

• Yay, a pig based rainbow generator ! +1 Jun 19, 2016 at 14:17
• If it's 2677 characters how can it be only 868 "blytes"? From how I understand that page the actual blytes should be 2677 + 4 Jan 9, 2018 at 7:56
• It's 868 if you build it in the world, 2677 if you use fallingsand to create it (which has a lot of overhead)
– quat
Jan 9, 2018 at 16:38

## Pyth, 150149 128 bytes

"<svg viewBox=0,0,400,200>"V8s["<circle cx=200 cy=200 r="-200*TN" fill="@c"red #ff7f00 #ff0 #0f0 #00f indigo #8f00ff #fff"dN" />

Outputs in SVG:

<svg viewBox=0,0,400,200>
<circle cx=200 cy=200 r=200 fill=red />
<circle cx=200 cy=200 r=190 fill=#ff7f00 />
<circle cx=200 cy=200 r=180 fill=#ff0 />
<circle cx=200 cy=200 r=170 fill=#0f0 />
<circle cx=200 cy=200 r=160 fill=#00f />
<circle cx=200 cy=200 r=150 fill=indigo />
<circle cx=200 cy=200 r=140 fill=#8f00ff />
<circle cx=200 cy=200 r=130 fill=#fff />

Thanks to @MamaFunRoll for 16 bytes and @PatrickRoberts for 6 more!

• You could probably save a lot of bytes by packing the strings. Mar 11, 2016 at 23:31
• @AquaTart All that does is add bytes. O_o Mar 12, 2016 at 0:20
• I don't think you need any of the quotes, ending slashes, or the last ending </svg> tag. Mar 12, 2016 at 2:57
• Two suggestions: red #ff7f00 #ff0 #0f0 #00f #8f00ff #fff for the color list and take single quotes off all parameter values that don't have spaces in them (cx, cy, r and fill) but make sure to leave a space between the value of fill and the / so the color doesn't get misinterpreted. Also remove the </svg> as suggested above. Mar 12, 2016 at 9:25
• Sorry, I meant red #ff7f00 #ff0 #0f0 #00f indigo #8f00ff #fff. Also if you replace the spaces with commas in the viewBox you can remove the single quotes for that parameter as well. Mar 12, 2016 at 10:46

# Mathematica 152144 126 bytes

Graphics@MapIndexed[{#,Disk[{0,0},4-#/5&@@#2,{Pi,0}]}&,RGBColor/@TextWords@"#f00 #ff7f00 #ff0 #0f0 #00f #4b0082 #8f00ff #fff"]

Thanks @CatsAreFluffy for shaving off 8 bytes & @njpipeorgan for a further 18 :)

• Use # vs #[[1]], #2 vs #[[2]], and @@@ vs /@. Mar 13, 2016 at 0:01
• Also, Thread works instead of Transpose. Mar 14, 2016 at 0:51
• Graphics@MapIndexed[{#,Disk[{0,0},4-#/5&@@#2,{Pi,0}]}&,RGBColor/@TextWords@"#f00 #ff7f00 #ff0 #0f0 #00f #4b0082 #8f00ff #fff"] saves another 18 bytes, but the idea is the same. Mar 14, 2016 at 2:39
• Just curious... is there a "rainbow builtin"? Mar 14, 2016 at 17:41
• @mbomb007 not that i'm aware of! Mar 15, 2016 at 11:46

## vim, 165142 139

i<svg viewBox=0,0,400,200><cr><circle cx=2<C-n> cy=2<C-n> r=2<C-n> fill=red<cr>#ff7f00<cr>#ff0<cr>#0f0<cr>#00f<cr>indigo<cr>#8f00ff<cr>#fff<esc>2Gqq0y4f=jPBB10<C-x>@qq@qV2G:norm A /><cr>

Yeesh, this is clunky. There's got to be improvements that can be made.

Outputs as SVG, like my Pyth answer.

Thanks to @MyHamDJ for shaving off 3 bytes!

• You could shave off 2 bytes (or keystrokes) if you replace your last ex command with kv3G:norm A'/><cr> Mar 12, 2016 at 1:12
• You could also take 3 more off if you enter the <circle cx... string on line 2 the first time through, rather then typing all of the colors then entering it afterwards. Mar 12, 2016 at 1:17

# HTML+SVG+ES6, 169

<svg width=400 viewBox=0,0,40,20 onload="this.innerHTML=f00
ff7f00
ff0
0f0
00f
4b0082
8f00ff
fff.replace(/.+/g,c=><circle cx=20 cy=20 r=${--r} fill=#${c} />,r=21)"/>

• use height=200 and cx=200 cy=200 r=${--r}0 instead of viewBox='0 0 40 20'. That should save 7 bytes. Mar 12, 2016 at 11:48 • I hope it's okay that I borrowed your idea with the .replace method... Mar 12, 2016 at 12:08 • @PatrickRoberts of course it's ok, I borrowed some of yours Mar 12, 2016 at 19:05 • I surely didn't expect to see r-=1 in code golf... – Neil Mar 12, 2016 at 20:26 • @Neil bah! it was -=10 in some iteration before the final release Mar 12, 2016 at 22:07 # JavaScript (ES6), 171 158 bytes document.write<svg width=400 height=200>${f00
ff7f00
ff0
0f0
00f
4b0082
8f00ff
fff.replace(/.+/g,c=><circle cx=200 cy=200 r=${i--}0 fill=#${c} />,i=20)}

Credit to @edc65 for the idea to convert

[...].map((c,i)=>...)

to

....replace(/.+/g,c=>...,i=20)

It may look longer but the amount of bytes saved in compressing the array to a string is well worth the conversion. (It saves 13 bytes in this case)

Sample output:

# Processing, 196186181179169 163 bytes

int d=400,i=0;size(d,d/2);background(-1);int[]c={-65536,-33024,-256,#00ff00,#0000ff,#4b0082,#8f00ff,-1};for(noStroke();i<8;ellipse(200,200,d,d),d-=20)fill(c[i++]);

Saved 10 bytes thanks to Kritixi Lithos
... and another 6 bytes thanks to dzaima

• Can shave off one more byte by changing for(int i=0;i<8;i++) into for(int i=0;i++<8;) or similar
– quat
Jun 21, 2016 at 21:14
• I don't think you can use variables while calling size() Dec 4, 2016 at 18:36
• @KritixiLithos What do you mean? Dec 4, 2016 at 21:56
• When I call size with variables as parameters, it gives me an error (before running) that I cannot use variables to set the dimensions on the screen Dec 5, 2016 at 6:53
• background(-1) is one byte shorter than background(255), and you can change the 255 in array c to -1 to save another byte Apr 23, 2017 at 15:38

# Excel VBA, 213 202 196 192 172 Bytes

### Code

Anonymous VBE immediate window function that takes no input and outputs a rainbow, as a vector image, to the sheets(1) object

### Subroutine Version

Sub a
For i=0To 7
j=400-20*i
s.Fill.ForeColor.RGB=Array(255,32767,65535,65280,-31*4^8,8519755,&HE1008F,-1)(i)
s.Line.Visible=0
Next
End Sub

-11 bytes for removing .Adjustments(3)=3/80 call and adding a 8th, white arc

-6 bytes for using -1 over &HFFFFFF

-3 bytes for using Sheet1 over Sheets(1)

-6 bytes for converting with statement to set statement

-14 bytes for converting from Sub to anonymous VBE function

### Output

• Ok, this is the most insane thing I've seen done on Excel of all places. Aug 23, 2020 at 15:53
• @Razetime Check out this one Aug 24, 2020 at 16:14

# R, 184 170 bytes

Making an image with fixed pixel dimensions turns out to be surprisingly tricky with R, whose plotting functions are mostly intended for statisticians. In particular R leaves extra space for labels and coordinate axes unless you explicitly set margins as zero-width by calling par.

On the other hand some of the required colours (specifically red, yellow and blue) are found in the default palette, and can be referenced simply by integer indices.

png(,400,200)
par(mar=0*1:4)
plot(as.raster(outer(199:0,-199.5:200,function(y,x)c(rep("white",13),"#8F00FF","#4B0082",4,"green",7,"#FF7F00",2)[1+(x^2+y^2)^.5%%200/10])))

# Forth Salon Haiku (184 bytes)

I can't satisfy the dimension constraints with this format, but I thought it worth sharing anyway.

: ^ 2 ** ;
: b 0.9 * dup x .5 - ^ y 2.01 / ^
+ sqrt dup rot > swap rot .045
+ < * * + ;
0 .56 .2 b .29 .25 b 1 .4 b
1 .45 b 1 .5 b 0 1 .35 b 1 .4 b
0.5 .45 b 0 1 .2 b .51 .25 b
1 .3 b

# DIV Games Studio (184 bytes)

Not the shortest but quite simple. Uses the DIV default palette

PROGRAM r;
local
c[]=22,26,235,41,54,82,249,15,15;
BEGIN
set_mode(400200);
for(x=-80;x<80;x+=10)
y=399-x;
draw(5,c[abs(x)/10],15,0,x,x,y,y);
x+=70*(x<0);END
LOOP;FRAME;END
END

## Explanation

Define program start (named "r" to save space)

PROGRAM r;

setup palette lookup

local
c[]=22,26,235,41,54,82,249,15,15;

BEGIN program code

BEGIN

Set video mode to 400,200

set_mode(400200);

loop x (predefined variable) from -80 (which bg hack) to 80 ( 7 colours + white centre)

for(x=-80;x<80;x+=10)

define elipse constraints

y=399-x;

draw elipse - on the first iteration this draws a circle larger than the screen in full white (index -8)

draw(type (5=filled elipse), colour, opacity, x0,y0,x1,y1)

draw(5,c[abs(x)/10],15,0,x,x,y,y);

once first is done, bump x up to zero to start drawing red band

x+=70*(x<0);

end for loop

END

infinite loop, drawing screen.

LOOP;FRAME;END

end (matches BEGIN at top of program)

END

## Perl, 175 + 1 = 176 bytes

perl -MSVG -E '$z=SVG->new(width=>4e2,height=>2e2);@x=qw/#fff #8f00ff indigo #00f #0f0 #ff0 #ff7f00 red/;$z->circle(cx=>200,cy=>200,r=>200-10*$a++,style=>{fill=>pop@x})for 1..8;say$z->xmlify'

# PHP, 190 bytes

imagefill($a=imagecreatetruecolor($r=400,200),0,0,$w=0xffffff);foreach([255<<16,0xff7f00,$w-255,65280,255,4915330,9371903,$w]as$i)imagefilledellipse($a,200,200,$r,20+$r-=20,$i);imagepng($a); Run it like this: php -r 'imagefill($a=imagecreatetruecolor($r=400,200),0,0,$w=0xffffff);foreach([255<<16,0xff7f00,$w-255,65280,255,4915330,9371903,$w]as$i)imagefilledellipse($a,200,200,$r,20+$r-=20,$i);imagepng($a);' | display

Also working in theory at 179 bytes (but the image looks a tad messed up, bad GD):

php -r '$r=410;imagesetthickness($a=imagecreatetruecolor(400,200),10);foreach([255<<16,0xff7f00,0xffff00,65280,255,4915330,9371903]as$i)imagearc($a,200,200,$r-=20,$r,1,0,$i);imagepng($a);' | display

Also not a perfect image, but much better than the above (and @166 bytes):

php -d error_reporting=30709 -r '$a=imagecreatetruecolor($r=400,200);foreach([255<<16,0xff7f00,0xffff00,65280,255,4915330,9371903]as$i)for(;++$$i<21;)imageellipse($a,200,200,$r,$r--,$i);imagepng($a);' | display