创建彩虹文字


22

您的挑战是将输入作为一行文本并以这种方式输出。

彩虹图像

输入输出

输入将是仅包含可打印ASCII字符的字符串。第一个或最后一个字符永远不会是空格,并且行中永远不会有两个空格。它总是至少两个字符长。

您的输出应为相同的字符串,转换为彩虹色,如下所述。输出可以是图像形式(保存到文件或以其他方式可用),也可以仅在屏幕上显示结果(如下面的参考实现所示)。

转换次数

要确定字符串中的每个字母应变成哪种颜色,请使用以下算法。请注意,每个字母都是其自己的单独颜色这不是渐变!

  • 如果此字符是空格:

    • ...没关系,因为空格无法真正...仍然具有颜色。只需输出一个空格。
  • 除此以外:

    • i=该字符在字符串中的索引(从0开始,因此对于第一个字母为0),不计算空格。例如,在字符串中foo bar,此值将4用于a。换句话说,这就是到目前为止已经遇到了多少个非空格。

    • n=字符串中非空格的数量。

    • 现在可以在HSL圆柱坐标系中将该字母的颜色表示为[hue =(i/ n)* 360°,饱和度= 100%,亮度= 50%]。

请注意,这些方向意味着输出foof oo应该是完全一样的,除了后的增值空间f。也就是说,所有字母应保留相同的颜色。

下文的“规则”部分中介绍了转换过程的其他规则

参考实施

这是用JavaScript编写的,您可以通过按“运行代码段”按钮进行尝试。

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

规则

  • 计算字母的Hue值时,几乎可以肯定会得到一个十进制(非整数)数字。您可以将其四舍五入为最接近的整数,对其进行下限,采用上限或根本不进行四舍五入。

  • 字体大小必须可读。在此,将其定义为10pt或更大的字体。

  • 您可以使用固定宽度的画布或“绘图区域”来输出文本,但是它必须能够适合本文第一句中给出的示例。

  • 得分是,因此以字节为单位的最短代码将获胜。


输出可以是数据URI吗?这就是HTML画布的输出
Downgoat 2015年

@vihan是的,符合“ 输出可能是图像形式(保存到文件或以其他方式提供) ”规则的资格。
门把手

您如何确定颜色是否符合规格?如果一种语言仅支持RGB颜色,您能否精确指定应使用哪种转换公式?另外,每个通道需要多少位精度?大概8可以,但是4或1呢?
feersum

@feersum要转换为RGB,可以使用内置方法或此处描述的方法之一。您能否澄清第二个问题的意思?您是在从HSL到RGB的转换中还是在一般情况下询问此问题?
门把手

2
Dang,我什至不打算尝试使用PowerShell ...您只能使用16种颜色(并且甚至没有排序... Rainbow或RGB或其他...只是任意十六进制值)。参考,附带图片 真的很酷的挑战!
AdmBorkBork 2015年

Answers:


12

Perl,95岁

92字节代码+ 3个 -p

该脚本使用的是终端可用颜色的近似值(最多256个),当前仅包括从此列表中选择的几个色点,因此它可能没有指定规格,但这还是很有趣的!我过滤列表仅显示颜色SL100%50%分别,然后通过色调进行排序,打包的数字转换成字符串,然后从列表中选择颜色。

此实现包括不可打印的字符!偷了@ edc65的想法,只是代替\S而不是.,简单但聪明!

@c=map ord,"..........vR../012.3-'!..9]........"=~/./g;s|\S|\e[38;5;$c[@c*$i++/y/!-~//]m$&|g

十六进制转储:

0000000: 4063 3d6d 6170 206f 7264 2c22 09c4 cad0  @c=map ord,"....
0000010: d6dc 0be2 be9a 7652 0a2e 2f30 3132 0e33  ......vR../012.3
0000020: 2d27 211b 1539 5d81 a50d c9c8 c7c6 c522  -'!..9]........"
0000030: 3d7e 2f2e 2f67 3b73 7c5c 537c 5c65 5b33  =~/./g;s|\S|\e[3
0000040: 383b 353b 2463 5b40 632a 2469 2b2b 2f79  8;5;$c[@c*$i++/y
0000050: 2f21 2d7e 2f2f 5d6d 2426 7c67            /!-~//]m$&|g

通过复制以上文本并运行来反转十六进制转储:

xxd -r > rainbowtext.pl

粘贴数据并按Ctrl+ D

运行使用:

perl -p rainbowtext.pl <<< 'Your challenge is to take input as a line of text and output it like this.'

它产生如下输出:

现在您的终端文字是红色的! 穆哈哈哈哈!


10

Python 2:240使用PIL和colorsys库

import PIL,colorsys as c
s=input()
u,a=len(s),255
g=Image.new('RGB',(u*6,13),(a,)*3)
[ImageDraw.Draw(g).text((j*6,0),s[j],fill=tuple(int(h*a)for h in c.hls_to_rgb(1.*(j-s[:j].count(' '))/(u-s.count(' ')),.5,1)))for j in range(u)]
g.show()

输出示例:

输出彩虹文本示例 用空格测试

感谢@agtoever和@Trang Oul提供了一些高尔夫技巧,并感谢@Mauris指出了空间要求。

要添加真字体,字体大小控制包括水平偏移和基于长度的颜色更改。

import PIL as P,colorsys as c
s=input()
u=len(s)
a=255
fs=25
f=P.ImageFont.truetype("a.ttf",fs)
sza=f.getsize(s)
oa=f.getoffset(s)
g=P.Image.new('RGB',(sza[0]+fs,2*sza[1]+oa[1]),(a,)*3)
r=fs/4
P.ImageDraw.Draw(g).text((r,0),s,fill=(0,0,0),font=f)
for j in range(u):   
 o=f.getoffset(s[j])
 sz=f.getsize(s[j])   
 r+=o[0]
 P.ImageDraw.Draw(g).text((r,0+fs),s[j],fill=tuple([int(h*a)for h in c.hls_to_rgb(1.*r/sza[0],.5,1)]),font=f)
 r+=sz[0]
g.save('a.png')
g.show()

我使用的字体可以从这里获得:结果是(最上面是打印字符串,下面是每个字母打印):

打字机


1
掉落as P并写出PIL两次赢得一个字符。更改imgi,再赢得4个角色。
agtoever

1
保存255为变量,替换所有重复出现并(a,)*3用作白色。替换float(j)(j+.0)
Trang Oul 2015年

1
另外:替换float(j)1.*j
agtoever 2015年

1
同时分配多个变量(例如u=len(s) a=255=> u,a=len(s),255)。[]从中删除括号tuple,不需要它们。用列表理解替换循环(方法将被评估为副作用)。
董里(Trang Oul)

1
@willem:看一下问题规范(在Conversion之下);它专门说明了程序应如何处理空格。
林恩

5

的JavaScript(ES6),114 117 125

Edit2保存了3个字节,@ Dom Hastings 编辑了无效的HTML,但是仍然可以工作。

通常的注意事项:测试在符合EcmaScript 6的浏览器上运行代码段(特别是不是Chrome而不是MSIE。我在Firefox上进行了测试)

F=s=>document.write(s.replace(/\S/g,c=>`<b style=color:hsl(${i++/s.replace(/ /g,'').length*360},100%,50%>`+c,i=0))
<input value='Your challenge is to take input as a line of text and output it like this.' id=I size=100>
<button onclick='F(I.value)'>-></button>


1
尚无浏览器完全符合ES6。IE甚至还不完全符合ES5!
SuperJedi224 2015年

@ SuperJedi224我同意。我只是说:不要在Chrome或MSIE上尝试使用它,而在使用Firefox时可以使用它
edc65

我觉得我什至不愿说什么,因为我只是在您的权限之下,但是我认为您可以省略声明)后的内容,hsl(因为它似乎在Firefox中对我仍然有效!
唐·黑斯廷斯

此外,您可以更改${c}''+c节省2个以上...最好继续与我联系!
Dom Hastings

这不适用于Safari 9.0。c:
Addison Crump 2015年

4

Python 3,131个字节

与Dom Hastings的答案类似,但以python实现。

该字符串'|\x82\x88\x8ejF"#$%\x1f\x19\x137[\x7f~}'是从列表中构建的,[124,130,136,142,106,70,34,35,36,37,31,25,19,55,91,127,126,125]是按顺序显示的终端颜色代码。它们已经过过滤,因此它们仅包含饱和度为100%且值为50%的颜色。然后对列表进行排序,以便首先显示正确的色相。

从stdin获取输入并将其返回到stdout。

您正在使用的终端必须支持ANSI转义码才能正常运行。

x=input();u=u'|\82\88\8ejF"#$%\1f\19\137[\7f~}';j=0
for i in x:print('\033[38;5;%dm%s'%(ord(u[j*18//len(x.replace(" ", ""))]),i),end="");j+=i!=" "

或带有文字字节字符的缩短版本(未正确粘贴):

x=input();u='|<82><88><8E>jF"#$%^_^Y^S7[^?~}';j=0
for i in x:print('ESC[38;5;%dm%s'%(ord(u[(j*18)//len(x.replace(" ", ""))]),i),end="");j+=i!=" "

字面量十六进制转储:

783d696e70757428293b753d277c82888e6a46222324251f1913375b7f7e7d273b6a3d300a666f72206920696e20783a7072696e7428271b5b33383b353b25646d25732725286f726428755b286a2a3138292f2f6c656e28782e7265706c616365282220222c20222229295d292c69292c656e643d2222293b6a2b3d69213d2220220a

感谢@swstephe保存了9个字节(并且还让我注意到我的字节计数确实有点非常错误)!


为什么不将“ \ x82”替换为实际字符?我将该字符串写入文件,然后以二进制形式将其读回到脚本中。您可以将\ 033替换为原始的转义字符,甚至替换为\ 1f(十六进制)。您声明“ u”,然后仅使用一次。您可以通过将其向下移动到表达式中来保存一些字符。您可以通过使用“ //”进行整数除法来避免int()调用。
swstephe

糟糕,\ 033与\ x1f相同。
swstephe

2

PHP,165字节

使用输入作为参数“ s”运行

HTML无效,但应在所有主要浏览器中呈现(已在Chrome和Firefox中测试)

<?php $n=preg_match_all("/[^ ]/",$q=$_GET['s']);for($i=$j=0;$j<strlen($q);$j++){if(" "!=$s=$q[$j])$i+=360;echo"<a style='color:hsl(".floor($i/$n).",100%,50%)'>".$s;}

1

PHP 4.1, 112 103 102字节

我用过 @DankMemes的答案作为起点。从那里,我已经实现了一个的变化,该代码是不同的点。

实现是相似的,代码是完全不同的。

foreach(str_split($s)as$c)echo"<a style=color:hsl(",((" "^$c?$i+=360:$i)/strlen($s))|0,",100%,50%>$c";

要使用它,只需在名称为的SESSION / GET / POST / COOKIE上设置一个值s

在测试语句上运行此功能的结果:

<a style=color:hsl(4,100%,50%>Y<a style=color:hsl(9,100%,50%>o<a style=color:hsl(14,100%,50%>u<a style=color:hsl(19,100%,50%>r<a style=color:hsl(24,100%,50%> <a style=color:hsl(29,100%,50%>c<a style=color:hsl(34,100%,50%>h<a style=color:hsl(38,100%,50%>a<a style=color:hsl(43,100%,50%>l<a style=color:hsl(48,100%,50%>l<a style=color:hsl(53,100%,50%>e<a style=color:hsl(58,100%,50%>n<a style=color:hsl(63,100%,50%>g<a style=color:hsl(68,100%,50%>e<a style=color:hsl(72,100%,50%> <a style=color:hsl(77,100%,50%>i<a style=color:hsl(82,100%,50%>s<a style=color:hsl(87,100%,50%> <a style=color:hsl(92,100%,50%>t<a style=color:hsl(97,100%,50%>o<a style=color:hsl(102,100%,50%> <a style=color:hsl(107,100%,50%>t<a style=color:hsl(111,100%,50%>a<a style=color:hsl(116,100%,50%>k<a style=color:hsl(121,100%,50%>e<a style=color:hsl(126,100%,50%> <a style=color:hsl(131,100%,50%>i<a style=color:hsl(136,100%,50%>n<a style=color:hsl(141,100%,50%>p<a style=color:hsl(145,100%,50%>u<a style=color:hsl(150,100%,50%>t<a style=color:hsl(155,100%,50%> <a style=color:hsl(160,100%,50%>a<a style=color:hsl(165,100%,50%>s<a style=color:hsl(170,100%,50%> <a style=color:hsl(175,100%,50%>a<a style=color:hsl(180,100%,50%> <a style=color:hsl(184,100%,50%>l<a style=color:hsl(189,100%,50%>i<a style=color:hsl(194,100%,50%>n<a style=color:hsl(199,100%,50%>e<a style=color:hsl(204,100%,50%> <a style=color:hsl(209,100%,50%>o<a style=color:hsl(214,100%,50%>f<a style=color:hsl(218,100%,50%> <a style=color:hsl(223,100%,50%>t<a style=color:hsl(228,100%,50%>e<a style=color:hsl(233,100%,50%>x<a style=color:hsl(238,100%,50%>t<a style=color:hsl(243,100%,50%> <a style=color:hsl(248,100%,50%>a<a style=color:hsl(252,100%,50%>n<a style=color:hsl(257,100%,50%>d<a style=color:hsl(262,100%,50%> <a style=color:hsl(267,100%,50%>o<a style=color:hsl(272,100%,50%>u<a style=color:hsl(277,100%,50%>t<a style=color:hsl(282,100%,50%>p<a style=color:hsl(287,100%,50%>u<a style=color:hsl(291,100%,50%>t<a style=color:hsl(296,100%,50%> <a style=color:hsl(301,100%,50%>i<a style=color:hsl(306,100%,50%>t<a style=color:hsl(311,100%,50%> <a style=color:hsl(316,100%,50%>l<a style=color:hsl(321,100%,50%>i<a style=color:hsl(325,100%,50%>k<a style=color:hsl(330,100%,50%>e<a style=color:hsl(335,100%,50%> <a style=color:hsl(340,100%,50%>t<a style=color:hsl(345,100%,50%>h<a style=color:hsl(350,100%,50%>i<a style=color:hsl(355,100%,50%>s<a style=color:hsl(360,100%,50%>. 

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.