สร้างข้อความสายรุ้ง


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

กฎระเบียบ

  • เมื่อคำนวณค่าฮิวของตัวอักษรคุณจะได้ตัวเลขทศนิยม (ไม่ใช่จำนวนเต็ม) คุณอาจปัดเศษนี้เป็นจำนวนเต็มที่ใกล้ที่สุดปูพื้นเพดานหรือไม่ปัดเลยก็ได้

  • ขนาดตัวอักษรต้องอ่านได้ ที่นี่กำหนดเป็นแบบอักษรขนาด 10 พอยต์ขึ้นไป

  • คุณอาจใช้ผืนผ้าใบที่มีความกว้างคงที่หรือ "พื้นที่การวาดภาพ" เพื่อเอาท์พุทข้อความ แต่ต้องสามารถใส่ตัวอย่างที่ให้ไว้ในประโยคแรกของโพสต์นี้

  • การให้คะแนนคือดังนั้นโค้ดที่สั้นที่สุดเป็นไบต์จะเป็นผู้ชนะ


เอาต์พุตสามารถเป็น Data URI ได้หรือไม่? นั่นคือผลลัพธ์จากผ้าใบ HTML
Downgoat

@vihan ใช่ว่ามีคุณสมบัติตามกฎ " เอาต์พุตอาจอยู่ในรูปแบบภาพ (บันทึกเป็นไฟล์หรือมีให้ในลักษณะอื่น) "
Doorknob

คุณจะทราบได้อย่างไรว่าสีมีคุณสมบัติตรงตามข้อกำหนด คุณสามารถระบุได้อย่างแม่นยำว่าควรใช้สูตรการแปลงใดหากรองรับเฉพาะสี RGB ในภาษาหนึ่ง ๆ นอกจากนี้จำเป็นต้องมีความแม่นยำกี่บิตต่อช่อง สมมุติ 8 น่าจะโอเค แต่จะประมาณ 4 หรือ 1?
feersum

@feersum แปลง RGB, คุณอาจจะใช้ builtin หรือวิธีใดวิธีหนึ่งที่อธิบายไว้ที่นี่ คุณช่วยอธิบายความหมายของคำถามที่สองของคุณได้ไหม? คุณถามถึงสิ่งนี้โดยเฉพาะในบริบทของการแปลง HSL เป็น RGB หรือโดยทั่วไป
Doorknob

2
แดงฉันจะไม่ลองกับ PowerShell ... คุณจะได้ 16 สีให้เล่นด้วย (และพวกเขาไม่ได้สั่ง ... สายรุ้งหรือ RGB หรืออย่างอื่น ... เพียงแค่ค่าฐานสิบหกโดยพลการ) แม้ว่าจะมีการอ้างอิงกับ Picturesความท้าทายที่ยอดเยี่ยมจริงๆ!
AdmBorkBork

คำตอบ:


12

Perl, 95

รหัส 92 ไบต์ + 3 สำหรับ -p

สคริปต์นี้ใช้การประมาณสีที่มีให้กับเทอร์มินัล (สูงสุด 256) ในขณะนี้รวมถึงจุดสีเพียงไม่กี่ที่เลือกจากรายการนี้ดังนั้นจึงมีแนวโน้มที่จะไม่เจาะจง แต่ก็สนุกดี! ฉันกรองรายการเพื่อแสดงเฉพาะสีSและและLค่าของ100%และ50%ตามลำดับแล้วเรียงลำดับด้วยเฉดสีบรรจุตัวเลขลงในสตริงและเลือกสีจากรายการนั้น

การใช้งานนี้รวมถึงตัวละครที่ไม่สามารถพิมพ์ได้! ขโมย@ edc65 's ความคิดของการเปลี่ยนเฉพาะ\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

วางในข้อมูลและกด+CtrlD

เรียกใช้โดยใช้:

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

มันผลิตผลลัพธ์เช่น:

ตอนนี้ข้อความ TERMINAL ของคุณเป็นสีแดงแล้ว!  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 ตัวอักษร
ทุก

1
บันทึก255เป็นตัวแปรแทนที่โอเคอเรนซ์ทั้งหมดและใช้(a,)*3เป็นสีขาว แทนที่โดยfloat(j) (j+.0)
ตรัง Oul

1
นอกจากนี้: แทนที่float(j)เป็น1.*j
ตลอดไป

1
กำหนดตัวแปรหลายตัวพร้อมกัน (เช่นu=len(s) a=255=> u,a=len(s),255) ลบ[]เครื่องหมายวงเล็บออกจากtupleซึ่งไม่จำเป็น แทนที่ลูปตามรายการความเข้าใจ (เมธอดจะถูกประเมินเป็นผลข้างเคียง)
ตรัง Oul

1
@willem: ดูข้อมูลจำเพาะของปัญหา (ใต้Conversion ); มันอธิบายถึงวิธีที่โปรแกรมของคุณควรจัดการกับช่องว่าง
Lynn

5

JavaScript (ES6), 114 117 125

Edit2 3 ไบต์บันทึกแล้วขอบคุณ @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!
Dom Hastings

นอกจากนี้คุณยังสามารถเปลี่ยน${c}'เป็น'+cประหยัดได้อีก 2 ... กลับมาดีกว่าด้วยของฉัน!
Dom Hastings

สิ่งนี้ใช้ไม่ได้กับ Safari 9.0 c:
Addison Crump

4

Python 3, 131 ไบต์

คำตอบ Simular to Dom Hastings แต่นำไปใช้งานใน 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

เทอร์มินัลของคุณที่คุณใช้ต้องรองรับ 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!=" "

ตัวอักษรฐานสิบหก:

783d696e70757428293b753d277c82888e6a46222324251f1913375b7f7e7d273b6a3d300a666f72206920696e20783a7072696e7428271b5b33383b353b25646d25732725286f726428755b286a2a3138292f2f6c656e28782e7265706c616365282220222c20222229295d292c69292c656e643d2222293b6a2b3d69213d2220220a

ขอบคุณ @swstephe สำหรับการบันทึก 9 ไบต์ (และยังทำให้ฉันสังเกตเห็นว่าการนับจำนวนไบต์ของฉันเป็นสิ่งที่ผิดเล็กน้อยมาก)


ทำไมไม่แทนที่ "\ x82" ด้วยตัวอักษรจริง? ฉันเขียนสตริงนั้นลงในไฟล์และอ่านกลับเข้าไปในสคริปต์ของฉันในรูปแบบไบนารี คุณสามารถแทนที่ \ 033 ด้วยตัวอักษร raw หรือแม้กระทั่ง \ 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";

ที่จะใช้มันเพียงแค่ตั้งค่าในเซสชั่น / GET / POST / 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%>. 

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.