Створіть текст веселки


22

Ваша задача полягає в тому, щоб сприйняти текст як рядок тексту та видати його таким чином.

зображення веселки

Введення-виведення

Введенням буде рядок, що містить лише символи для друку ASCII. Перший або останній символи ніколи не будуть пробілами, і ніколи не буде двох пробілів поспіль. Це завжди буде не менше двох символів.

Вихід повинен бути тим самим рядком, перетвореним у кольори веселки, як буде описано нижче. Вихід може бути у формі зображення (зберігається у файлі чи якимось іншим чином доступний), або він може просто відображати результат на екрані (як це робиться в нижченаведеній реалізації).

Перетворення

Щоб визначити, яким кольором має стати кожна літера в рядку, скористайтеся наступним алгоритмом. Зауважте, що кожна літера має свій індивідуальний колір . Це не градієнт!

  • Якщо цей символ є пробілом:

    • ... це не має значення, оскільки простори не можуть насправді ... мати колір все одно. Просто виведіть пробіл.
  • Інакше:

    • Нехай i= індекс цього символу в рядку (на основі 0, тому для першої літери це 0), не рахуючи пробілів. Наприклад, у рядку foo barце значення буде 4для a. Іншими словами, саме стільки непросторів зустрічалося досі.

    • Нехай n= кількість не пропусків у рядку.

    • Колір цього листа тепер може бути виражений у циліндрично-координатній системі HSL як [hue = ( i/ n) * 360 °, насиченість = 100%, легкість = 50%].

Зауважте, що ці вказівки означають, що результат для fooта f ooповинен бути абсолютно однаковим, за винятком додаткового простору після f. Тобто всі літери повинні зберігати однакові кольори.

Подальші правила процесу перетворення описані нижче, у розділі Правила .

Довідкова реалізація

Це написано на JavaScript, і ви можете спробувати, натиснувши кнопку «Запустити фрагмент коду».

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

Правила

  • Обчислюючи значення букви Hue, ви майже напевно отримаєте десяткове (не ціле число) число. Ви можете закруглити це до найближчого цілого числа, перекрити підлогу, взяти стелю або просто зовсім не округлити.

  • Розмір шрифту повинен бути читабельним. Тут це визначається як шрифт розміром 10 крап або більше.

  • Ви можете використовувати полотно фіксованої ширини або "зону малювання" для виведення тексту, але він повинен вміти відповідати прикладу, наведеному в першому реченні цього допису.

  • Підрахунок балів - це , тому найкоротший код у байтах виграє.


Чи може висновок бути URI даних? Ось результат із HTML-полотна
Downgoat

@vihan Так, це кваліфікується згідно з правилом "Виведення може бути у формі зображення (збережене у файл або якимось іншим чином доступне) ".
Дверна ручка

Як визначити, чи відповідає забарвлення специфікації? Чи можете ви точно вказати, яку формулу перетворення слід використовувати, якщо мовою підтримуються лише кольори RGB? Крім того, скільки біт точності на канал потрібно? Імовірно, 8 було б добре, але як щодо 4, або 1?
feersum

@feersum Для перетворення в RGB ви можете використовувати вбудований або один із описаних тут методів . Чи можете ви уточнити, що ви маєте на увазі під своїм другим запитанням? Ви питаєте про це конкретно в контексті перетворення HSL в RGB або взагалі?
Дверна ручка

2
Данг, я навіть не збираюся пробувати з PowerShell ... У вас є лише 16 кольорів, з якими можна грати (а вони навіть не замовлені ... веселка або RGB чи іншим чином ... просто довільне значення шістнадцяткової). Довідка, але зі зображеннями Дійсно класний виклик, хоча!
AdmBorkBork

Відповіді:


12

Перл, 95

92 байти код + 3 для -p

Цей сценарій використовує наближення кольорів, доступних для терміналу (максимум 256), включаючи лише кілька кольорових точок, вибраних із цього списку , так що, швидше за все, не буде специфікацій, але це все одно було цікаво! Я фільтрується список , щоб показувати тільки кольору з Sі Lзначення 100%і , 50%відповідно, потім відсортовані по відтінку, упаковане число в рядок і вибрати колір з цього списку.

Ця реалізація включає недруковані символи! Ідея Stole @ edc65 замінити лише \Sзамість .простої, але розумної!

@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

Зворотний шестикутник скасуйте, скопіювавши вищезгаданий текст і запустивши:

xxd -r > rainbowtext.pl

вставка даних і натискання Ctrl+ D.

Запустити за допомогою:

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

Це дає вихід:

СЕЙЧАС ТЕХНІЧНИЙ ТЕКСТ ЧИТАЄТЬСЯ!  МУХАХАХА!


10

Python 2: 240 за допомогою PIL та colorys 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()

Приклад виводу:

Виведіть приклад тексту веселки тест з пробілами

Дякуємо @agtoever і @Trang Oul за кілька порад щодо гольфу, а також @Mauris за вказівку на простір.

Щоб додати шрифти справжнього типу, контроль розміру шрифту, включаючи горизонтальне зміщення та зміну кольору залежно від довжини.

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

Шрифт, який я використав, доступний тут : Результат (у верхній частині - це просто друк рядка, а внизу - друк на лист):

друкарська машинка


1
Опустіть as Pі випишіть PILдвічі і виграйте один символ. Зміна imgдо iі виграти 4 більше символів.
1515

1
Збережіть 255до змінної, замініть всі явища та використовуйте (a,)*3як білий колір. Замінити float(j)на (j+.0).
Транг Оул

1
Також: замінити float(j)на1.*j
1515

1
Призначте кілька змінних одночасно (наприклад, u=len(s) a=255=> u,a=len(s),255). Знімайте []дужки tuple, вони не потрібні. Замініть цикл на розуміння списку (метод буде оцінено як побічний ефект).
Транг Оул

1
@willem: ознайомтеся зі специфікацією проблеми (під перетворенням ); він спеціально пояснює, як ваша програма повинна обробляти пробіли.
Лінн

5

JavaScript (ES6), 114 117 125

Edit2 3 байти збережено thx @Dom Hastings Редагувати недійсний HTML, але все одно працює.

Звичайна примітка: перевірка запуску фрагмента в сумісному браузері EcmaScript 6 (особливо це не Chrome, а не MSIE. Я тестував на 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
Жоден браузер не сумісний повністю з ES6. IE ще не повністю сумісний з ES5!
SuperJedi224

@ SuperJedi224 Я згоден. Я просто кажу: не спробуйте це з Chrome або MSIE, тоді як користуєтеся Firefox, це працює
edc65

Я відчуваю, що я навіть не повинен нічого говорити, тому що я тільки що мій під твоїм, але я думаю, що ти можеш пропустити )після своєї hsl(декларації, оскільки це, здається, все ще працює для мене в Firefox!
Дом Гастінгс

Крім того, ви можете змінити, ${c}'щоб '+cзберегти ще 2 ... Краще поверніться до моєї!
Дом Гастінгс

Це не працює на Safari 9.0. c:
Addison Crump

4

Python 3, 131 байт

Модуль відповіді Дома Гастінгса, але реалізований в python.

Рядок '|\x82\x88\x8ejF"#$%\x1f\x19\x137[\x7f~}'був побудований із списку [124,130,136,142,106,70,34,35,36,37,31,25,19,55,91,127,126,125]- це термінальні кодові кольори для відображення в порядку. Вони були відфільтровані, тому вони включають лише кольори з насиченістю 100% і значенням 50%. Після цього список був відсортований, щоб спочатку були відображені правильні відтінки.

Бере вхід зі stdin та повертає його до stdout.

Для правильного запуску цього терміналу ви повинні використовувати ОБОВ'ЯЗКОВІ коди аварійних відхилень.

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

Або скорочена версія з буквальними байтовими символами (Не вставлено належним чином):

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

Буквальний гексадум:

783d696e70757428293b753d277c82888e6a46222324251f1913375b7f7e7d273b6a3d300a666f72206920696e20783a7072696e7428271b5b33383b353b25646d25732725286f726428755b286a2a3138292f2f6c656e28782e7265706c616365282220222c20222229295d292c69292c656e643d2222293b6a2b3d69213d2220220a

Дякую @swstephe за збереження 9 байтів (а також змусив мене помітити, що мій підрахунок байтів колись був так злегка неправильним)!


Чому б не замінити "\ x82" фактичним символом? Я записав цей рядок у файл і прочитав його назад у своєму сценарії у двійковій формі. Ви можете замінити \ 033 необробленим символом втечі або навіть \ 1f (шістнадцятковим). Ви оголошуєте "u", а потім використовуєте лише один раз. Ви можете зберегти кілька символів, перемістивши їх у вираз. Ви можете уникнути дзвінка int (), використовуючи "//" для цілого поділу.
swstephe

ой, \ 033 те саме, що \ x1f.
swstephe

2

PHP, 165 байт

Запустити з введенням як параметр "s"

HTML-код недійсний, але він повинен відображатися у всіх основних браузерах (тестовано в Chrome та 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 байти

Я використовував відповідь @DankMemes як вихідний пункт. З цього моменту, я реалізував масу змін, до того , що код відрізняється.

Реалізація схожа, код абсолютно інший.

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

Щоб використовувати його, просто встановіть значення на SESSION / GET / POST / COOKIE з назвою s.

Результат виконання цієї функції в тестовому реченні:

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

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.