Создать текст радуги


22

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

изображение радуги

Ввод, вывод

На входе будет строка, содержащая только печатные символы ASCII. Первый или последний символы никогда не будут пробелами, и никогда не будет двух пробелов подряд. Он всегда будет длиной не менее двух символов.

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

преобразование

Чтобы определить, каким цветом должна стать каждая буква в строке, используйте следующий алгоритм. Обратите внимание, что каждая буква имеет свой индивидуальный цвет . Это не градиент!

  • Если этот символ пробел:

    • ... это не имеет значения, потому что пространства не могут ... иметь цвет в любом случае. Просто выведите пробел.
  • Иначе:

    • Let i= индекс этого символа в строке (на основе 0, так что для самой первой буквы это 0), не считая пробелов. Например, в строке foo barэто значение будет 4для a. Другими словами, это то, сколько непробелов было встречено до сих пор.

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

правила

  • При вычислении значения оттенка буквы вы почти наверняка получите десятичное (нецелое) число. Вы можете округлить это до ближайшего целого числа, поставить пол, взять потолок или просто не округлить вообще.

  • Размер шрифта должен быть читабельным. Здесь это определяется как размер шрифта 10pt или больше.

  • Вы можете использовать холст фиксированной ширины или «область рисования» для вывода текста, но он должен уметь соответствовать примеру, приведенному в самом первом предложении этого поста.

  • Подсчет очков - это , поэтому победит самый короткий код в байтах.


Может ли вывод быть URI данных? Это вывод из холста HTML
Downgoat

@vihan Да, это соответствует правилу « Вывод может быть в виде изображения (сохранен в файл или как-то иначе доступен) ».
Дверная ручка

Как вы определяете, соответствует ли окраска спецификации? Можете ли вы точно указать, какую формулу преобразования следует использовать, если в языке поддерживаются только цвета RGB? Кроме того, сколько бит точности на канал необходимо? Предположительно 8 будет в порядке, но как насчет 4 или 1?
feersum

@feersum Для преобразования в RGB вы можете использовать встроенный или один из методов, описанных здесь . Не могли бы вы уточнить, что вы подразумеваете под своим вторым вопросом? Вы спрашиваете об этом конкретно в контексте преобразования HSL в RGB или вообще?
Дверная ручка

2
Черт, я даже не собираюсь пробовать PowerShell ... Вы получаете только 16 цветов для игры (и они даже не упорядочены ... радуга или RGB или что-то еще ... просто произвольное шестнадцатеричное значение). Ссылка, с картинками Действительно крутой вызов, хотя!
AdmBorkBork

Ответы:


12

Perl, 95

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

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

Эта реализация включает в себя непечатные символы! Украл @ 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

Обратитесь к hexdump, скопировав приведенный выше текст и запустив:

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

Это производит вывод как:

ТЕПЕРЬ ВАШ ТЕРМИНАЛ КРАСНЫЙ!  MUHAHAHAHA!


10

Python 2: 240 с использованием PIL и 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()

Пример вывода:

Пример вывода текста радуги тест с пробелами

Спасибо @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 больше символов.
agtoever

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

1
Также: заменить float(j)на1.*j
agtoever

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:
Эддисон Крамп

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%. Затем список был отсортирован, поэтому правильные оттенки отображались первыми.

Принимает ввод из стандартного ввода и возвращает его в стандартный вывод.

Ваш терминал, который вы используете, ДОЛЖЕН поддерживать управляющие коды ANSI для правильной работы.

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

Литеральный hexdump:

783d696e70757428293b753d277c82888e6a46222324251f1913375b7f7e7d273b6a3d300a666f72206920696e20783a7072696e7428271b5b33383b353b25646d25732725286f726428755b286a2a3138292f2f6c656e28782e7265706c616365282220222c20222229295d292c69292c656e643d2222293b6a2b3d69213d2220220a

Спасибо @swstephe за сохранение 9 байтов (а также за то, что я заметил, что мой подсчет байтов был совсем немного неправильным)!


Почему бы не заменить "\ x82" реальным символом? Я записал эту строку в файл и прочитал ее обратно в свой скрипт в двоичном виде. Вы можете заменить \ 033 необработанным escape-символом или даже \ 1f (hex). Вы объявляете «и», затем используйте его только один раз. Вы можете сохранить несколько символов, переместив их вниз в выражение. Вы можете избежать вызова 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.