Criar texto do arco-íris

22

Seu desafio é receber a entrada como uma linha de texto e produzi-la dessa maneira.

imagem do arco-íris

Entrada / saída

A entrada será uma sequência que contém apenas caracteres ASCII imprimíveis. O primeiro ou o último caracteres nunca serão espaços e nunca haverá dois espaços seguidos. Sempre terá pelo menos dois caracteres.

Sua saída deve ser a mesma string, convertida em cores do arco-íris, conforme descrito abaixo. A saída pode estar na forma de imagem (salva em um arquivo ou de alguma forma disponibilizada) ou pode simplesmente exibir o resultado na tela (como a implementação de referência abaixo).

Conversão

Para determinar a cor de cada letra na sequência, use o seguinte algoritmo. Observe que cada letra tem sua própria cor individual . Este não é um gradiente!

  • Se esse personagem for um espaço:

    • ... não importa, porque os espaços não podem realmente ... ter uma cor de qualquer maneira. Basta imprimir um espaço.
  • De outra forma:

    • Let i= o índice desse caractere na string (com base em 0, portanto, para a primeira letra 0), sem contar os espaços. Por exemplo, na cadeia foo bar, esse valor seria 4para o a. Em outras palavras, é esse o número de não-espaços encontrados até agora.

    • Let n= o número de não espaços na string.

    • A cor desta letra agora pode ser expressa, no sistema de coordenadas cilíndricas HSL , como [matiz = ( i/ n) * 360 °, saturação = 100%, luminosidade = 50%].

Observe que essas instruções implicam que a saída fooe f oodeve ser exatamente a mesma, exceto por um espaço adicional após a f. Ou seja, todas as letras devem manter as mesmas cores.

Regras adicionais para o processo de conversão estão descritas abaixo, na seção Regras .

Implementação de referência

Isso está escrito em JavaScript e você pode experimentá-lo pressionando o botão "Executar trecho de código".

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

Regras

  • Ao calcular o valor de Matiz de uma letra, você quase certamente obterá um número decimal (não inteiro). Você pode arredondar para o número inteiro mais próximo, colocar no chão, pegar o teto ou simplesmente não arredondar.

  • O tamanho da fonte deve ser legível. Aqui, isso é definido como uma fonte de tamanho 10pt ou superior.

  • Você pode usar uma tela de largura fixa ou "área de desenho" para produzir o texto, mas ele deve poder se encaixar no exemplo dado na primeira frase desta postagem.

  • A pontuação é , portanto o código mais curto em bytes vencerá.

Maçaneta da porta
fonte
A saída pode ser um URI de dados? Essa é a saída da tela HTML
Downgoat
@vihan Sim, isso é qualificado de acordo com a regra " A saída pode estar na forma de imagem (salva em um arquivo ou de alguma outra forma disponibilizada) ".
Maçaneta
Como você determina se uma coloração atende às especificações? Você pode especificar com precisão qual fórmula de conversão deve ser usada se apenas as cores RGB forem suportadas em um idioma? Além disso, quantos bits de precisão por canal são necessários? Presumivelmente 8 seria bom, mas que tal 4 ou 1?
feersum
@feersum Para converter para RGB, você pode usar um built-in ou um dos métodos descritos aqui . Você poderia esclarecer o que você quer dizer com sua segunda pergunta? Você está perguntando sobre isso especificamente no contexto da conversão de HSL para RGB ou em geral?
Maçaneta
2
Caramba, eu não vou nem tentar com o PowerShell ... Você só tem 16 cores para brincar (e elas nem são encomendadas ... arco-íris ou RGB ou outra coisa ... apenas um valor hexadecimal arbitrário). Referência, com fotos Um desafio muito legal!
AdmBorkBork

Respostas:

12

Perl, 95

Código de 92 bytes + 3 para -p

Esse script usa uma aproximação das cores disponíveis para o terminal (máximo de 256) atualmente, incluindo apenas alguns pontos de cores selecionados nesta lista ; portanto, é provável que não especifique, mas foi divertido de qualquer maneira! Filtrei a lista para mostrar apenas cores com Se Lvalores de 100%e 50%, respectivamente, e depois classificadas por matiz, agrupei os números em uma sequência e selecionei as cores dessa lista.

Esta implementação inclui caracteres não imprimíveis! Roubou a idéia do @ edc65 de substituir apenas ao \Sinvés de ., simples, mas inteligente!

@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

Inverta o hexdump copiando o texto acima e executando:

xxd -r > rainbowtext.pl

colando nos dados e pressionando Ctrl+ D.

Execute usando:

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

Produz saída como:

AGORA SEU TEXTO TERMINAL É VERMELHO!  MUHAHAHAHA!

Dom Hastings
fonte
10

Python 2: 240 usando PIL e colorsys lib

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

Exemplo de saída:

Exemplo de texto do arco-íris de saída teste com espaços

Agradecemos a @agtoever e @Trang Oul por algumas dicas de golfe e a @Mauris por apontar os requisitos de espaço.

Para adicionar fontes de tipo verdadeiro, controle de tamanho da fonte, incluindo deslocamento horizontal e alteração de cores com base no comprimento.

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

A fonte que usei está disponível aqui : O resultado é (a parte superior está imprimindo a sequência de caracteres, a abaixo está imprimindo por letra):

máquina de escrever

Willem
fonte
1
Solte as Pe escreva PILduas vezes e ganhe um personagem. Mude imgpara ie ganhe mais 4 personagens.
agtoever
1
Salve 255em uma variável, substitua todas as ocorrências e use (a,)*3como cor branca. Substitua float(j)por (j+.0).
Trang Oul
1
Também: substituir float(j)para1.*j
agtoever
1
Atribua várias variáveis ​​simultaneamente (por exemplo, u=len(s) a=255=> u,a=len(s),255). Remova os []suportes tuple, eles não são necessários. Substituir loop pela compreensão da lista (o método será avaliado como um efeito colateral).
Trang Oul
1
@ willem: dê uma olhada na especificação do problema (em Conversão ); explica especificamente como seu programa deve lidar com espaços.
Lynn
5

JavaScript (ES6), 114 117 125

Edit2 3 bytes salvos thx @Dom Hastings Edit HTML inválido, mas funcionando de qualquer maneira.

Nota habitual: teste ao executar o snippet em um navegador compatível com EcmaScript 6 (principalmente o Chrome, não o MSIE. Testei no 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>

edc65
fonte
1
Ainda não há navegador totalmente compatível com ES6. O IE ainda nem é totalmente compatível com o ES5!
precisa saber é o seguinte
@ SuperJedi224 eu concordo. Só estou dizendo: não tente fazer isso com o Chrome ou MSIE, enquanto estiver usando o Firefox funciona
edc65
Sinto que não deveria nem dizer nada, porque acabei de colocar a minha na sua, mas acho que você pode omitir a declaração )após a hsl(declaração, pois parece que ainda funciona para mim no Firefox!
Dom Hastings
Além disso, você pode mudar ${c}'para '+ceconomizar mais 2 ... É melhor voltar com o meu!
Dom Hastings
Isso não funciona no Safari 9.0. c:
Addison Crump
4

Python 3, 131 bytes

Semelhante à resposta de Dom Hastings, mas implementada em python.

A sequência '|\x82\x88\x8ejF"#$%\x1f\x19\x137[\x7f~}'foi criada a partir da lista, [124,130,136,142,106,70,34,35,36,37,31,25,19,55,91,127,126,125]os códigos de cores dos terminais a serem exibidos em ordem. Eles foram filtrados para incluir apenas cores com saturação de 100% e valor de 50%. A lista foi então classificada para que os matizes corretos fossem exibidos primeiro.

Pega a entrada de stdin e retorna para stdout.

O terminal que você está usando DEVE suportar códigos de escape ANSI para executar isso corretamente.

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

Ou versão reduzida com caracteres de bytes literais (não colou corretamente):

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

783d696e70757428293b753d277c82888e6a46222324251f1913375b7f7e7d273b6a3d300a666f72206920696e20783a7072696e7428271b5b33383b353b25646d25732725286f726428755b286a2a3138292f2f6c656e28782e7265706c616365282220222c20222229295d292c69292c656e643d2222293b6a2b3d69213d2220220a

Obrigado @swstephe por salvar 9 bytes (e também por me fazer notar que minha contagem de bytes estava levemente muito errada)!

Azul
fonte
Por que não substituir "\ x82" pelo caractere real? Eu escrevi essa string em um arquivo e li de volta no meu script em binário. Você pode substituir \ 033 por um caractere de escape bruto ou mesmo \ 1f (hex). Você declara "u" e depois o usa apenas uma vez. Você pode salvar alguns caracteres movendo-o para baixo na expressão. Você pode evitar a chamada int () usando "//" para dividir números inteiros.
precisa saber é
opa, \ 033 é o mesmo que \ x1f.
swstephe
2

PHP, 165 bytes

Execute com entrada como o parâmetro "s"

O HTML é inválido, mas deve ser renderizado nos principais navegadores (testado no Chrome e 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;}
DankMemes
fonte
1

PHP 4.1, 112 103 102 bytes

Eu usei a resposta @DankMemes como ponto de partida. A partir daí, eu implementei um tonelada de mudanças, a ponto de o código ser diferente.

A implementação é semelhante, o código é totalmente diferente.

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

Para usá-lo, basta definir um valor em SESSION / GET / POST / COOKIE com o nome s .

Resultado da execução desta função, na sentença de teste:

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

Ismael Miguel
fonte