AppleSauceフェーダー


11

当時、1337人の子供全員がチャットルームでテキストフェーダーを使用していました。君たちのことは知らないが、彼らのようにクールに感じたい。唯一の問題は、古いスクリプトとアプリケーションが、それらが作成されたソフトウェアと大きく結びついていることです。そのため、この驚くべき機能をどこでも利用することはできません。また、ソリューションを簡単に移植できるようにしたいので、フロッピーディスクに収まるようにコードをできる限り小さくする必要があります(ソースコードが大きすぎる場合は、フロッピーを1枚しか持ちません私は複数を運ぶことができます:P)。

入力

  • 色のリスト(rgb、hex、namesなど)
  • フォーマットするテキスト

プログラムでは、色のリストに少なくとも2色が含まれている必要があります。
フォーマットするテキストの長さはゼロより大きくすることができ、文字は印刷可能なアスキーに制限されます。(ヒント:長いテキスト入力では、連続する文字の中間色を再利用する必要がある場合があります)

出力

出力テキストは、フォントおよび/またはマークアップ/スタイリング以外の点で入力テキストと異なるべきではありません(注:出力にhtmlマークアップが含まれている場合、入力をhtmlエンコードする必要があります)。マークアップ/スタイリング(htmlスタイルタグ、コンソールの色など)を使用してテキストを出力したり、色あせたテキストの画像を出力したりできます。入力にこの要件を満たすのに十分な文字が含まれていない場合を除き、すべてのカラーヘックスが出力に存在する必要があります。この場合、優先ルールを参照して、出力にどの色のヘックスが存在するかを決定してください。出力の順序またはこれらの色は、入力順序のままです。

色優先ルール

  1. 入力が1文字の場合、最初の色が使用されます
  2. 文字が2つしかない場合、最初と最後の色が使用されます
  3. 3色よりも多く、文字よりも多くの色がある場合、最初と最後の色に優先順位を付け、次に残りの色を入力順に並べる必要があります。
  4. 色よりも文字が多い場合、文字は中間色を使用してある色から次の色にフェードする必要があります

例(それぞれ優先規則1〜3):
#色| カラー0 | ... | カラーn | テキスト
3 ff0000 0000ff ffff00 M-> -> ->最初だけ
3 ff0000 0000ff ffff00 hi2番目を無視
4 ff0000 0000ff ffff00 0fff00 sup3日無視

明確にするために、テキストの色は1つの色のヘックスから次のヘックスにフェードする必要があります。フェードは完全に均一である必要はありませんが、きれいにフェードするのに十分なキャラクターがいない限り、急激な色の変化であってはなりません。通常、このフェードは、作業する必要のある文字の数と色の違いによって決まる間隔でrgb値をインクリメント/デクリメントすることにより、各文字の中間色を選択することによって実現されます。たとえば、赤(#ff0000)と黒(#000000)の間の単一の色が必要な場合#800000、真ん中に配置するように選択できます。最適な出力はかなりきれいに見えます。

例(優先度ルール4):
3 ff0000 ff7f00 f0ff00 To be or not to be, that is the question...-> -OR-であるかどうか

<span style="color:#ff0000;">T</span><span style="color:#ff0600;">o</span><span style="color:#ff0c00;"> </span><span style="color:#ff1200;">b</span><span style="color:#ff1800;">e</span><span style="color:#ff1e00;"> </span><span style="color:#ff2400;">o</span><span style="color:#ff2a00;">r</span><span style="color:#ff3000;"> </span><span style="color:#ff3600;">n</span><span style="color:#ff3c00;">o</span><span style="color:#ff4300;">t</span><span style="color:#ff4900;"> </span><span style="color:#ff4f00;">t</span><span style="color:#ff5500;">o</span><span style="color:#ff5b00;"> </span><span style="color:#ff6100;">b</span><span style="color:#ff6700;">e</span><span style="color:#ff6d00;">,</span><span style="color:#ff7300;"> </span><span style="color:#ff7900;">t</span><span style="color:#ff7f00;">h</span><span style="color:#fe8500;">a</span><span style="color:#fe8b00;">t</span><span style="color:#fd9100;"> </span><span style="color:#fc9700;">i</span><span style="color:#fb9d00;">s</span><span style="color:#fba400;"> </span><span style="color:#faaa00;">t</span><span style="color:#f9b000;">h</span><span style="color:#f9b600;">e</span><span style="color:#f8bc00;"> </span><span style="color:#f7c200;">q</span><span style="color:#f6c800;">u</span><span style="color:#f6ce00;">e</span><span style="color:#f5d400;">s</span><span style="color:#f4da00;">t</span><span style="color:#f4e100;">i</span><span style="color:#f3e700;">o</span><span style="color:#f2ed00;">n</span><span style="color:#f1f300;">.</span><span style="color:#f1f900;">.</span><span style="color:#f0ff00;">.</span> 

回答では、出力の表示方法を指定してください(html、コンソール、画像など)。

*すべての黒の背景は色を強調するためのものであり、必須ではありません

得点

これはであるため、最短回答(バイト単位)が優先されます。
あなたが個々のキャラクターにフェードを追加することができれば、私はあなたがクールだと永遠に思います(しかし、これはいくつかの言語では公平ではないため、スコアにボーナスはありません)



@LeakyNun RGBスペースでは十分に近く、他のオプションは#7f0000です。
— ニール

あんまり。この方法で赤と緑を平均化して、黄色になるかどうかを確認してください。正しい方法で行うには、直接平均の代わりに二乗平均を取ります。
— リーキー修道女

平均値000000とff0000する必要がありますb40000(255*sqrt((0+1)/2))
— 漏れ修道女

1
@LeakyNunあなたが色を平均する必要があると言ったことはありません。このような課題に時々使用されるフェードの簡単な方法を説明しました。この場合、2色の赤を平均化(および丸め)しました。また、この課題で、フェードが完全に均一である必要はないことにも注意しました。このフェードの実装方法は、ユーザー次第です。
— ポケ

回答:


3

JavaScript(ES6)、290バイト

h=a=>f(a,a.shift());f=
(a,w)=>[...w].map((c,i)=>{l=w.length-1;m=a.length-1;s=o.appendChild(document.createElement('span'));s.textContent=c;s.style.color=`#${i?i-l?a[r=l%m,n=l/m|0,i<r*n+r?++n:i-=r,k=i/n|0,k++].replace(/./g,(c,d)=>((parseInt(c,16)*(n-i%n)+i%n*parseInt(a[k][d],16))/n|0).toString(16)):a[m]:a[0]}`;})
<textarea rows=10 cols=40 oninput="o.textContent='';h(this.value.split`\n`)">Type the text here and the colours on subsequent lines.
FF0000
00FF00
0000FF</textarea><div id=o>


1
コードスニペットでリアルタイムに発生するのを見るのは本当にクールです。:D
— AdmBorkBork


1

Java、702 662文字

ゴルフの2つの機能:

import java.awt.*;String f(Color C,char c){return"<span style=\"color:#"+Integer.toHexString(C.getRGB()).substring(2)+";\">"+c+"</span>";}String c(String t,String[]h){String r="";int l=h.length,e=t.length(),i=0,s=0,g=1,c=-1,p,q,u;double d,m=0,v;char[]T=t.toCharArray();Color C[]=new Color[l],H[],a,b;for(;i<l;)C[i]=Color.decode(h[i++]);if(l>e){H=java.util.Arrays.copyOfRange(C,0,e);H[e-1]=C[l-1];H[0]=C[0];C=H;l=e;}d=--e/(l-1.);for(;++c<e;){a=C[s];b=C[g];p=b.getRed()-a.getRed();q=b.getGreen()-a.getGreen();u=b.getBlue()-a.getBlue();v=m/d;r+=f(new Color(a.getRGB()+((int)(v*p)<<16|(int)(v*q)<<8|(int)(v*u))),T[c]);if(++m>d){m-=d;s=g++;}}return r+f(C[l-1],T[e]);}

誰もこれを読むことができないので、ここにクラスの両方の機能があります:

import java.awt.*;

public class Q80554 {

    static String format(Color color, char character) {
        return "<span style=\"color:#" + Integer.toHexString(color.getRGB()).substring(2) + ";\">" + character + "</span>";
    }

    static String colorizeB(String text, String[] hexColors) {
        String result = "";
        int colorsLength = hexColors.length, textLength = text.length(), i, currentStartColorPos = 0, currentGoalColorPos = 1, currentCharPos = -1, diffColorRed, diffColorGreen, diffColorBlue;
        double difference, goneDifference = 0, relativeChange;
        char[] textArray = text.toCharArray();
        Color colors[] = new Color[colorsLength], changer[], currentStartColor, currentGoalColor;

        for (i = 0; i < colorsLength;)
            colors[i] = Color.decode(hexColors[i++]);

        if (colorsLength > textLength) {
            changer = Arrays.copyOfRange(colors, 0, textLength);
            changer[textLength - 1] = colors[colorsLength - 1];
            changer[0] = colors[0];

            colors = changer;
            colorsLength = textLength;
        }

        // fade
        difference = --textLength / (colorsLength - 1.); // space between colors    

        for (; ++currentCharPos < textLength;) {
            currentStartColor = colors[currentStartColorPos];
            currentGoalColor = colors[currentGoalColorPos];

            diffColorRed = currentGoalColor.getRed() - currentStartColor.getRed();
            diffColorGreen = currentGoalColor.getGreen() - currentStartColor.getGreen();
            diffColorBlue = currentGoalColor.getBlue() - currentStartColor.getBlue();

            relativeChange = goneDifference / difference;

            result += format(new Color(currentStartColor.getRGB() + ((int) (relativeChange * diffColorRed) << 16 | (int) (relativeChange * diffColorGreen) << 8 | (int) (relativeChange * diffColorBlue))), textArray[currentCharPos]);

            if (++goneDifference > difference) {
                goneDifference -= difference;
                currentStartColorPos = currentGoalColorPos++;                   
            }
        }

        // last character always has last color
        return result + format(colors[colorsLength - 1], textArray[textLength]);
    }
}

ここには、独自のコードの上限があります。使用方法は、colorize(ゴルフバージョンではc)を呼び出して、テキストと16進カラーコードの配列を渡すことです。この関数は、OPのようにHTMLタグを含むStringを返すため、HTMLをレンダリングする何らかの方法が必要です。

アルゴリズムは質問が次のように簡単です。最初の文字は常に最初の色を取得し、最後の文字は常に最後の色を取得します。テキストに文字よりも多くの色がある場合は、テキストと色を繰り返して適用します。楽しい部分はフェードのある部分です。テキストの色がどの距離にあるかを調べることから始めました。基本的に、2つの与えられた色の間の赤、緑、青の差を計算し、その差の一部を最初の色に追加します。2色の間隔を空けた場合、次の2色から新しいものから始めます。これは、最後の文字を除いてすべて繰り返されます。最後の文字は常に最後の色です。これにより、非常に美しいフェードが得られます。

その質問はとても楽しかったです!ありがとう!

更新情報

今では、すべてのケースを特別に処理するわけではありません。代わりに、2つある場合は色をトリミングし、すべての文字列にフェード機能を適用します。テキストよりも色が多かった場合、色はトリミングされ、フェード機能は単純なマッピングとまったく同じように機能します。

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