Regenbogentext erstellen

22

Ihre Herausforderung besteht darin, die Eingabe als Textzeile zu verstehen und so auszugeben.

Regenbogenbild

Input-Output

Die Eingabe ist eine Zeichenfolge, die nur druckbare ASCII-Zeichen enthält. Das erste oder letzte Zeichen wird niemals ein Leerzeichen sein, und es wird niemals zwei Leerzeichen in einer Reihe geben. Es wird immer mindestens zwei Zeichen lang sein.

Ihre Ausgabe sollte dieselbe Zeichenfolge sein, die in Regenbogenfarben konvertiert wurde, wie nachfolgend beschrieben wird. Die Ausgabe kann in Bildform erfolgen (in einer Datei gespeichert oder auf andere Weise verfügbar gemacht), oder sie zeigt das Ergebnis einfach auf dem Bildschirm an (wie in der folgenden Referenzimplementierung).

Umwandlung

Verwenden Sie den folgenden Algorithmus, um zu bestimmen, welche Farbe jeder Buchstabe in der Zeichenfolge haben soll. Beachten Sie, dass jeder Buchstabe eine eigene Farbe hat . Dies ist kein Farbverlauf!

  • Wenn dieses Zeichen ein Leerzeichen ist:

    • ... spielt keine Rolle, da Leerzeichen sowieso keine Farbe haben können. Gib einfach ein Leerzeichen aus.
  • Andernfalls:

    • Let i= der Index dieses Zeichens in der Zeichenfolge (0-basiert, also für den allerersten Buchstaben 0), ohne Leerzeichen. In der Zeichenfolge foo barwäre dieser Wert beispielsweise 4für die a. Mit anderen Worten, so viele Nicht-Leerzeichen wurden bisher angetroffen.

    • Let n= Die Anzahl der Nicht-Leerzeichen in der Zeichenfolge.

    • Die Farbe dieses Buchstabens kann nun im HSL-Zylinderkoordinatensystem ausgedrückt werden als [Farbton = ( i/ n) * 360 °, Sättigung = 100%, Helligkeit = 50%].

Beachten Sie, dass diese Richtungen implizieren, dass die Ausgabe für foound f oogenau gleich sein sollte, mit Ausnahme eines zusätzlichen Leerzeichens nach dem f. Das heißt, alle Buchstaben sollten die gleichen Farben behalten.

Weitere Regeln für den Konvertierungsprozess werden unten im Abschnitt Regeln beschrieben .

Referenzimplementierung

Dies ist in JavaScript geschrieben, und Sie können es versuchen, indem Sie auf die Schaltfläche "Code-Snippet ausführen" klicken.

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

Regeln

  • Wenn Sie den Farbtonwert eines Buchstabens berechnen, erhalten Sie mit ziemlicher Sicherheit eine Dezimalzahl (keine Ganzzahl). Sie können dies auf die nächste ganze Zahl runden, auf den Boden legen, die Decke nehmen oder einfach gar nicht runden.

  • Die Schriftgröße muss lesbar sein. Hier wird dies als Schriftgröße von 10pt oder mehr definiert.

  • Sie können eine Leinwand mit fester Breite oder einen "Zeichenbereich" verwenden, um den Text auszugeben, aber er muss in der Lage sein, dem im allerersten Satz dieses Beitrags angegebenen Beispiel zu entsprechen.

  • Das Scoring ist , also gewinnt der kürzeste Code in Bytes.

Türknauf
quelle
Kann die Ausgabe eine Daten-URI sein? Das ist die Ausgabe von der HTML-
Zeichenfläche
@vihan Ja, das entspricht der Regel " Die Ausgabe kann in Bildform erfolgen (in einer Datei gespeichert oder auf andere Weise verfügbar gemacht) ".
Türklinke
Wie stellen Sie fest, ob eine Färbung der Spezifikation entspricht? Können Sie genau angeben, welche Umrechnungsformel verwendet werden soll, wenn in einer Sprache nur RGB-Farben unterstützt werden? Wie viele Bits Genauigkeit pro Kanal sind außerdem erforderlich? Vermutlich wäre 8 in Ordnung, aber wie wäre es mit 4 oder 1?
Feersum
@feersum Zum Konvertieren in RGB können Sie eine integrierte oder eine der hier beschriebenen Methoden verwenden . Können Sie klarstellen, was Sie mit Ihrer zweiten Frage meinen? Fragen Sie dies speziell im Zusammenhang mit der Konvertierung von HSL in RGB oder allgemein?
Türklinke
2
Verdammt, ich werde es nicht einmal mit PowerShell versuchen ... Sie haben nur 16 Farben zum Spielen (und sie sind nicht einmal bestellt ... Regenbogen oder RGB oder sonstwie ... nur ein beliebiger Hex-Wert). Hinweis, mit Bildern Wirklich coole Herausforderung!
AdmBorkBork

Antworten:

12

Perl, 95

92 Byte Code + 3 für -p

Dieses Skript verwendet eine Annäherung der für das Terminal verfügbaren Farben (maximal 256), wobei derzeit nur einige Farbpunkte aus dieser Liste ausgewählt werden. Es wird also wahrscheinlich nicht spezifiziert, aber das hat trotzdem Spaß gemacht! Ich habe die Liste gefiltert, um nur Farben mit Sund LWerten von 100%bzw. 50%anzuzeigen, dann nach Farbton sortiert, die Zahlen in eine Zeichenfolge gepackt und die Farben aus dieser Liste ausgewählt.

Diese Implementierung enthält nicht druckbare Zeichen! Die Idee von Stole @ edc65 , nur zu ersetzen, \Sstatt ., einfach, aber clever!

@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

Kehren Sie den Hexdump um, indem Sie den obigen Text kopieren und ausführen:

xxd -r > rainbowtext.pl

Einfügen der Daten und Drücken von Ctrl+ D.

Ausführen mit:

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

Es erzeugt eine Ausgabe wie:

JETZT IST IHR TERMINALTEXT ROT!  MUHAHAHAHA!

Dom Hastings
quelle
10

Python 2: 240 mit PIL und 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()

Beispielausgabe:

Beispiel für die Ausgabe eines Regenbogentexts Test mit Leerzeichen

Vielen Dank an @agtoever und @Trang Oul für einige Golftipps und an @Mauris für den Hinweis auf den Platzbedarf.

Zum Hinzufügen von True Type-Schriftarten können Sie die Schriftgröße steuern, einschließlich des horizontalen Versatzes und der Farbänderung basierend auf der Länge.

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

Die Schriftart I verwendet wird , ist aus verfügbar hier : Das Ergebnis ist (die obere nur die Zeichenfolge gedruckt wird , unter die man Druck pro Brief):

Schreibmaschine

Willem
quelle
1
Lass es fallen as Pund schreib es PILzweimal auf und gewinne einen Charakter. Wechsle imgzu iund gewinne 4 weitere Charaktere.
Am
1
In 255einer Variablen speichern , alle Vorkommen ersetzen und (a,)*3als weiße Farbe verwenden. Ersetzen float(j)durch (j+.0).
Trang Oul
1
Auch: ersetzen float(j)zu1.*j
agtoever
1
Weisen Sie mehrere Variablen gleichzeitig zu (z . B. u=len(s) a=255=> u,a=len(s),255). Entfernen Sie die []Klammern von tuple, sie werden nicht benötigt. Schleife durch Listenverständnis ersetzen (Methode wird als Nebeneffekt gewertet).
Trang Oul
1
@willem: Schauen Sie sich die Problembeschreibung an (unter Konvertierung ); Es wird speziell erklärt, wie Ihr Programm mit Leerzeichen umgehen soll.
Lynn
5

JavaScript (ES6), 114 117 125

Edit2 3 Bytes gespeichert dank @Dom Hastings Edit Ungültiges HTML, aber es funktioniert trotzdem.

Üblicher Hinweis: Testen Sie die Ausführung des Snippets in einem EcmaScript 6-kompatiblen Browser (insbesondere nicht in Chrome, nicht in MSIE. Ich habe es in Firefox getestet).

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
quelle
1
Noch ist kein Browser vollständig ES6-kompatibel. IE ist noch nicht einmal vollständig ES5-konform!
SuperJedi224
@ SuperJedi224 da stimme ich zu. Ich sage nur: Versuchen Sie es nicht mit Chrome oder MSIE, während Firefox funktioniert
edc65
Ich habe das Gefühl, ich sollte nicht einmal etwas sagen, weil ich nur meine unter deiner habe, aber ich denke, du kannst die )nach deiner hsl(Erklärung weglassen, da das in Firefox immer noch für mich zu funktionieren scheint!
Dom Hastings
Sie können auch ändern ${c}', '+cum 2 weitere zu sparen ... Machen Sie besser mit meinen weiter!
Dom Hastings
Dies funktioniert nicht mit Safari 9.0. c:
Addison Crump
4

Python 3, 131 Bytes

Ähnlich der Antwort von Dom Hastings, aber in Python implementiert.

Die Zeichenfolge '|\x82\x88\x8ejF"#$%\x1f\x19\x137[\x7f~}'wurde aus der Liste [124,130,136,142,106,70,34,35,36,37,31,25,19,55,91,127,126,125]der Terminal-Farbcodes erstellt, die in der angegebenen Reihenfolge angezeigt werden sollen. Sie wurden gefiltert, sodass nur Farben mit einer Sättigung von 100% und einem Wert von 50% enthalten sind. Die Liste wurde dann sortiert, sodass zuerst die richtigen Farbtöne angezeigt wurden.

Übernimmt die Eingabe von stdin und gibt sie an stdout zurück.

Ihr Terminal, das Sie verwenden, MUSS ANSI-Escape-Codes unterstützen, um dies ordnungsgemäß auszuführen.

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

Oder verkürzte Version mit Literalbyte-Zeichen (wurde nicht richtig eingefügt):

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

Literal Hexdump:

783d696e70757428293b753d277c82888e6a46222324251f1913375b7f7e7d273b6a3d300a666f72206920696e20783a7072696e7428271b5b33383b353b25646d25732725286f726428755b286a2a3138292f2f6c656e28782e7265706c616365282220222c20222229295d292c69292c656e643d2222293b6a2b3d69213d2220220a

Vielen Dank an @swstephe, dass du 9 Bytes gespart hast (und mir auch aufgefallen ist, dass meine Byteanzählung etwas falsch war)!

Blau
quelle
Warum nicht "\ x82" durch das eigentliche Zeichen ersetzen? Ich habe diesen String in eine Datei geschrieben und ihn binär in mein Skript zurückgelesen. Sie können \ 033 durch ein Escape-Zeichen oder sogar \ 1f (hex) ersetzen. Sie deklarieren "u" und verwenden es dann nur einmal. Sie können einige Zeichen speichern, indem Sie sie nach unten in den Ausdruck verschieben. Sie können den Aufruf von int () vermeiden, indem Sie "//" für die Ganzzahldivision verwenden.
swstephe
Hoppla, \ 033 ist dasselbe wie \ x1f.
swstephe
2

PHP, 165 Bytes

Mit Eingabe als Parameter "s" ausführen

Der HTML-Code ist ungültig, sollte jedoch in allen gängigen Browsern dargestellt werden (getestet in Chrome und 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
quelle
1

PHP 4.1, 112 103 102 Bytes

Ich habe die Antwort von @DankMemes als Ausgangspunkt verwendet. Von da an habe ich eine Menge Änderungen vorgenommen, bis zu dem Punkt, dass der Code anders ist.

Die Implementierung ist ähnlich, der Code ist völlig anders.

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

Um es zu benutzen, setzen Sie einfach einen Wert auf ein SESSION / GET / POST / COOKIE mit dem Namen s.

Ergebnis der Ausführung dieser Funktion für den Testsatz:

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