Créer un texte arc-en-ciel

22

Votre défi est de prendre l'entrée comme une ligne de texte et de la produire comme ceci.

image arc-en-ciel

Entrée sortie

L'entrée sera une chaîne qui ne contient que des caractères ASCII imprimables. Le premier ou le dernier caractère ne sera jamais un espace et il n'y aura jamais deux espaces de suite. Il comportera toujours au moins deux caractères.

Votre sortie doit être la même chaîne, convertie en couleurs arc-en-ciel comme décrit ci-dessous. La sortie peut être sous forme d'image (enregistrée dans un fichier ou autrement mise à disposition), ou simplement afficher le résultat à l'écran (comme le fait l'implémentation de référence ci-dessous).

Conversion

Pour déterminer la couleur de chaque lettre de la chaîne, utilisez l'algorithme suivant. Notez que chaque lettre a sa propre couleur individuelle . Ce n'est pas un dégradé!

  • Si ce personnage est un espace:

    • ... cela n'a pas d'importance, car les espaces ne peuvent pas vraiment ... avoir une couleur de toute façon. Générez simplement un espace.
  • Autrement:

    • Soit i= l'index de ce caractère dans la chaîne (basé sur 0, donc pour la toute première lettre, c'est 0), sans compter les espaces. Par exemple, dans la chaîne foo bar, cette valeur serait 4pour le a. En d'autres termes, c'est le nombre de non-espaces qui ont été rencontrés jusqu'à présent.

    • Soit n= le nombre de non-espaces dans la chaîne.

    • La couleur de cette lettre peut maintenant être exprimée, dans le système de coordonnées cylindriques HSL , comme [teinte = ( i/ n) * 360 °, saturation = 100%, légèreté = 50%].

Notez que ces directions impliquent que la sortie pour fooet f oodoit être exactement la même, sauf pour un espace ajouté après le f. Autrement dit, toutes les lettres doivent conserver les mêmes couleurs.

D'autres règles pour le processus de conversion sont décrites ci-dessous, dans les règles section .

Implémentation de référence

Ceci est écrit en JavaScript, et vous pouvez l'essayer en appuyant sur le bouton "Exécuter l'extrait de code".

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

Règles

  • Lors du calcul de la valeur de teinte d'une lettre, vous obtiendrez presque certainement un nombre décimal (non entier). Vous pouvez l'arrondir à l'entier le plus proche, le fixer au sol, prendre le plafond ou simplement ne pas arrondir du tout.

  • La taille de la police doit être lisible. Ici, cela est défini comme une police de taille 10pt ou supérieure.

  • Vous pouvez utiliser un canevas à largeur fixe ou une "zone de dessin" pour sortir le texte, mais il doit être en mesure de correspondre à l'exemple donné dans la toute première phrase de cet article.

  • La notation est le , donc le code le plus court en octets gagnera.

Poignée de porte
la source
La sortie peut-elle être un URI de données? C'est la sortie du canevas HTML
Downgoat
@vihan Oui, cela est conforme à la règle " La sortie peut être sous forme d'image (enregistrée dans un fichier ou autrement mise à disposition) ".
Poignée de porte
Comment déterminez-vous si une coloration répond aux spécifications? Pouvez-vous spécifier précisément la formule de conversion à utiliser si seules les couleurs RVB sont prises en charge dans une langue? De plus, combien de bits de précision par canal sont nécessaires? Vraisemblablement 8 serait OK, mais qu'en est-il de 4 ou 1?
feersum
@feersum Pour convertir en RVB, vous pouvez utiliser une fonction intégrée ou l'une des méthodes décrites ici . Pourriez-vous préciser ce que vous entendez par votre deuxième question? Vous posez des questions à ce sujet spécifiquement dans le contexte de la conversion HSL en RVB, ou en général?
Poignée de porte
2
Dang, je ne vais même pas essayer avec PowerShell ... Vous ne disposez que de 16 couleurs pour jouer (et elles ne sont même pas ordonnées ... arc-en-ciel ou RVB ou autre ... juste une valeur hexadécimale arbitraire). Référence, avec des images Un défi vraiment cool!
AdmBorkBork

Réponses:

12

Perl, 95

92 octets code + 3 pour -p

Ce script utilise une approximation des couleurs disponibles pour le terminal (256 maximum), n'incluant actuellement que quelques points de couleur sélectionnés dans cette liste , il est donc probable qu'il ne soit pas spécifié, mais c'était quand même amusant! J'ai filtré la liste pour n'afficher que les couleurs avec Set les Lvaleurs de 100%et 50%respectivement, puis trié par teinte, emballé les nombres dans une chaîne et sélectionné les couleurs de cette liste.

Cette implémentation comprend des caractères non imprimables! L'idée de Stole @ edc65 de remplacer seulement \Sau lieu de ., simple, mais intelligente!

@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

Inversez le hexdump en copiant le texte ci-dessus et en exécutant:

xxd -r > rainbowtext.pl

coller les données et appuyer sur Ctrl+ D.

Exécutez en utilisant:

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

Il produit une sortie comme:

MAINTENANT, VOTRE TEXTE TERMINAL EST ROUGE!  MUHAHAHAHA!

Dom Hastings
la source
10

Python 2: 240 utilisant PIL et 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()

Exemple de sortie:

Exemple de texte arc-en-ciel en sortie test avec des espaces

Merci à @agtoever et @Trang Oul pour quelques conseils de golf et à @Mauris pour avoir souligné les besoins en espaces.

Pour ajouter un vrai type de police, contrôlez la taille de la police, y compris le décalage horizontal et le changement de couleur en fonction de la longueur.

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 police que j'ai utilisée est disponible à partir d' ici : Le résultat est (le haut n'imprime que la chaîne, celui ci-dessous imprime par lettre):

machine à écrire

Willem
la source
1
Déposez as Pet écrivez PILdeux fois et gagnez un personnage. Changement imgà iet gagner 4 caractères.
agtoever
1
Enregistrer 255dans une variable, remplacer toutes les occurrences et utiliser (a,)*3comme couleur blanche. Remplacez float(j)par (j+.0).
Trang Oul
1
Aussi: remplacer float(j)to1.*j
agtoever
1
Attribuez plusieurs variables simultanément (par exemple u=len(s) a=255=> u,a=len(s),255). Retirez les []supports de tuple, ils ne sont pas nécessaires. Remplacez la boucle par la compréhension de la liste (la méthode sera évaluée comme un effet secondaire).
Trang Oul
1
@willem: Jetez un œil à la spécification du problème (sous Conversion ); il explique spécifiquement comment votre programme doit gérer les espaces.
Lynn
5

JavaScript (ES6), 114 117 125

Edit2 3 octets enregistrés thx @Dom Hastings Edit HTML non valide, mais fonctionnant quand même.

Remarque habituelle: test de l'exécution de l'extrait sur un navigateur compatible EcmaScript 6 (notamment pas Chrome ni MSIE. J'ai testé sur 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
la source
1
Pour l'instant, aucun navigateur n'est entièrement compatible avec ES6. IE n'est même pas encore entièrement compatible ES5!
SuperJedi224
@ SuperJedi224 Je suis d'accord. Je dis juste: ne l'essayez pas avec Chrome ou MSIE, tout en utilisant Firefox, cela fonctionne
edc65
J'ai l'impression que je ne devrais même pas dire quoi que ce soit parce que je viens juste d'avoir le mien sous le vôtre, mais je pense que vous pouvez omettre la déclaration )après votre hsl(déclaration car cela semble toujours fonctionner pour moi dans Firefox!
Dom Hastings
De plus, vous pouvez changer ${c}'pour '+cenregistrer 2 de plus ... Mieux vaut reprendre le mien!
Dom Hastings
Cela ne fonctionne pas sur Safari 9.0. c:
Addison Crump
4

Python 3, 131 octets

Similaire à la réponse de Dom Hastings mais implémenté en python.

La chaîne a '|\x82\x88\x8ejF"#$%\x1f\x19\x137[\x7f~}'été créée à partir de la liste [124,130,136,142,106,70,34,35,36,37,31,25,19,55,91,127,126,125]des codes de couleur terminaux à afficher dans l'ordre. Ils ont été filtrés de sorte qu'ils n'incluent que les couleurs avec une saturation de 100% et une valeur de 50%. La liste a ensuite été triée afin que les teintes correctes soient affichées en premier.

Prend l'entrée de stdin et la renvoie à stdout.

Votre terminal que vous utilisez DOIT prendre en charge les codes d'échappement ANSI pour fonctionner correctement.

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 version raccourcie avec des caractères d'octets littéraux (n'a pas collé correctement):

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

Vidage hexadécimal littéral:

783d696e70757428293b753d277c82888e6a46222324251f1913375b7f7e7d273b6a3d300a666f72206920696e20783a7072696e7428271b5b33383b353b25646d25732725286f726428755b286a2a3138292f2f6c656e28782e7265706c616365282220222c20222229295d292c69292c656e643d2222293b6a2b3d69213d2220220a

Merci @swstephe pour avoir économisé 9 octets (et aussi pour m'avoir fait remarquer que mon comptage d'octets était très légèrement faux)!

Bleu
la source
Pourquoi ne pas remplacer "\ x82" par le caractère réel? J'ai écrit cette chaîne dans un fichier et l'ai relue dans mon script en binaire. Vous pouvez remplacer \ 033 par un caractère d'échappement brut, ou même \ 1f (hex). Vous déclarez "u", puis ne l'utilisez qu'une seule fois. Vous pouvez enregistrer quelques caractères en le déplaçant vers le bas dans l'expression. Vous pouvez éviter l'appel int () en utilisant "//" pour la division entière.
swstephe
oups, \ 033 est identique à \ x1f.
swstephe
2

PHP, 165 octets

Exécuter avec entrée comme paramètre "s"

Le code HTML n'est pas valide, mais il devrait s'afficher dans tous les principaux navigateurs (testé dans Chrome et 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
la source
1

PHP 4.1, 112 103 102 octets

J'ai utilisé la réponse de @DankMemes comme point de départ. À partir de là, j'ai implémenté une tonne de changements, au point que le code est différent.

L'implémentation est similaire, le code est totalement différent.

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

Pour l'utiliser, il suffit de définir une valeur sur une SESSION / GET / POST / COOKIE avec le nom s.

Résultat de l'exécution de cette fonction, sur la phrase test:

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