レインボーテキストを作成する


22

あなたの課題は、入力をテキスト行として取得し、次のように出力することです。

虹画像

入出力

入力は、印刷可能なASCII文字のみを含む文字列になります。最初または最後の文字がスペースになることはありません。また、2つのスペースが連続することはありません。常に少なくとも2文字の長さになります。

出力は、以下で説明するように、虹色に変換された同じ文字列である必要があります。出力は画像形式(ファイルに保存されるか、何らかの方法で利用可能になったもの)である場合もあれば、単に画面に結果を表示する場合もあります(以下の参照実装のように)。

変換

文字列の各文字が何色になるかを判断するには、次のアルゴリズムを使用します。各文字は、独自の個別の色であることに注意してください。これは勾配ではありません!

  • この文字がスペースの場合:

    • ...スペースは実際にはできないので、それは問題ではありません...とにかく色を持っています。単にスペースを出力します。
  • さもないと:

    • Let i=文字列内のこの文字のインデックス(0から始まるため、最初の文字の場合、これは0)で、スペースはカウントしません。例えば、文字列でfoo bar、この値は次のようになります4ためa。つまり、これは、これまでに検出された非スペースの数です。

    • Let n=文字列内の非スペースの数。

    • この文字の色は、HSL円筒座標系で、[色相=(i/ n)* 360°、彩度= 100%、明度= 50%] として表現できるようになりました。

これらの指示は、の後に追加されたスペースを除き、fooとの出力f 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;
}

ルール

  • 文字の色相値を計算すると、ほぼ確実に10進数(非整数)が取得されます。これを最も近い整数に丸めるか、床に乗せるか、天井を取るか、まったく丸めないことができます。

  • フォントサイズは読み取り可能である必要があります。ここでは、これは10ptサイズ以上のフォントとして定義されています。

  • 固定幅のキャンバスまたは「描画領域」を使用してテキストを出力できますが、この投稿の最初の文に記載されている例に適合する必要あります。

  • スコアリングはであるため、バイト単位の最短コードが優先されます。


出力はデータURIですか?これは、HTMLのキャンバスからの出力だ
Downgoat

@vihanはい、「出力は画像形式(ファイルに保存されるか、何らかの方法で利用可能になる場合があります)」ルールに従って修飾されます
ドアノブ

配色が仕様を満たしているかどうかをどのように判断しますか?言語でRGBカラーのみがサポートされている場合に使用する変換式を正確に指定できますか?また、チャネルごとに何ビットの精度が必要ですか?おそらく8でも構いませんが、4または1はどうでしょうか。
feersum

@feersum RGBに変換するには、ビルトインまたはここで説明する方法のいずれかを使用できます。2番目の質問の意味を明確にできますか?これについて具体的にHSLからRGBへの変換のコンテキストで質問していますか、それとも一般的な質問ですか?
ドアノブ

2
ダン、PowerShellを試してみるつもりはありません... 16色しか使用できません(順序付けられていません...レインボーまたはRGBまたは...任意の16進値)。参照、写真付き しかし、本当にクールな挑戦!
AdmBorkBork

回答:


12

Perl、95

92バイトコード+ 3 -p

このスクリプトは、現在このリストから選択された少数の色点のみを含む端末で使用可能な色の近似値(最大256)を使用しているため、仕様化されない可能性がありますが、とにかく楽しかったです!リストをフィルタリングして、次の色SL値のみを表示しました100%50%それぞれ色相で並べ替え、数字を文字列にパックして、そのリストから色を選択しました。

この実装には、印刷できない文字が含まれています!@ edc65のアイデアを盗んだ、\S代わりに.、単に、代わりに、シンプルだが賢い!

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

Hexdump:

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

上記のテキストをコピーして実行することにより、hexdumpを反転します。

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:PILおよびcolorsys libを使用する240

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に感謝します。

True Typeフォント、水平オフセットを含むフォントサイズコントロール、および長さに基づく色の変更を追加するには。

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してPIL2回書き留め、1人のキャラクターを獲得します。に変更imgしてi、さらに4つのキャラクターを獲得します。
-agtoever

1
255変数に保存し、すべての出現を置き換えて(a,)*3、白色として使用します。置き換えfloat(j)によって(j+.0)
トランオウル

1
また:置き換えるfloat(j)1.*j
agtoever

1
複数の変数を同時に割り当てます(例u=len(s) a=255== u,a=len(s),255)。[]からブラケットを取り外しますtuple。これらは必要ありません。ループをリスト内包で置き換えます(メソッドは副作用として評価されます)。
トランオウル

1
@willem:問題の仕様(Conversionの下)を見てください。プログラムがスペースを処理する方法を具体的に説明します。
リン

5

JavaScript(ES6)、114 117 125

Edit2 3バイトが保存されましたthx @Dom Hastings Edit無効なHTMLをが、とにかく動作します。

通常の注意:EcmaScript 6準拠のブラウザーでスニペットを実行してテストします(特にMSIEではなくChromeです。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

@ SuperJedi224同意します。私はただ言っている:ChromeやMSIEで試してはいけない、Firefoxを使用している間は動作する
-edc65

私はあなたのものの下にいるだけなので、何も言ってはいけない気がしますが、Firefoxでは私にとってはうまくいくように見える)ので、あなたのhsl(宣言の後を省略することができると思います!
ドムヘイスティングス

また、に変更${c}''+cて、さらに2つ保存することもできます。
ドムヘイスティングス

これはSafari 9.0では機能しません。c:
アディソンクランプ

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!=" "

リテラルhexdump:

783d696e70757428293b753d277c82888e6a46222324251f1913375b7f7e7d273b6a3d300a666f72206920696e20783a7072696e7428271b5b33383b353b25646d25732725286f726428755b286a2a3138292f2f6c656e28782e7265706c616365282220222c20222229295d292c69292c656e643d2222293b6a2b3d69213d2220220a

9バイトを保存してくれた@swstepheに感謝します(また、バイトのカウントが非常にわずかに間違っていたことに気付きました)。


「\ x82」を実際の文字に置き換えてみませんか?その文字列をファイルに書き込み、バイナリでスクリプトに読み戻しました。\ 033を生のエスケープ文字、または\ 1f(16進数)に置き換えることもできます。「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%>. 

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.