Your challenge is to take input as a line of text and output it like this.
Input / output
The input will be a string that contains only printable ASCII characters. The first or last characters will never be spaces, and there will never be two spaces in a row. It will always be at least two characters long.
Your output should be the same string, converted to rainbow colors as will be described below. The output may be in image form (saved to a file or somehow otherwise made available), or it may simply display the result on the screen (as the reference implementation below does).
Conversion
To determine what color each letter in the string should become, use the following algorithm. Note that each letter is its own individual color. This is not a gradient!
If this character is a space:
- ... it doesn't matter, because spaces can't really... have a color anyway. Simply output a space.
Otherwise:
Let
i
= the index of this character in the string (0-based, so for the very first letter, this is0
), not counting spaces. For example, in the stringfoo bar
, this value would be4
for thea
. In other words, this is how many non-spaces have been encountered so far.Let
n
= the number of non-spaces in the string.The color of this letter can now be expressed, in the HSL cylindrical-coordinate system, as [hue=(
i
/n
)*360°, saturation=100%, lightness=50%].
Note that these directions imply that the output for foo
and f oo
should be exactly the same, except for an added space after the f
. That is, all the letters should retain the same colors.
Further rules for the conversion process are described below, in the Rules section.
Reference implementation
This is written in JavaScript, and you can try it by pressing the "Run code snippet" button.
window.addEventListener('load', function() {
addRainbow('Your challenge is to take input as a line of text and ' +
'output it like this.');
});
// append this text rainbow-ified to the argument (document.body by default)
function addRainbow(text, el) {
(el || document.body).appendChild(makeRainbow(text));
}
// returns a <div> that contains the text in a rainbow font
function makeRainbow(text) {
var div = document.createElement('div');
var letterCount = text.replace(/ /g, '').length, spaceCount = 0;
text.split('').forEach(function(letter, idx) {
if (letter == ' ') ++spaceCount;
div.appendChild(makeLetter(letter, (idx - spaceCount) / letterCount));
});
return div;
}
// returns a <span> that contains the letter in the specified color
function makeLetter(letter, hue) {
hue = Math.floor(hue * 360);
var span = document.createElement('span');
span.appendChild(document.createTextNode(letter));
span.style.color = 'hsl(' + hue + ', 100%, 50%)';
return span;
}
Rules
When computing the Hue value of a letter, you will almost certainly get a decimal (non-integer) number. You may round this to the nearest integer, floor it, take the ceiling, or simply not round at all.
The font size must be readable. Here, this is defined as a 10pt size font or greater.
You may use a fixed-width canvas or "drawing area" to output the text, but it must be able to fit the example given in the very first sentence of this post.
Scoring is code-golf, so the shortest code in bytes will win.