Utwórz tekst tęczy

22

Wyzwanie polega na przyjęciu tekstu jako wiersza tekstu i wydrukowaniu go w ten sposób.

obraz tęczy

Wejście wyjście

Dane wejściowe będą ciągiem zawierającym tylko drukowalne znaki ASCII. Pierwsze lub ostatnie znaki nigdy nie będą spacjami i nigdy nie będzie dwóch spacji z rzędu. Zawsze będzie mieć co najmniej dwie postacie.

Twój wynik powinien być taki sam, przekonwertowany na kolory tęczy, co zostanie opisane poniżej. Wynik może być w postaci obrazu (zapisany w pliku lub w inny sposób udostępniony) lub może po prostu wyświetlić wynik na ekranie (tak jak w poniższej implementacji referencyjnej).

Konwersja

Aby ustalić, jaki kolor powinna mieć każda litera w ciągu, użyj następującego algorytmu. Pamiętaj, że każda litera ma swój indywidualny kolor . To nie jest gradient!

  • Jeśli ta postać jest spacją:

    • ... to nie ma znaczenia, ponieważ przestrzenie tak naprawdę nie mogą ... mieć koloru. Po prostu wyjmij spację.
  • Inaczej:

    • Niech i= indeks tego znaku w ciągu (oparty na 0, więc dla pierwszej litery to jest 0), nie licząc spacji. Na przykład w ciągu foo barta wartość będzie 4dla a. Innymi słowy, tak wiele napotkano do tej pory spacji.

    • Niech n= liczba spacji w ciągu.

    • Kolor tej litery można teraz wyrazić w układzie współrzędnych cylindrycznych HSL jako [odcień = ( i/ n) * 360 °, nasycenie = 100%, jasność = 50%].

Zauważ, że te kierunki sugerują, że dane wyjściowe dla fooi f oopowinny być dokładnie takie same, z wyjątkiem dodanej spacji po f. Oznacza to, że wszystkie litery powinny zachować te same kolory.

Dalsze zasady dotyczące procesu konwersji opisano poniżej w sekcji Reguły .

Realizacja referencyjna

Jest to napisane w JavaScript i możesz spróbować, naciskając przycisk „Uruchom fragment kodu”.

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

Zasady

  • Podczas obliczania wartości Barwy litery prawie na pewno otrzymasz liczbę dziesiętną (niecałkowitą). Możesz zaokrąglić to do najbliższej liczby całkowitej, umieścić ją na podłodze, wziąć sufit lub po prostu w ogóle nie zaokrąglić.

  • Rozmiar czcionki musi być czytelny. Tutaj jest to definiowane jako czcionka o rozmiarze 10pt lub większa.

  • Do wydrukowania tekstu możesz użyć płótna o stałej szerokości lub „obszaru rysowania”, ale musi on pasować do przykładu podanego w pierwszym zdaniu tego wpisu.

  • Punktacja to , więc wygra najkrótszy kod w bajtach.

Klamka
źródło
Czy dane wyjściowe mogą być identyfikatorem URI danych? To jest wynik z kanwy HTML
Downgoat
@vihan Tak, to kwalifikuje się zgodnie z regułą „ Dane wyjściowe mogą być w formie obrazu (zapisane w pliku lub w inny sposób udostępnione w inny sposób) ”.
Klamka
Jak ustalić, czy podbarwienie spełnia specyfikację? Czy możesz dokładnie określić, jakiej formuły konwersji należy użyć, jeśli w danym języku obsługiwane są tylko kolory RGB? Ile bitów precyzji na kanał jest niezbędnych? Przypuszczalnie 8 byłoby OK, ale co powiesz na 4 lub 1?
feersum
@feersum Aby przekonwertować na RGB, możesz użyć wbudowanego lub jednej z opisanych tutaj metod . Czy możesz wyjaśnić, co rozumiesz przez swoje drugie pytanie? Czy pytasz o to konkretnie w kontekście konwersji HSL na RGB, czy ogólnie?
Klamka
2
Dang, nawet nie zamierzam wypróbować PowerShell ... Dostajesz tylko 16 kolorów do zabawy (i nie są nawet uporządkowane ... tęcza, RGB lub w inny sposób ... tylko dowolna wartość szesnastkowa). Referencje ze zdjęciami Naprawdę fajne wyzwanie!
AdmBorkBork

Odpowiedzi:

12

Perl, 95

Kod 92 bajty + 3 dla -p

Ten skrypt używa aproksymacji kolorów dostępnych dla terminala (maksymalnie 256), obecnie obejmując tylko kilka punktów kolorów wybranych z tej listy , więc prawdopodobnie nie jest określony, ale i tak było fajnie! I filtrowany listę, aby tylko pokazać kolory z Soraz Lwartości 100%i 50%odpowiednio, następnie sortowane przez odcień, zapakowane numery na sznurku i wybrać kolory z tej listy.

Ta implementacja zawiera znaki niedrukowalne! Pomysł Stole @ edc65 polegający na zamianie tylko \Szamiast ., prosty, ale sprytny!

@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

Odwróć zrzut heksowy, kopiując powyższy tekst i uruchamiając:

xxd -r > rainbowtext.pl

wklejenie danych i naciśnięcie Ctrl+ D.

Uruchom używając:

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

Wytwarza dane wyjściowe takie jak:

TERAZ TEKST TERMINALU JEST CZERWONY!  MUHAHAHAHA!

Dom Hastings
źródło
10

Python 2: 240 przy użyciu PIL i 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()

Przykładowe dane wyjściowe:

Przykład wyjściowego tekstu tęczy test ze spacjami

Podziękowania dla @agtoever i @Trang Oul za wskazówki dotyczące gry w golfa oraz @Mauris za wskazanie wymagań dotyczących miejsca.

Aby dodać czcionki typu true, należy kontrolować rozmiar czcionki, w tym przesunięcie w poziomie i zmianę koloru w zależności od długości.

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

Czcionka, której użyłem, jest dostępna tutaj : Rezultat jest następujący (góra drukuje tylko ciąg, a poniższa drukuje na literę):

maszyna do pisania

Willem
źródło
1
Rzuć as Pi wypisz PILdwa razy i wygraj jedną postać. Zmień imgsię ii wygraj 4 kolejne postacie.
agtoever
1
Zapisz 255w zmiennej, zamień wszystkie okazje i użyj (a,)*3jako białego koloru. Zastąp float(j)przez (j+.0).
Trang Oul,
1
Również: zamień float(j)na1.*j
agtoever
1
Przypisz wiele zmiennych jednocześnie (np. u=len(s) a=255=> u,a=len(s),255). Usuń []nawiasy klamrowe tuple, nie są potrzebne. Zastąp pętlę zrozumieniem listy (metoda zostanie oceniona jako efekt uboczny).
Trang Oul,
1
@willem: Spójrz na specyfikację problemu (w obszarze Konwersja ); szczegółowo wyjaśnia, jak twój program powinien obsługiwać spacje.
Lynn,
5

JavaScript (ES6), 114 117 125

Edytuj2 3 bajty zapisane dzięki @Dom Hastings Edytuj Nieprawidłowy HTML, ale i tak działa.

Zwykła uwaga: przetestuj fragment kodu w przeglądarce zgodnej z EcmaScript 6 (w szczególności nie Chrome, a nie MSIE. Testowałem na 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
źródło
1
Żadna przeglądarka nie jest jeszcze w pełni zgodna z ES6. IE nie jest jeszcze w pełni zgodny z ES5!
SuperJedi224,
@ SuperJedi224 Zgadzam się. Mówię tylko: nie próbuj z Chrome lub MSIE, podczas korzystania z Firefoxa działa
edc65
Wydaje mi się, że nie powinienem nawet nic mówić, ponieważ właśnie dostałem moje pod twoje, ale myślę, że możesz pominąć deklarację )po, hsl(ponieważ wydaje się, że nadal działa dla mnie w przeglądarce Firefox!
Dom Hastings,
Możesz także zmienić, ${c}'aby '+czaoszczędzić jeszcze 2 ... Lepiej wróć do mnie!
Dom Hastings,
To nie działa w przeglądarce Safari 9.0. c:
Addison Crump,
4

Python 3, 131 bajtów

Podobnie do odpowiedzi Dom Hastings, ale zaimplementowany w pythonie.

Ciąg '|\x82\x88\x8ejF"#$%\x1f\x19\x137[\x7f~}'został zbudowany z listy, która [124,130,136,142,106,70,34,35,36,37,31,25,19,55,91,127,126,125]zawiera kody kolorów terminali, które mają być wyświetlane w kolejności. Zostały przefiltrowane, więc zawierają tylko kolory o nasyceniu 100% i wartości 50%. Lista została następnie posortowana, więc najpierw wyświetlane były prawidłowe barwy.

Pobiera dane wejściowe ze standardowego wejścia i zwraca je do standardowego wejścia.

Twój terminal, którego używasz MUSI obsługiwać kody ucieczki ANSI, aby poprawnie to uruchomić.

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

Lub wersja skrócona ze znakami bajtów dosłownych (niepoprawnie wklejona):

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

Dosłowny zrzut heksowy:

783d696e70757428293b753d277c82888e6a46222324251f1913375b7f7e7d273b6a3d300a666f72206920696e20783a7072696e7428271b5b33383b353b25646d25732725286f726428755b286a2a3138292f2f6c656e28782e7265706c616365282220222c20222229295d292c69292c656e643d2222293b6a2b3d69213d2220220a

Dzięki @swstephe za uratowanie 9 bajtów (i również powiadomienie mnie, że moje liczenie bajtów było bardzo nieznacznie bardzo błędne)!

niebieski
źródło
Dlaczego nie zastąpić „\ x82” faktycznym znakiem? Napisałem ten ciąg do pliku i wczytałem go z powrotem do binarnego skryptu. Możesz zastąpić \ 033 surowym znakiem ucieczki, a nawet \ 1f (hex). Deklarujesz „u”, a następnie użyj go tylko raz. Możesz zapisać kilka znaków, przesuwając go w dół do wyrażenia. Możesz uniknąć wywołania int (), używając „//” do podziału liczb całkowitych.
swstephe
Ups, \ 033 jest taki sam jak \ x1f.
swstephe
2

PHP, 165 bajtów

Uruchom z wejściem jako parametrem „s”

HTML jest nieprawidłowy, ale powinien się wyświetlać we wszystkich głównych przeglądarkach (testowane w Chrome i 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
źródło
1

PHP 4.1, 112 103 102 bajty

Użyłem odpowiedź @DankMemes' jako punkt wyjścia. Odtąd wprowadziłem mnóstwo zmian, do tego stopnia, że ​​kod jest inny.

Implementacja jest podobna, kod jest zupełnie inny.

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

Aby go użyć, po prostu ustaw wartość w SESSION / GET / POST / COOKIE o nazwie s.

Wynik uruchomienia tej funkcji w zdaniu testowym:

<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
źródło