Crear texto de arcoiris

22

Su desafío es tomar la entrada como una línea de texto y generarla de esta manera.

imagen del arcoiris

De entrada y salida

La entrada será una cadena que contiene solo caracteres ASCII imprimibles. El primer o el último carácter nunca serán espacios, y nunca habrá dos espacios seguidos. Siempre tendrá al menos dos caracteres de longitud.

Su salida debe ser la misma cadena, convertida a colores del arco iris como se describirá a continuación. La salida puede estar en forma de imagen (guardada en un archivo o de alguna manera disponible), o simplemente puede mostrar el resultado en la pantalla (como lo hace la implementación de referencia a continuación).

Conversión

Para determinar en qué color debe convertirse cada letra en la cadena, use el siguiente algoritmo. Tenga en cuenta que cada letra es su propio color individual . ¡Esto no es un gradiente!

  • Si este personaje es un espacio:

    • ... no importa, porque los espacios no pueden ... tener un color de todos modos. Simplemente genera un espacio.
  • De otra manera:

    • Let i= el índice de este carácter en la cadena (basado en 0, por lo que para la primera letra, esto es 0), sin contar espacios. Por ejemplo, en la cadena foo bar, este valor sería 4para el a. En otras palabras, esta es la cantidad de no espacios que se han encontrado hasta ahora.

    • Let n= el número de no espacios en la cadena.

    • El color de esta letra ahora se puede expresar, en el sistema de coordenadas cilíndricas HSL , como [hue = ( i/ n) * 360 °, saturation = 100%, lightness = 50%].

Tenga en cuenta que estas instrucciones implican que la salida para fooy f oodebería ser exactamente la misma, excepto por un espacio adicional después de f. Es decir, todas las letras deben conservar los mismos colores.

Las reglas adicionales para el proceso de conversión se describen a continuación, en las Reglas sección .

Implementación de referencia

Esto está escrito en JavaScript, y puede probarlo presionando el botón "Ejecutar fragmento 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;
}

Reglas

  • Al calcular el valor de tono de una letra, es casi seguro que obtendrá un número decimal (no entero). Puede redondear esto al número entero más cercano, colocarlo en el piso, tomar el techo o simplemente no redondear en absoluto.

  • El tamaño de la fuente debe ser legible. Aquí, esto se define como una fuente de tamaño 10pt o mayor.

  • Puede usar un lienzo de ancho fijo o "área de dibujo" para generar el texto, pero debe poder ajustarse al ejemplo dado en la primera oración de esta publicación.

  • La puntuación es el , por lo que ganará el código más corto en bytes.

Pomo de la puerta
fuente
¿Puede la salida ser un URI de datos? Ese es el resultado del lienzo HTML
Downgoat
@vihan Sí, eso califica según la regla " La salida puede estar en forma de imagen (guardada en un archivo o de alguna manera disponible) ".
Pomo de la puerta
¿Cómo se determina si una coloración cumple con las especificaciones? ¿Puede especificar con precisión qué fórmula de conversión se debe usar si solo se admiten colores RGB en un idioma? Además, ¿cuántos bits de precisión por canal son necesarios? Presumiblemente 8 estaría bien, pero ¿qué tal 4 o 1?
Feersum
@feersum Para convertir a RGB, puede usar uno incorporado o uno de los métodos descritos aquí . ¿Podría aclarar qué quiere decir con su segunda pregunta? ¿Está preguntando sobre esto específicamente en el contexto de la conversión de HSL a RGB, o en general?
Pomo de la puerta
2
Dang, ni siquiera voy a probar con PowerShell ... Solo obtienes 16 colores para jugar (y ni siquiera están ordenados ... arco iris o RGB o de lo contrario ... solo un valor hexadecimal arbitrario). Referencia, con imágenes ¡Un desafío realmente genial!
AdmBorkBork

Respuestas:

12

Perl, 95

Código de 92 bytes + 3 para -p

Este script utiliza una aproximación de los colores disponibles para el terminal (256 máximo) que actualmente solo incluye algunos puntos de color seleccionados de esta lista , por lo que es probable que no especifique, ¡pero de todos modos fue divertido! Filtré la lista para mostrar solo los colores Sy Lvalores de 100%y 50%respectivamente, luego los ordené por tono, empaqué los números en una cadena y seleccioné los colores de esa lista.

¡Esta implementación incluye caracteres no imprimibles! ¡La idea de Stole @ edc65 de reemplazar solo en \Slugar de ., simple, pero 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

Invierta el hexdump copiando el texto anterior y ejecutando:

xxd -r > rainbowtext.pl

pegando los datos y presionando Ctrl+ D.

Ejecutar usando:

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

Produce resultados como:

AHORA SU TEXTO TERMINAL ES ROJO!  MUHAHAHAHA!

Dom Hastings
fuente
10

Python 2: 240 usando PIL y 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()

Salida de ejemplo:

Ejemplo de texto de arco iris de salida prueba con espacios

Gracias a @agtoever y @Trang Oul por algunos consejos de golf, y a @Mauris por señalar el requisito de espacios.

Para agregar fuentes de tipo verdadero, control de tamaño de fuente, incluyendo desplazamiento horizontal y cambio de color según la longitud.

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

La fuente que utilicé está disponible desde aquí : El resultado es (la parte superior solo imprime la cadena, la siguiente se imprime por letra):

máquina de escribir

Willem
fuente
1
Suelta as Py escribe PILdos veces y gana un personaje. Cambiar imga iy ganar 4 caracteres más.
agtoever
1
Guardar 255en una variable, reemplazar todas las ocurrencias y usar (a,)*3como color blanco. Reemplazar float(j)por (j+.0).
Trang Oul
1
También: reemplace float(j)a1.*j
agtoever
1
Asigne múltiples variables simultáneamente (p. Ej. u=len(s) a=255=> u,a=len(s),255). Retire los []soportes de tuple, no son necesarios. Reemplazar el bucle por la comprensión de la lista (el método se evaluará como un efecto secundario).
Trang Oul
1
@willem: Eche un vistazo a la especificación del problema (en Conversión ); Explica específicamente cómo su programa debe manejar los espacios.
Lynn
5

JavaScript (ES6), 114 117 125

Edit2 3 bytes guardados thx @Dom Hastings Editar HTML no válido, pero funciona de todos modos.

Nota habitual: prueba ejecutando el fragmento en un navegador compatible con EcmaScript 6 (notablemente no Chrome ni MSIE. Probé en 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
fuente
1
Ningún navegador es completamente compatible con ES6, todavía. ¡IE ni siquiera es totalmente compatible con ES5 todavía!
SuperJedi224
@ SuperJedi224 Estoy de acuerdo. Solo digo: no lo intente con Chrome o MSIE, mientras usa Firefox funciona
edc65
Siento que ni siquiera debería decir nada porque acabo de tener el mío debajo del tuyo, ¡pero creo que puedes omitir el )después de tu hsl(declaración, ya que parece que todavía funciona para mí en Firefox!
Dom Hastings
Además, puedes cambiar ${c}'a '+cpara ahorrar 2 más ... ¡Es mejor que sigas con el mío!
Dom Hastings
Esto no funciona en Safari 9.0. c:
Addison Crump
4

Python 3, 131 bytes

Simular a la respuesta de Dom Hastings pero implementado en python.

La cadena '|\x82\x88\x8ejF"#$%\x1f\x19\x137[\x7f~}'se creó a partir de la lista.[124,130,136,142,106,70,34,35,36,37,31,25,19,55,91,127,126,125] los códigos de color del terminal para mostrar en orden. Se han filtrado por lo que solo incluyen colores con una saturación del 100% y un valor del 50%. La lista se ordenó para que los tonos correctos se mostraran primero.

Toma la entrada de stdin y la devuelve a stdout.

Su terminal que está utilizando DEBE admitir códigos de escape ANSI para ejecutar esto correctamente.

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

O versión abreviada con caracteres de byte literal (No se pegó correctamente):

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

¡Gracias @swstephe por guardar 9 bytes (y también por hacerme notar que mi recuento de bytes fue un poco muy incorrecto)!

Azul
fuente
¿Por qué no reemplazar "\ x82" con el carácter real? Escribí esa cadena en un archivo y la leí en mi script en binario. Puede reemplazar \ 033 con un carácter de escape sin formato, o incluso \ 1f (hexadecimal). Usted declara "u", luego solo lo usa una vez. Puede guardar algunos caracteres moviéndolo hacia abajo en la expresión. Puede evitar la llamada int () utilizando "//" para la división de enteros.
swstephe
Uy, \ 033 es lo mismo que \ x1f.
swstephe
2

PHP, 165 bytes

Ejecutar con entrada como el parámetro "s"

El HTML no es válido, pero debe mostrarse en todos los principales navegadores (probado en Chrome y 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
fuente
1

PHP 4.1, 112 103 102 bytes

He usado la respuesta de @DankMemes como punto de partida. A partir de ahí, he implementado un montón de cambios, hasta el punto de que el código es diferente.

La implementación es similar, el código es totalmente diferente.

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

Para usarlo, simplemente establezca un valor en SESSION / GET / POST / COOKIE con el nombre s.

Resultado de ejecutar esta función, en la oración de prueba:

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