AppleSauce Fader


11

Antigamente, todas as 1337 crianças usavam faders de texto nas salas de chat. Eu não sei sobre vocês, mas quero me sentir bem como eles. O único problema é que seus scripts e aplicativos antigos estavam fortemente acoplados ao software para o qual foram criados, então não posso simplesmente usar essa incrível funcionalidade onde quiser. Também quero que a solução seja facilmente portátil, para que você precise tornar o código o menor possível para caber no meu disquete (prefiro carregar apenas um disquete, mas se o seu código-fonte for muito grande Eu posso carregar mais de um : P ).

Entrada

  • Uma lista de cores (rgb, hex, nomes etc.)
  • Texto para formatar

Seu programa deve esperar que a lista de cores contenha pelo menos 2 cores.
O texto a ser formatado pode ter qualquer comprimento maior que zero e os caracteres serão limitados aos ascii imprimíveis. (Dica: entradas de texto mais longas podem exigir que você reutilize cores intermediárias para caracteres consecutivos)

Resultado

O texto de saída não deve diferir do texto de entrada de nenhuma outra maneira que não seja fonte e / ou marcação / estilo (Nota: se sua saída contiver marcação html, será necessário codificar html na entrada). Você pode produzir texto com marcação / estilo (tags de estilo html, cores do console etc.) ou uma imagem do texto desbotado. Todos os hexágonos de cores devem estar presentes na saída, a menos que a entrada não contenha caracteres suficientes para atender a esse requisito. Se for esse o caso, consulte as regras de prioridade para determinar quais hexadecimais de cores devem estar presentes em sua saída. A ordem ou essas cores em sua saída ainda devem ser a ordem de entrada.

Regras de prioridade de cores

  1. No caso de a entrada ser um caractere, a primeira cor será usada
  2. No caso de haver apenas dois caracteres, a primeira e a última cor serão usadas
  3. No caso de haver mais de três cores e mais cores do que caracteres, a primeira e a última cores devem ser priorizadas e, em seguida, o restante das cores na ordem de entrada.
  4. No caso de haver mais caracteres do que cores, os caracteres devem desaparecer de uma cor para a outra usando cores intermediárias

Exemplos (regras de prioridade 1-3, respectivamente):
# Cores | Cor 0 | ... Cor n | Texto
3 ff0000 0000ff ffff00 M-> -> ->somente primeiro
3 ff0000 0000ff ffff00 hiignorar segundo
4 ff0000 0000ff ffff00 0fff00 supignorar terceiro

Para ficar claro, a cor do texto deve desaparecer de uma cor hexadecimal para a seguinte. O desbotamento não precisa ser perfeitamente uniforme, mas não deve ser uma mudança abrupta de cor, a menos que não haja caracteres suficientes para desbotar. Geralmente, esse desbotamento é alcançado escolhendo cores intermediárias para cada um dos caracteres, aumentando / diminuindo os valores de rgb em algum intervalo determinado pelo número de caracteres com os quais você deve trabalhar e pela diferença entre as cores. Por exemplo, se precisarmos de uma única cor entre vermelho(# ff0000) e Preto(# 000000), poderemos escolher # 800000como fica no meio. A saída ideal parecerá bastante bonita.

Exemplo (regra de prioridade 4):
3 ff0000 ff7f00 f0ff00 To be or not to be, that is the question...-> -OR-ser ou não

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

Na sua resposta, especifique como sua saída deve ser exibida (como html, em um console, como uma imagem etc.).

* Todos os fundos pretos são apenas para ênfase de cores e não são necessários

Pontuação

Isso é , então a resposta mais curta (em bytes) vence.
Se você conseguir adicionar fade a personagens individuais, eu sempre pensarei que você é legal (mas nenhum bônus para marcar, pois isso não será justo para alguns langs)



@LeakyNun No espaço RGB, ele é próximo o suficiente, a outra opção é # 7f0000.
Neil

Na verdade não. Tente calcular a média de vermelho e verde dessa maneira e veja se você fica amarelo. Para fazer isso da maneira certa, use a raiz quadrada média em vez da média direta.
Freira Furada

A média de 000000e ff0000deve ser b40000( 255*sqrt((0+1)/2)) #
Leaky Nun 25/05

1
@LeakyNun Eu nunca disse que você precisava calcular a média das cores. Descrevi um método fácil de desbotamento que às vezes é empregado para desafios como esse. Nesse caso, calculamos a média dos vermelhos das duas cores (e arredondadas). Também notei no desafio que o desbotamento não precisa ser perfeitamente uniforme. Cabe a você como você deseja implementar esse desbotamento.
puxão

Respostas:


3

JavaScript (ES6), 290 bytes

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
É muito legal ver isso acontecer em tempo real com o snippet de código. : D
AdmBorkBork

1

Pitão, 126 bytes

Média quadrática média quadrática obrigatória em vez da média aritmética direta.

L%"<span style=\"color:#%s\">%s</span>",smt.H+256s*255@d2ebhbMm+hG*-eGhGcdHH=Q^RL2Q+smsyMC,hdCgRlhdCedC,ctlQPzC,QtQy,ez?tlzeQh

Experimente online!

Saída de amostra:

amostra


1

Java, 702 662 caracteres

Duas funções jogadas:

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

Como ninguém pode ler isso: aqui estão as duas funções na versão não destruída em uma classe:

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

Aqui você tem um limite superior para seu próprio código. O uso é chamar colorize(ou c na versão golfed) e passar o texto e uma matriz de códigos de cores hexadecimais. A função retornará uma String com tags HTML, como o OP, portanto, você precisa de uma maneira de renderizar o HTML.

O algoritmo é mais fácil como a pergunta parece. O primeiro caractere sempre obtém a primeira cor, o último sempre a última. Se tivermos mais cores do que caracteres no texto, apenas iteramos sobre o texto e as cores e as aplicamos. A parte divertida é a que se desvanece: comecei descobrindo a que distância as cores estão no texto. Eu basicamente calculo a diferença de vermelho, verde e azul entre duas cores fornecidas e, em seguida, adiciono uma parte dessa diferença à primeira cor, dependendo de onde o caractere está entre as cores. Se deixar o intervalo de duas cores, começamos do novo com as próximas duas cores. Isso é repetido para todos, exceto o último caractere, que sabemos que é sempre a última cor. Isso dá um desbotamento muito bonito.

Essa pergunta foi muito divertida! Obrigado!

Atualizações

Agora eu não manuseio todos os casos especialmente. Em vez disso, aparei as cores, se houver duas, e aplico a função fade a todas as cordas. Se houver mais cores do que texto, as cores serão aparadas e a função de desbotamento funcionará exatamente como um mapeamento simples.

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.