Crea testo arcobaleno


22

La tua sfida è prendere l'input come una riga di testo e generarlo in questo modo.

immagine arcobaleno

Input Output

L'input sarà una stringa che contiene solo caratteri ASCII stampabili. Il primo o l'ultimo personaggio non saranno mai spazi e non ci saranno mai due spazi di fila. Avrà sempre almeno due caratteri.

L'output deve essere la stessa stringa, convertita in colori arcobaleno come sarà descritto di seguito. L'output può essere in forma di immagine (salvato in un file o in qualche modo reso disponibile), oppure può semplicemente visualizzare il risultato sullo schermo (come fa l'implementazione di riferimento di seguito).

Conversione

Per determinare di che colore dovrebbe diventare ciascuna lettera nella stringa, utilizzare il seguente algoritmo. Nota che ogni lettera ha il suo colore individuale . Questo non è un gradiente!

  • Se questo personaggio è uno spazio:

    • ... non importa, perché gli spazi non possono davvero ... avere un colore comunque. Basta generare uno spazio.
  • Altrimenti:

    • Let i= l'indice di questo carattere nella stringa (basato su 0, quindi per la prima lettera, questo è 0), senza contare gli spazi. Ad esempio, nella stringa foo bar, questo valore sarebbe 4per a. In altre parole, questo è il numero di non spazi finora incontrati.

    • Let n= il numero di non spazi nella stringa.

    • Il colore di questa lettera può ora essere espresso, nel sistema di coordinate cilindriche HSL , come [tonalità = ( i/ n) * 360 °, saturazione = 100%, leggerezza = 50%].

Si noti che queste direzioni implicano che l'output per fooe f oodovrebbe essere esattamente lo stesso, ad eccezione di uno spazio aggiunto dopo il f. Cioè, tutte le lettere dovrebbero conservare gli stessi colori.

Ulteriori regole per il processo di conversione sono descritte di seguito, nella sezione Regole .

Implementazione di riferimento

Questo è scritto in JavaScript e puoi provarlo premendo il pulsante "Esegui frammento di codice".

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

Regole

  • Quando si calcola il valore di tonalità di una lettera, si otterrà quasi certamente un numero decimale (non intero). Puoi arrotondarlo al numero intero più vicino, spostarlo, prendere il soffitto o semplicemente non arrotondare affatto.

  • La dimensione del carattere deve essere leggibile. Qui, questo è definito come un carattere di dimensione 10pt o superiore.

  • Puoi usare una tela a larghezza fissa o "area di disegno" per produrre il testo, ma deve essere in grado di adattarsi all'esempio dato nella prima frase di questo post.

  • Il punteggio è , quindi vincerà il codice più breve in byte.


L'output può essere un URI di dati? Questo è l'output della tela HTML
Downgoat

@vihan Sì, è conforme alla regola " L'output può essere in formato immagine (salvato in un file o in qualche modo reso disponibile) ".
Maniglia della porta

Come si determina se una colorazione soddisfa le specifiche? Puoi specificare con precisione quale formula di conversione utilizzare se sono supportati solo i colori RGB in una lingua? Inoltre, quanti bit di precisione per canale sono necessari? Presumibilmente 8 sarebbe OK, ma che ne dici di 4 o 1?
feersum

@feersum Per convertire in RGB, è possibile utilizzare un metodo incorporato o uno dei metodi descritti qui . Potresti chiarire cosa intendi con la tua seconda domanda? Stai chiedendo questo in particolare nel contesto della conversione da HSL a RGB, o in generale?
Maniglia della porta

2
Dang, non proverò nemmeno con PowerShell ... Avrai solo 16 colori con cui giocare (e non sono nemmeno ordinati ... arcobaleno o RGB o altro ... solo un valore esadecimale arbitrario). Riferimento, con immagini Sfida davvero interessante, però!
AdmBorkBork,

Risposte:


12

Perl, 95

92 byte codice + 3 per -p

Questo script utilizza un'approssimazione dei colori disponibili per il terminale (massimo 256) che attualmente include solo alcuni punti di colore selezionati da questo elenco , quindi è probabile che non sia speculare, ma è stato comunque divertente! Ho filtrato l'elenco per mostrare solo i colori con Se rispettivamente i Lvalori di 100%e 50%, quindi, ordinati per tonalità, ho compresso i numeri in una stringa e ho selezionato i colori da quell'elenco.

Questa implementazione include caratteri non stampabili! L'idea di Stole @ edc65 di sostituire solo \Sinvece di ., semplice, ma 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

Invertire il dump esadecimale copiando il testo sopra ed eseguendo:

xxd -r > rainbowtext.pl

incollando i dati e premendo Ctrl+ D.

Esegui utilizzando:

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

Produce output come:

ORA IL TUO TESTO DEL TERMINALE È ROSSO!  MUHAHAHAHA!


10

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

Esempio di output:

Esempio di testo arcobaleno di output prova con spazi

Grazie a @agtoever e @Trang Oul per alcuni suggerimenti sul golf e per @Mauris per aver sottolineato i requisiti di spazio.

Per aggiungere un tipo di carattere vero, controllo della dimensione del carattere, inclusi offset orizzontale e cambio colore in base alla lunghezza.

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

Il font che ho usato è disponibile da qui : il risultato è (la parte superiore sta semplicemente stampando la stringa, quella sotto è la stampa per lettera):

macchina da scrivere


1
Rilascia as Pe scrivi PILdue volte e vinci un personaggio. Passa imga ie vinci altri 4 personaggi.
agtoever,

1
Salvare 255in una variabile, sostituire tutte le occorrenze e utilizzare (a,)*3come colore bianco. Sostituisci float(j)con (j+.0).
Trang Oul,

1
Inoltre: sostituire float(j)a1.*j
agtoever il

1
Assegna più variabili contemporaneamente (ad es. u=len(s) a=255=> u,a=len(s),255). Rimuovere le []parentesi da tuple, non sono necessarie. Sostituisci loop con la comprensione dell'elenco (il metodo verrà valutato come effetto collaterale).
Trang Oul,

1
@willem: dai un'occhiata alla specifica del problema (sotto Conversione ); spiega specificamente come il tuo programma dovrebbe gestire gli spazi.
Lynn,

5

JavaScript (ES6), 114 117 125

Edit2 3 byte salvati grazie a @Dom Hastings Edit HTML non valido, ma funzionante comunque.

Nota usuale: test di esecuzione dello snippet su un browser compatibile con EcmaScript 6 (in particolare Chrome non MSIE. Ho testato su 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>


1
Nessun browser è ancora completamente conforme ES6. IE non è ancora completamente conforme a ES5!
SuperJedi224,

@ SuperJedi224 Sono d'accordo. Sto solo dicendo: non provarlo con Chrome o MSIE, mentre usando Firefox funziona
edc65

Sento che non dovrei nemmeno dire nulla perché ho solo il mio sotto il tuo, ma penso che tu possa omettere la dichiarazione )dopo hsl(che sembra funzionare ancora per me in Firefox!
Dom Hastings,

Inoltre, puoi cambiare ${c}'per '+csalvare altri 2 ... Meglio tornare con il mio!
Dom Hastings,

Questo non funziona su Safari 9.0. c:
Addison Crump,

4

Python 3, 131 byte

Simile alla risposta di Dom Hastings ma implementato in Python.

La stringa è '|\x82\x88\x8ejF"#$%\x1f\x19\x137[\x7f~}'stata creata dall'elenco[124,130,136,142,106,70,34,35,36,37,31,25,19,55,91,127,126,125] sono i codici colore del terminale da visualizzare in ordine. Sono stati filtrati in modo da includere solo colori con saturazione 100% e valore 50%. L'elenco è stato quindi ordinato in modo da visualizzare prima le tonalità corrette.

Prende l'input da stdin e lo restituisce a stdout.

Il terminale che stai utilizzando DEVE supportare i codici di escape ANSI per eseguirlo correttamente.

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 versione abbreviata con caratteri letterali in byte (non incollata correttamente):

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

783d696e70757428293b753d277c82888e6a46222324251f1913375b7f7e7d273b6a3d300a666f72206920696e20783a7072696e7428271b5b33383b353b25646d25732725286f726428755b286a2a3138292f2f6c656e28782e7265706c616365282220222c20222229295d292c69292c656e643d2222293b6a2b3d69213d2220220a

Grazie @swstephe per aver salvato 9 byte (e anche per avermi fatto notare che il mio conteggio dei byte è stato sempre leggermente sbagliato)!


Perché non sostituire "\ x82" con il carattere reale? Ho scritto quella stringa in un file e l'ho letta nel mio script in binario. È possibile sostituire \ 033 con un carattere di escape non elaborato o anche \ 1f (esadecimale). Dichiara "u", quindi lo usi solo una volta. Puoi salvare alcuni personaggi spostandolo verso il basso nell'espressione. È possibile evitare la chiamata int () utilizzando "//" per la divisione di numeri interi.
swstephe,

oops, \ 033 è uguale a \ x1f.
swstephe,

2

PHP, 165 byte

Esegui con input come parametro "s"

L'HTML non è valido ma dovrebbe essere visualizzato in tutti i principali browser (testato su 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;}

1

PHP 4.1, 112 103 102 byte

Ho usato la risposta di @DankMemes come punto di partenza. Da quel momento in poi, ho implementato molte modifiche, al punto che il codice è diverso.

L'implementazione è simile, il codice è totalmente diverso.

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

Per usarlo, basta impostare un valore su SESSION / GET / POST / COOKIE con il nome s .

Risultato dell'esecuzione di questa funzione, sulla frase di prova:

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

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.