Bạn có thể làm cho thiết bị đầu cuối của tôi bớt nhàm chán?


11

Thiết bị đầu cuối rất nhàm chán những ngày này. Họ đã từng trông như thế này:

Nhà ga 1 Nhà ga số 2

Bây giờ họ chỉ nhạt nhẽo và buồn tẻ và đen trắng. Tôi muốn bạn viết cho tôi một chương trình sẽ làm cho thiết bị đầu cuối của tôi trở nên đầy màu sắc một lần nữa!

Sự miêu tả

Lấy ví dụ này về mã Ruby:

Mã ví dụ

Hầu hết các thiết bị đầu cuối Linux hỗ trợ các chuỗi thoát này ( \eviết tắt của ký tự thoát) và Windows có thể hỗ trợ chúng với ANSICON . Dưới đây là cú pháp của chuỗi thoát cụ thể có thể thay đổi văn bản hoặc màu nền của chuỗi:

\e[{{COLOR}}m

trong đó \eviết tắt của ký tự thoát ( 0x1Btrong ASCII) và {{COLOR}}được thay thế bằng số màu mà bạn muốn sử dụng (chi tiết hơn về điều đó sau). Văn bản xuất hiện sau chuỗi thoát này sẽ được định dạng theo chỉ dẫn và giá trị 0sẽ đặt lại tất cả định dạng.

Thách thức của bạn là lấy một chuỗi chỉ định một số văn bản có thể chứa màu và xuất ra phiên bản đầy màu sắc của nó.

Đầu ra đầu vào

Văn bản bình thường hoạt động giống như bình thường, và được in theo nghĩa đen. Ví dụ, đầu vào wafflesmang lại cùng một đầu ra, không có màu đặc biệt.

Cú pháp chỉ định màu tương tự cú pháp của Wikipedia . Ví dụ: để tô màu các từ "màu đỏ" bằng màu đỏ trong câu This is the color red!, đầu vào sẽ là:

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

Màu nền cũng hoạt động. Nếu bạn muốn chữ màu đen trên nền trắng, bạn sẽ sử dụng:

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

Để chỉ nhận được màu nền, hãy bỏ qua nền trước:

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

Sự chỉ rõ

Hai dấu ngoặc nhọn mở luôn chỉ định bắt đầu một lệnh màu . Hai dấu ngoặc nhọn đóng chỉ định kết thúc. Chân đế sẽ luôn khớp; sẽ không bao giờ có cái {{không có tương ứng }}, và }}sẽ không bao giờ đến trước cái tương ứng của nó {{. Các chỉ thị màu này sẽ không được lồng nhau và {{sẽ không bao giờ xuất hiện trong một chỉ thị màu.

Trong một chỉ thị màu, sẽ luôn có một hoặc hai |ký hiệu. Nếu có một, văn bản trước nó là màu nền trước và văn bản sau là chuỗi để hiển thị trong màu đó. Nếu có hai, văn bản trước cái thứ nhất là màu nền trước, văn bản sau cái thứ nhất nhưng trước cái thứ hai là màu nền và văn bản sau cái thứ hai là chuỗi để hiển thị. Các thanh dọc này có thể tồn tại bên ngoài một chỉ thị màu và nên được in theo nghĩa đen.

Màu nền trước hoặc màu nền (nhưng không phải cả hai) có thể trống, trong trường hợp đó bạn nên để chúng làm mặc định. Chuỗi cuối cùng (chuỗi đầu ra) sẽ không bao giờ trống.

Dưới đây là các hướng dẫn để xuất văn bản của một màu nhất định:

  • Một chuỗi màu được xác định trong phần "Mô tả". Ví dụ, một chuỗi màu 42 sẽ là "\e[42m".

  • Để đặt màu, hãy in chuỗi màu của số được xác định bên dưới:

     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
    
  • Tên màu phân biệt chữ hoa chữ thường và tên màu không hợp lệ sẽ không bao giờ được cung cấp. Bạn không phải xử lý những thứ như REDhoặc lightgrey(đánh vần là một e).

  • Sau khi bạn in một chuỗi màu, nó sẽ áp dụng cho tất cả các văn bản theo sau nó. Để kết thúc chuỗi màu (đặt lại về màu mặc định), hãy xuất chuỗi màu của 0( "\e[0m").

Trường hợp thử nghiệm

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

Điều này sẽ tạo ra một khuôn mặt cười ... với đôi mắt đỏ ác.

Quy tắc

  • Bạn không được sử dụng bất kỳ thư viện hoặc chức năng nào của ngôn ngữ lập trình để tự động phân tích màu. Điều này có nghĩa là bạn phải là người xác định "red"nghĩa là gì ; bạn không thể có một thư viện tự động làm điều đó cho bạn.

  • Đây là , vì vậy mã ngắn nhất tính bằng byte sẽ giành chiến thắng!


Nó thực sự được coi là một thiết bị đầu cuối? Hay chỉ là một trình xem văn bản đầy màu sắc? Có phải là để chạy lệnh?
Nathan Merrill

Tôi thấy khó để kiểm tra điều này. Tất cả mọi thứ tôi gửi đến STDOUT bằng cú pháp được chỉ định đều có văn bản thuần túy. Hồ sơ bash của tôi sử dụng một dấu nhắc màu, vì vậy tôi đã thử \n\[\e[32m\]\w\n\[\e[0m\]> (tên thư mục màu xanh lá cây, dấu nhắc đơn giản trên dòng tiếp theo), nhưng tôi không thể làm cho nó hoạt động từ một chương trình (đã thử python và Java). Có ý kiến ​​gì không?
Geobits

@Geobits Hãy thử echo -e "\e[31mtest\e[0m".
Doorknob

4
Tôi nghĩ bạn sẽ thích lolcat.
Anko

1
Tôi nghĩ rằng theo younghĩa bóng của anh ta your program(trái ngược với một cuộc gọi đến chức năng thư viện), và anh ta determinehiểu theo nghĩa figure out, không phải như trong choose. Tức là chương trình của bạn sẽ xử lý ánh xạ: Chuỗi ("đỏ") | -> Số nguyên (31). redchỉ 31bởi vì ông nói như vậy, thông tin đó cần được tích hợp vào chương trình. Mặc dù có thể lập luận chính xác những gì sẽ được tính là your program- chúng ta có thể sử dụng các hàm thao tác Chuỗi mục đích chung không? - đừng lừa dối / lạm dụng một cách trắng trợn.
blutorange

Câu trả lời:


6

Ruby, 205 189 188 186 185 182 174 170 165 161 159 154 byte

Đặt chuỗi dài các tên màu trong mã của bạn trông không đủ.

Giảm xuống 170 một phần nhờ rubik. Bây giờ các thanh cuộn đã biến mất!

Một cải tiến rõ ràng và một không quá rõ ràng, nhờ câu trả lời linh hoạt, mà không cải thiện nó, tôi sẽ không xem lại điều này!

Không còn nữa, tôi đã lưu 4 byte với #sum. Tôi không có ý định đó, nhưng tôi chỉ nhận thấy giải pháp này không phân biệt chữ hoa chữ thường. Nó hạnh phúc xử lý {{RED|Red text}}.

Đổ lục giác:

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

Bạn có thể chuyển đổi nó với xxd -r hex.dump.

Chương trình với tất cả các ký tự không in được thoát cho mục đích tham khảo:

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

Đó là một dòng. Sử dụng nó như thế này

ruby colors.rb -W0 < input.txt

Các -W0cờ ngăn chặn cảnh báo rằng sẽ được gửi đến stderrkhác. Tuy nhiên, chương trình hoạt động tốt mà không có cờ.

Đầu ra:

đầu ra


1
Ah, tôi có cùng một ý tưởng, nhưng bạn đã đánh bại tôi! Tôi nghĩ bạn có thể lưu một char với cơ sở 35, modulus 98 và xor 1. Chuỗi sẽ là : '1?IYU_N[(\x0c\x16&",\x1f\x01'. Chuỗi của tôi là 16 chiều dài mặc dù. Tôi thấy bạn là 18, vì vậy bạn có thể phải điều chỉnh.
rubik

Cảm ơn. Hai byte bổ sung có sẵn để hỗ trợ mã màu 39/49, thiết lập màu back / forground mặc định. Nhưng cảm ơn vì tiền boa, tôi hiện đang làm việc và tôi sẽ suy nghĩ thêm khi trở về nhà.
blutorange

1
Vâng, tôi đã quan sát thấy rằng các cơ sở duy nhất bạn có thể sử dụng là 35 và 36 (ít nhất int()chức năng của Python không thể vượt quá 36). Sau đó, tôi đã thử tất cả các kết hợp cho mô-đun (từ 2 đến 10000, nhưng theo lý thuyết, người ta có thể mở rộng tìm kiếm cho tất cả Unicode) và cho xor, mà tôi giữ ở mức nhỏ (1 đến 9). Sau đó, tôi chỉ xem xét các kết quả có thể chấp nhận được với những kết quả không chứa các ký tự trùng lặp.
rubik

Vâng, đó là ít nhiều những gì tôi đã làm là tốt. Ban đầu, tôi đã giới hạn bản thân mình vào các ký tự có thể in được, bởi vì điều đó giúp bạn bớt đau đầu và trông đẹp hơn. Nhưng vì tôi đang sử dụng byte 0x1e thay vì chuỗi thoát đã có, tôi cũng có thể sử dụng nhiều ký tự không in được hơn. Để đạt được các ký tự có thể in, tôi đã sử dụng x.to_i(base)%mod+offset. Sau đó tôi thay thế +bằng ^, bởi vì, nó trông mát mẻ hơn. Ngoài ra, nó là không cần thiết. Bỏ ^99và thay đổi <<để +lưu cho nhiều byte hơn. Cảm ơn vì tiền boa, tôi sẽ không nhận ra điều gì khác!
blutorange

4

Ruby, 329 byte.

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

Phiên bản nào của Ruby tôi cần để chạy cái này? Tôi đã sử dụng ruby 2.1.2p95và nó ném lỗi : undefined method 'gsub' for nil:NilClass (NoMethodError) .
Ray

Xin chào @Ray, nó hoạt động trong 2.0.0-p451. Tôi đã không thử nó trong 2.1.2. Ở đây nó hoạt động như một kịch bảnỞ đây nó hoạt động trong irb .
Alex Deva

Nó hoạt động khi bạn nhập văn bản bằng tay. Nếu bạn làm như vậy ruby colors.rb < input.txt, nó sẽ tiếp tục lặp sau khi tất cả các đầu vào đã được đọc. Sau đó getstrả về nil, không có #gsubphương thức, do đó gây ra lỗi. Sử dụng $><<$<.readthay vì loop{puts gets, nó cũng ngắn hơn; )
blutorange

Tôi vừa thử kịch bản này với khuôn mặt cười (xem câu hỏi và hình ảnh từ bài đăng của tôi), và không có viền màu vàng xung quanh mặt cười?
blutorange

4

Flex (lexer) - 226 197 192 182 168 (hoặc 166)

Để giảm xuống 166, thay đổi \33ký tự thoát thực tế.

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

Biên dịch và chạy:

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

3

Con trăn - 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

Rắn hổ mang - 496

gần như có thể là một tuyên bố in duy nhất.

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

Con trăn, 561

Đọc văn bản để định dạng từ 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
Thật quá dài dòng khi có is not Nonemột con cá tuyết. Bạn có thể sử dụng !=None, ví dụ.
Ray

Ngoài ra, trong def p(f,b,t), mã của bạn sẽ ném a ZeroDivisionError. Bất cứ điều gì mod 0 là không thể.
Beta Decay

@BetaDecay đó không phải là một số nguyên được mô đun hóa, đó là một chuỗi được định dạng.
Sammitch

Tôi đang gặp lỗi cú pháp không hợp lệ khi re.subchạy này
ArtOfCode

(nhận xét muộn) Mã 49 byte này có hoạt động không?
Erik the Outgolfer 20/07/2016
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.