Tạo văn bản cầu vồng


22

Thách thức của bạn là lấy đầu vào là một dòng văn bản và xuất nó như thế này.

hình ảnh cầu vồng

Đầu ra đầu vào

Đầu vào sẽ là một chuỗi chỉ chứa các ký tự ASCII có thể in được. Các ký tự đầu tiên hoặc cuối cùng sẽ không bao giờ là khoảng trắng và sẽ không bao giờ có hai khoảng trắng liên tiếp. Nó sẽ luôn dài ít nhất hai ký tự.

Đầu ra của bạn phải là cùng một chuỗi, được chuyển đổi thành màu cầu vồng như được mô tả bên dưới. Đầu ra có thể ở dạng hình ảnh (được lưu vào một tệp hoặc bằng cách nào đó có sẵn) hoặc đơn giản là nó có thể hiển thị kết quả trên màn hình (như cách thực hiện tham chiếu bên dưới).

Chuyển đổi

Để xác định màu nào mỗi chữ cái trong chuỗi sẽ trở thành, sử dụng thuật toán sau. Lưu ý rằng mỗi chữ cái là màu riêng của nó . Đây không phải là một gradient!

  • Nếu nhân vật này là một khoảng trắng:

    • ... không thành vấn đề, bởi vì không gian thực sự không thể ... có màu. Đơn giản chỉ cần xuất ra một không gian.
  • Nếu không thì:

    • Đặt i= chỉ mục của ký tự này trong chuỗi (dựa trên 0, vì vậy đối với chữ cái đầu tiên, đây là 0), không tính khoảng trắng. Ví dụ: trong chuỗi foo bar, giá trị này sẽ 4dành cho a. Nói cách khác, đây là cách mà nhiều không gian đã gặp phải cho đến nay.

    • Đặt n= số lượng khoảng trắng trong chuỗi.

    • Màu sắc của chữ cái này hiện có thể được thể hiện, trong hệ tọa độ hình trụ HSL , như [hue = ( i/ n) * 360 °, bão hòa = 100%, độ sáng = 50%].

Lưu ý rằng các hướng này ngụ ý rằng đầu ra cho foof oophải giống hệt nhau, ngoại trừ một không gian được thêm vào sau f. Đó là, tất cả các chữ cái nên giữ lại màu sắc giống nhau.

Các quy tắc khác cho quy trình chuyển đổi được mô tả bên dưới, trong phần Quy tắc .

Thực hiện tham khảo

Điều này được viết bằng JavaScript và bạn có thể thử nó bằng cách nhấn nút "Chạy đoạn mã".

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

Quy tắc

  • Khi tính toán giá trị Hue của một chữ cái, bạn gần như chắc chắn sẽ nhận được một số thập phân (không nguyên). Bạn có thể làm tròn số này đến số nguyên gần nhất, đặt sàn, lấy trần hoặc đơn giản là không làm tròn số nào cả.

  • Kích thước phông chữ phải có thể đọc được. Ở đây, đây được định nghĩa là phông chữ kích thước 10pt hoặc lớn hơn.

  • Bạn có thể sử dụng khung vẽ có chiều rộng cố định hoặc "vùng vẽ" để xuất văn bản, nhưng nó phải có thể phù hợp với ví dụ được đưa ra trong câu đầu tiên của bài đăng này.

  • Ghi điểm là , vì vậy mã ngắn nhất tính bằng byte sẽ giành chiến thắng.


Đầu ra có thể là URI dữ liệu không? Đó là đầu ra từ khung vẽ HTML
Downgoat

@vihan Có, đủ điều kiện theo quy tắc " Đầu ra có thể ở dạng hình ảnh (được lưu vào một tệp hoặc bằng cách nào đó có sẵn) ".
Doorknob

Làm thế nào để bạn xác định xem một màu sắc đáp ứng thông số kỹ thuật? Bạn có thể chỉ định chính xác công thức chuyển đổi nào nên sử dụng nếu chỉ hỗ trợ màu RGB trong ngôn ngữ không? Ngoài ra, cần bao nhiêu bit chính xác cho mỗi kênh? Có lẽ 8 sẽ ổn, nhưng 4, hoặc 1 thì sao?
frageum

@feersum Để chuyển đổi sang RGB, bạn có thể sử dụng nội dung dựng sẵn hoặc một trong các phương pháp được mô tả ở đây . Bạn có thể làm rõ những gì bạn có ý nghĩa bởi câu hỏi thứ hai của bạn? Bạn đang hỏi về điều này cụ thể trong bối cảnh chuyển đổi HSL sang RGB, hay nói chung?
Doorknob

2
Dang, tôi thậm chí sẽ không thử với PowerShell ... Bạn chỉ có 16 màu để chơi (và chúng thậm chí không được đặt hàng ... cầu vồng hoặc RGB hoặc nói cách khác ... chỉ là một giá trị hex tùy ý). Tham khảo, với hình ảnh thử thách thực sự mát mẻ, mặc dù!
admBorkBork

Câu trả lời:


12

Perl, 95

Mã 92 byte + 3 cho -p

Tập lệnh này sử dụng xấp xỉ các màu có sẵn cho thiết bị đầu cuối (tối đa 256) hiện chỉ bao gồm một vài điểm màu được chọn từ danh sách này , do đó có thể không chỉ định, nhưng dù sao thì điều này cũng rất vui! Tôi lọc danh sách để chỉ hiển thị màu sắc với SLgiá trị của 100%50%tương ứng, sau đó sắp xếp theo màu sắc, đóng gói các con số vào một chuỗi và chọn màu từ danh sách đó.

Việc thực hiện này bao gồm các ký tự không in được! Lấy trộm @ edc65 ý tưởng 's chỉ thay thế \Sthay vì ., đơn giản, nhưng thông minh!

@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

Đảo ngược hexdump bằng cách sao chép văn bản trên và chạy:

xxd -r > rainbowtext.pl

dán vào dữ liệu và nhấn Ctrl+ D.

Chạy bằng cách sử dụng:

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

Nó tạo ra đầu ra như:

NGAY BÂY GIỜ VĂN BẢN CỦA BẠN LÀ ĐỎ!  MUHAHAHAHA!


10

Python 2: 240 sử dụng PIL và 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()

Ví dụ đầu ra:

Ví dụ văn bản cầu vồng đầu ra kiểm tra với không gian

Cảm ơn @agtoever và @Trang Oul về một số mẹo chơi gôn và @Mauris đã chỉ ra yêu cầu về không gian.

Để thêm phông chữ đúng, kiểm soát kích thước phông chữ, bao gồm bù ngang và thay đổi màu dựa trên chiều dài.

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

Phông chữ tôi sử dụng có sẵn từ đây : Kết quả là (trên cùng chỉ là in chuỗi, cái bên dưới là in trên mỗi chữ cái):

máy đánh chữ


1
Thả as Pvà viết ra PILhai lần và giành được một nhân vật. Thay đổi imgđể ivà giành chiến thắng 4 ký tự hơn.
bất cứ lúc nào

1
Lưu 255vào một biến, thay thế tất cả các ocurrences và sử dụng (a,)*3như màu trắng. Thay thế float(j)bằng (j+.0).
Trang Oul

1
Ngoài ra: thay thế float(j)thành1.*j
bất cứ lúc nào

1
Gán nhiều biến đồng thời (ví dụ u=len(s) a=255=> u,a=len(s),255). Xóa []dấu ngoặc khỏi tuple, chúng không cần thiết. Thay thế vòng lặp bằng cách hiểu danh sách (phương pháp sẽ được đánh giá là tác dụng phụ).
Trang Oul

1
@willem: Hãy xem đặc tả vấn đề (bên dưới Chuyển đổi ); nó đặc biệt giải thích cách chương trình của bạn nên xử lý các không gian.
Lynn

5

JavaScript (ES6), 114 117 125

Edit2 3 byte đã lưu thx @Dom Hastings Chỉnh sửa HTML không hợp lệ, nhưng dù sao cũng hoạt động.

Lưu ý thông thường: kiểm tra chạy đoạn mã trên trình duyệt tuân thủ EcmaScript 6 (đáng chú ý không phải Chrome không phải MSIE. Tôi đã thử nghiệm trên 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
Không có trình duyệt nào hoàn toàn tuân thủ ES6. IE thậm chí chưa hoàn toàn tuân thủ ES5!
SuperJedi224

@ SuperJedi224 Tôi đồng ý. Tôi chỉ nói: đừng thử với Chrome hoặc MSIE, trong khi sử dụng Firefox thì nó hoạt động
edc65

Tôi cảm thấy mình thậm chí không nên nói bất cứ điều gì vì tôi chỉ nhận được của tôi, nhưng tôi nghĩ bạn có thể bỏ qua phần khai báo )của mình hsl(vì điều đó dường như vẫn hoạt động với tôi trong Firefox!
Dom Hastings

Ngoài ra, bạn có thể thay đổi ${c}'để '+ctiết kiệm thêm 2 ... Tốt hơn hãy quay lại với tôi!
Dom Hastings

Điều này không hoạt động trên Safari 9.0. c:
Addison Crump

4

Python 3, 131 byte

Simular theo câu trả lời của Dom Hastings nhưng được thực hiện bằng python.

Chuỗi '|\x82\x88\x8ejF"#$%\x1f\x19\x137[\x7f~}'được xây dựng dưới dạng danh sách [124,130,136,142,106,70,34,35,36,37,31,25,19,55,91,127,126,125]là mã màu đầu cuối để hiển thị theo thứ tự. Chúng đã được lọc để chúng chỉ bao gồm các màu có độ bão hòa 100% và giá trị 50%. Danh sách sau đó được sắp xếp để màu sắc chính xác được hiển thị đầu tiên.

Lấy đầu vào từ stdin và trả nó về thiết bị xuất chuẩn.

Thiết bị đầu cuối của bạn, bạn đang sử dụng PHẢI hỗ trợ mã thoát ANSI để chạy mã này đúng cách.

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

Hoặc phiên bản rút gọn với các ký tự byte bằng chữ (Không dán đúng cách):

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

Chữ viết tắt:

783d696e70757428293b753d277c82888e6a46222324251f1913375b7f7e7d273b6a3d300a666f72206920696e20783a7072696e7428271b5b33383b353b25646d25732725286f726428755b286a2a3138292f2f6c656e28782e7265706c616365282220222c20222229295d292c69292c656e643d2222293b6a2b3d69213d2220220a

Cảm ơn @swstephe vì đã lưu 9 byte (và cũng khiến tôi nhận thấy việc đếm byte của tôi đã từng rất sai)!


Tại sao không thay thế "\ x82" bằng ký tự thực tế? Tôi đã viết chuỗi đó vào một tệp và đọc lại thành tập lệnh của mình ở dạng nhị phân. Bạn có thể thay thế \ 033 bằng ký tự thoát thô hoặc thậm chí \ 1f (hex). Bạn khai báo "u", sau đó chỉ sử dụng một lần. Bạn có thể lưu một vài ký tự bằng cách di chuyển nó xuống biểu thức. Bạn có thể tránh cuộc gọi int () bằng cách sử dụng "//" để chia số nguyên.
bước vào

Rất tiếc, \ 033 giống với \ x1f.
bước vào

2

PHP, 165 byte

Chạy với đầu vào là tham số "s"

HTML không hợp lệ nhưng nó sẽ hiển thị trong tất cả các trình duyệt chính (đã được thử nghiệm trong Chrome và 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

Tôi đã sử dụng câu trả lời của @DankMeme làm điểm bắt đầu. Từ đó trở đi, tôi đã thực hiện một tấn các thay đổi, đến mức mà mã là khác nhau.

Việc thực hiện là tương tự, mã là hoàn toàn khác nhau.

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

Để sử dụng nó, chỉ cần đặt một giá trị trên SESSION / GET / POST / COOKIE với tên s.

Kết quả của việc chạy chức năng này, trên câu kiểm tra:

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

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.