คุณสามารถทำให้เทอร์มินัลของฉันน่าเบื่อน้อยลงได้หรือไม่?


11

เทอร์มินัลน่าเบื่อมากในวันนี้ พวกเขาเคยเป็นแบบนี้:

อาคาร 1 อาคาร 2

ตอนนี้พวกเขากำลังอ่อนโยนและน่าเบื่อและสีดำและสีขาว ฉันต้องการให้คุณเขียนโปรแกรมที่จะทำให้เทอร์มินัลของฉันมีสีสันอีกครั้ง!

ลักษณะ

ใช้โค้ด Ruby ตัวอย่างนี้:

รหัสตัวอย่าง

ขั้วลินุกซ์ส่วนใหญ่สนับสนุนเหล่านี้ลำดับหนี ( \eย่อมาจากตัวหนี) และ Windows สามารถรองรับพวกเขาด้วยANSICON นี่คือไวยากรณ์ของลำดับ escape เฉพาะที่สามารถเปลี่ยนข้อความหรือสีพื้นหลังของสตริง:

\e[{{COLOR}}m

โดยที่\eย่อมาจากอักขระเลี่ยง ( 0x1Bใน ASCII) และ{{COLOR}}ถูกแทนที่ด้วยจำนวนสีที่คุณต้องการใช้ (รายละเอียดเพิ่มเติมในภายหลัง) ข้อความที่อยู่หลังลำดับ escape นี้จะถูกจัดรูปแบบตามที่กำหนดและค่า0จะรีเซ็ตการจัดรูปแบบทั้งหมด

ความท้าทายของคุณคือการใช้สตริงที่ระบุข้อความบางอย่างที่อาจมีสีและส่งออกเวอร์ชันที่มีสีสันของมัน

อินพุต / เอาต์พุต

ข้อความปกติใช้งานได้เหมือนปกติ ตัวอย่างเช่นอินพุตwafflesให้เอาต์พุตเดียวกันโดยไม่มีสีพิเศษ

ไวยากรณ์สำหรับการระบุสีคล้ายกับไวยากรณ์วิกิพีเดีย ตัวอย่างเช่นในการระบายสีคำว่า "สีแดง" เป็นสีแดงในประโยคThis is the color red!อินพุตจะเป็น:

This is {{red|the color red}}!

สีพื้นหลังก็ใช้ได้เช่นกัน หากคุณต้องการตัวอักษรสีดำบนพื้นหลังสีขาวคุณจะใช้สิ่งนี้:

{{black|white|This text is black on white}}

ในการรับเฉพาะสีพื้นหลังให้ตัดส่วนหน้า:

{{|red|This text has a red background}}

สเปค

วงเล็บปีกกาเปิดสองชุดจะระบุจุดเริ่มต้นของคำสั่งสีเสมอ วงเล็บปีกกาปิดสองตัวระบุจุดสิ้นสุด วงเล็บจะจับคู่เสมอ จะไม่มีจะเป็น{{โดยไม่ต้องสอดคล้องกัน}}และจะไม่มาก่อนที่จะสอดคล้องกัน}} คำสั่งสี{{เหล่านี้จะไม่ซ้อนกันและจะไม่ปรากฏในคำสั่งสี{{

ภายในคำสั่งสีจะมี|สัญลักษณ์หนึ่งหรือสองสัญลักษณ์เสมอ หากมีหนึ่งข้อความก่อนหน้านั้นจะเป็นสีพื้นหน้าและข้อความหลังจากนั้นเป็นสตริงที่จะแสดงในสีนั้น หากมีสองข้อความก่อนหน้าสีแรกคือสีพื้นหน้าข้อความหลังสีแรก แต่ก่อนสีที่สองคือสีพื้นหลังและข้อความหลังสีที่สองคือสตริงที่จะแสดง แถบแนวตั้งเหล่านี้อาจมีอยู่นอกคำสั่งสีและควรพิมพ์อย่างแท้จริง

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

ต่อไปนี้เป็นคำแนะนำในการส่งข้อความสีที่ต้องการ:

  • ลำดับสีที่กำหนดไว้ในส่วน "คำอธิบาย" ยกตัวอย่างเช่นลำดับสี 42 "\e[42m"จะเป็น

  • หากต้องการตั้งค่าสีให้พิมพ์ลำดับสีตามจำนวนที่กำหนดด้านล่าง:

     Color name   | Color sequence number (foreground / background)
    --------------+----------
     black        | 30 / 40
     red          | 31 / 41
     green        | 32 / 42
     yellow       | 33 / 43
     blue         | 34 / 44
     magenta      | 35 / 45
     cyan         | 36 / 46
     lightgray    | 37 / 47
     darkgray     | 90 / 100
     lightred     | 91 / 101
     lightgreen   | 92 / 102
     lightyellow  | 93 / 103
     lightblue    | 94 / 104
     lightmagenta | 95 / 105
     lightcyan    | 96 / 106
     white        | 97 / 107
    
  • ชื่อสีจะต้องตรงตามตัวพิมพ์ใหญ่ - เล็กและจะไม่มีการระบุชื่อสีที่ไม่ถูกต้อง คุณไม่ต้องจัดการกับสิ่งที่ชอบREDหรือlightgrey(สะกดด้วยe)

  • หลังจากที่คุณพิมพ์ลำดับสีมันจะใช้กับข้อความทั้งหมดที่ตามมา หากต้องการสิ้นสุดลำดับสี (รีเซ็ตเป็นสีเริ่มต้น) ให้ส่งลำดับสีเป็น0( "\e[0m")

กรณีทดสอบ

 {{|yellow|     }}
{{|yellow| }}     {{|yellow| }}
{{|yellow| }} {{red|'}} {{red|'}} {{|yellow| }}
{{|yellow| }} \_/ {{|yellow| }}
{{|yellow| }}     {{|yellow| }}
 {{|yellow|     }}

นี่ควรจะเป็นใบหน้าที่ยิ้มแย้ม ... ด้วยดวงตาสีแดงที่ชั่วร้าย

กฎระเบียบ

  • คุณไม่สามารถใช้ไลบรารีหรือฟังก์ชั่นของภาษาโปรแกรมของคุณเพื่อแยกสีโดยอัตโนมัติ ซึ่งหมายความว่าคุณจะต้องเป็นคนที่จะกำหนดสิ่งที่"red"หมายถึง; คุณไม่สามารถมีห้องสมุดให้ทำเพื่อคุณโดยอัตโนมัติ

  • นี่คือดังนั้นโค้ดที่สั้นที่สุดเป็นไบต์จะเป็นผู้ชนะ!


จริง ๆ แล้วมันควรจะเป็นเทอร์มินัล หรือเพียงแค่โปรแกรมอ่านข้อความที่มีสีสัน มันควรจะรันคำสั่งหรือไม่?
Nathan Merrill

ฉันพบว่ามันยากที่จะทดสอบสิ่งนี้ ทุกอย่างที่ฉันส่งไปยัง STDOUT โดยใช้ไวยากรณ์ที่ระบุนั้นจะเป็นข้อความธรรมดา โปรไฟล์ทุบตีของฉันใช้พรอมต์สีดังนั้นการขโมยจากที่ฉันลอง\n\[\e[32m\]\w\n\[\e[0m\]> (ชื่อไดเรกทอรีสีเขียวพรอมต์ธรรมดาในบรรทัดถัดไป) แต่ฉันไม่สามารถใช้งานได้จากโปรแกรม (ลอง python และ Java จนถึงตอนนี้) ความคิดใด ๆ
Geobits

@Geobits echo -e "\e[31mtest\e[0m"ลอง
Doorknob

4
lolcatฉันคิดว่าคุณจะสนุกกับการ
Anko

1
ผมคิดว่าโดยyouเขาเปรียบเปรยหมายถึงyour program(เมื่อเทียบกับการเรียกร้องให้ฟังก์ชั่นห้องสมุด) และบอกว่าเขาจะใช้เวลาdetermineในความรู้สึกของการไม่เป็นในfigure out chooseนั่นคือโปรแกรมของคุณที่ควรจัดการการแมป: String ("red") | -> จำนวนเต็ม (31) redเป็นเพียง31เพราะเขาพูดอย่างนั้นข้อมูลจะต้องรวมเข้ากับโปรแกรม แม้ว่ามันอาจจะเป็นที่ถกเถียงกันอยู่ว่าอะไรจะนับเป็นyour program- เราสามารถใช้ฟังก์ชั่นการจัดการสตริงเอนกประสงค์ได้หรือไม่? - อย่าโกง / ทำทารุณอย่างโจ๋งครึ่ม
blutorange

คำตอบ:


6

ทับทิม, 205 189 188 186 185 182 174 170 165 161 159 154 ไบต์

การใส่ชื่อสีจำนวนมากลงในรหัสของคุณนั้นดูไม่น่าเบื่อ

ลงไปที่ 170 rubikส่วนหนึ่งต้องขอบคุณ ตอนนี้แถบเลื่อนจะหายไป!

หนึ่งที่เห็นได้ชัดและอีกหนึ่งการปรับปรุงไม่ชัดเจนขอบคุณคำตอบที่ยืดหยุ่นโดยไม่ต้องปรับปรุงมันฉันจะไม่กลับมาอีกเลย!

ไม่อีกต่อไปฉันบันทึก 4 ไบต์ด้วย #sum ฉันไม่ได้ตั้งใจ แต่ฉันเพิ่งสังเกตเห็นว่าวิธีนี้ไม่คำนึงถึงตัวพิมพ์ใหญ่และตัวพิมพ์เล็ก {{RED|Red text}}มันมีความสุขประมวลผล

การถ่ายโอนข้อมูล Hex:

0000000: 7a3d 2d3e 6a7b 693d 2240 3054 2d44 1547  z=->j{i="@0T-D.G
0000010: 5155 0034 3256 2f46 1749 0b22 2e69 6e64  QU.42V/F.I.".ind
0000020: 6578 2028 415b 6a5d 2e74 6f5f 732e 7375  ex (A[j].to_s.su
0000030: 6d25 3839 292e 6368 723b 692b 3d69 3e39  m%89).chr;i+=i>9
0000040: 3f38 303a 3330 7d0a 243e 3c3c 243c 2e72  ?80:30}.$><<$<.r
0000050: 6561 642e 6773 7562 282f 7b7b 282e 2a3f  ead.gsub(/{{(.*?
0000060: 297d 7d2f 297b 413d 2431 2e73 706c 6974  )}}/){A=$1.split
0000070: 277c 273b 221b 5b25 693b 2569 6d23 7b41  '|';".[%i;%im#{A
0000080: 2e70 6f70 7d1b 5b30 6d22 255b 7a5b 305d  .pop}.[0m"%[z[0]
0000090: 2c31 302b 7a5b 315d 5d7d                 ,10+z[1]]}

xxd -r hex.dumpคุณสามารถแปลงด้วย

โปรแกรมที่มีอักขระที่ไม่สามารถพิมพ์ได้ทั้งหมดหลบหนีเพื่อการอ้างอิง:

z=->j{i="@0T-D\x15GQU\x0042V/F\x17I\v".index (A[j].to_s.sum%89).chr;i+=i>9?80:30}
$><<$<.read.gsub(/{{(.*?)}}/){A=$1.split'|';"\x1b[%i;%im#{A.pop}\x1b[0m"%[z[0],10+z[1]]}

นั่นคือหนึ่งบรรทัด ใช้มันแบบนี้

ruby colors.rb -W0 < input.txt

-W0คำเตือนธงไม่ใส่ที่จะถูกส่งไปstderrเป็นอย่างอื่น อย่างไรก็ตามโปรแกรมทำงานได้ดีโดยไม่มีการตั้งค่าสถานะใด ๆ

เอาท์พุท:

เอาท์พุต


1
อาฉันมีความคิดเดียวกัน แต่คุณเอาชนะฉันมัน! ฉันคิดว่าคุณจะสามารถประหยัดถ่านที่มีฐาน 35, 98 และโมดูลัส xor 1. '1?IYU_N[(\x0c\x16&",\x1f\x01'สตริงจะเป็น: แม้ว่าสตริงของฉันมีความยาว 16 ฉันเห็นว่าคุณอายุ 18 ดังนั้นคุณอาจต้องปรับตัว
บิค

ขอบคุณ มีสองไบต์เพิ่มเติมเพื่อสนับสนุนรหัสสี 39/49 ซึ่งตั้งค่าสีแบ็คกราวด์ / ฟอร์ดเริ่มต้น แต่ขอบคุณสำหรับเคล็ดลับฉันกำลังทำงานและฉันจะให้ความคิดเพิ่มเติมเมื่อฉันกลับบ้าน
blutorange

1
ฉันสังเกตว่ามีเพียงฐานเดียวที่คุณสามารถใช้ได้คือ 35 และ 36 (อย่างน้อยint()ฟังก์ชั่นของไพ ธ อนไม่สามารถเกิน 36) จากนั้นฉันลองชุดค่าผสมทั้งหมดสำหรับโมดูลัส (จาก 2 ถึง 10,000 แต่ในทางทฤษฎีเราสามารถขยายการค้นหาไปยังUnicode ทั้งหมด ) และสำหรับ xor ซึ่งฉันเก็บไว้เล็กน้อย (1 ถึง 9) จากนั้นฉันพิจารณาผลลัพธ์ที่ยอมรับได้เฉพาะในกรณีที่ไม่มีอักขระซ้ำกัน
rubik

ใช่นั่นเป็นสิ่งที่ฉันทำไม่มากก็น้อย แต่เดิมฉัน จำกัด ตัวเองให้เป็นตัวละครที่พิมพ์ได้เพราะนั่นทำให้คุณปวดหัวน้อยลงและดูดีขึ้น แต่เนื่องจากฉันใช้ byte 0x1e แทนลำดับ escape แล้วฉันก็อาจใช้อักขระที่ไม่สามารถพิมพ์ได้อีก x.to_i(base)%mod+offsetเพื่อให้บรรลุตัวอักษรพิมพ์ผมใช้ ฉันจึงแทนที่+ด้วย^เพราะเพราะมันดูเท่กว่า นอกเหนือจากนั้นมันไม่จำเป็น วาง^99และเปลี่ยน<<เป็น+บันทึกเพิ่มเติมไบต์ ขอบคุณสำหรับเคล็ดลับฉันจะไม่ได้สังเกตเห็นอย่างอื่น!
blutorange

4

Ruby, 329 ไบต์

h={};(y=0..15).each{|i|h[%w(black red green yellow blue magenta cyan lightgray darkgray lightred lightgreen lightyellow lightblue lightmagenta lightcyan white)[i]]=y.map{|j|[30,40].map{|k|k+i%8+i/8*60}}[i]}
loop{puts gets.gsub(/{{.+?}}/){|x|"\e[#{h[(g=x.scan(/[^{}|]+/))[0]][0]}m#{(g[2]? "\e[#{h[g[1]][1]}m":'')}#{g.last}\e[0m"}}

ฉันต้องใช้ทับทิมรุ่นใด ฉันใช้ruby 2.1.2p95แล้วมันเกิดข้อผิดพลาด: undefined method 'gsub' for nil:NilClass (NoMethodError) .
เรย์

สวัสดี @ เรย์มันทำงานใน 2.0.0-p451 ฉันไม่ได้ลองใน 2.1.2 นี่มันทำงานเป็นสคริปต์และนี่มันทำงานในคณะกรรมการ
Alex Deva

มันทำงานได้เมื่อคุณป้อนข้อความด้วยตนเอง หากคุณทำเช่นruby colors.rb < input.txtนั้นก็จะวนซ้ำหลังจากอ่านอินพุตทั้งหมดแล้ว จากนั้นgetsส่งคืนnilซึ่งไม่มี#gsubวิธีดังนั้นจึงทำให้เกิดข้อผิดพลาด ใช้$><<$<.readแทนloop{puts getsมันสั้นกว่าด้วย )
blutorange

ฉันเพิ่งทดสอบสคริปต์นี้ด้วยหน้ายิ้ม (ดูคำถามและภาพจากโพสต์ของฉัน) และไม่มีเส้นขอบสีเหลืองรอบ ๆ รอยยิ้ม?
blutorange

4

Flex (lexer) - 226 197 192 182 168 (หรือ 166)

หากต้องการลดลงเป็น 166 ให้เปลี่ยน\33อักขระการหลบหนีที่แท้จริง

 int z;p(i){printf("\33[%dm",i);}
%%
"{{" z=2;
[a-z]*\| if(!z)REJECT;~-yyleng&&p("062q00t03058ns7uo0p90r4"[*(int*)&yytext[yyleng>7?4:0]%131%27]-10*z);z--;
"}}" p(z=0);

รวบรวมและเรียกใช้:

$ flex -o colour.c colour.l
$ gcc -o colour colour.c -lfl
$ ./colour < input

3

Python - 351

import re,sys
R=range
E=lambda n,d=0:'\033[%dm'%(T[n]+d)if n else''
def P(m):f,b,t=m.groups();return'%s%s%s\033[0m'%(E(f),E(b,10),t)
x='!red!green!yellow!blue!magenta!cyan'.replace
T=dict(zip(('black'+x('!',' ')+' lightgray darkgray'+x('!',' light')+' white').split(),R(30,38)+R(90,98)))
print re.sub(r'{{(\w+)?\|?(\w+)?\|?(.+?)}}',P,sys.stdin.read())

1

งูเห่า - 496

มันอาจจะเกือบจะเป็นคำสั่งพิมพ์เดียว

use System.Text.RegularExpressions
class P
    def main
        print Regex.replace(Console.readLine,r'\{\{('+(l=List<of String>(((m=' black red green yellow blue magenta cyan'.split).join(' ')+' lightgray darkgray'+m.join(' light')+' white').split))[1:].join('|')+r')?\|?('+l[1:].join('|')+r')?\|(.*?)\}\}',do(a as Match))
            return if(x=l.indexOf('[a.groups[1]]'),r'\e['+'[if(x>8,x+81,x+29)]m','')+if(y=l.indexOf('[a.groups[2]]'),r'\e['+'[if(y>8,y+91,y+39)]m','')+'[a.groups[3]]'+if(x+y,r'\e[0m','')

1

Python 561

อ่านข้อความเพื่อจัดรูปแบบจาก stdin

import re,sys
def p(f,b,t):
    p=''
    m='\033[%dm'
    if f!=0:p+=m%f
    if b!=0:p+=m%b
    return p+t+m%0
def c(n,b=0):
    s='black:30#red:31#green:32#yellow:33#blue:34#magenta:35#cyan:36#lightgray:37#darkgray:90#lightred:91#lightgreen:92#lightyellow:93#lightblue:94#lightmagenta:95#lightcyan:96#white:97'
    r=0
    for i in s.split('#'):
        (t,c)=i.split(':')
        if t==n:
            r=int(c)
            if b==1:r+=10
    return r
def r(m):
    i=m.groups()
    f=b=0
    if i[0]!='':f=c(i[0])
    if i[1]!=None:b=c(i[1],1)
    return p(f,b,i[2])
print re.sub('{{(\w*)\|(?:(\w*)\|)?([^}]+)}}',r,sys.stdin.read())

2
มัน verbose เกินไปที่จะมีis not Noneใน codegolf !=Noneตัวอย่างเช่นคุณอาจใช้
เรย์

นอกจากนี้ในรหัสของคุณจะโยนdef p(f,b,t) ZeroDivisionErrorอะไร mod 0 เป็นไปไม่ได้
สลายตัวเบต้า

@BetaDecay ที่ไม่ใช่จำนวนเต็มโมดูลัสของที่เป็นสตริงที่มีการจัดรูปแบบ
Sammitch

ฉันได้รับข้อผิดพลาดทางไวยากรณ์ที่ไม่ถูกต้องขณะre.subใช้งานนี้
ArtOfCode

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