Nghệ thuật khử răng cưa ASCII


33

Lý lịch

Nghệ thuật ASCII là thực hành tạo hình ảnh bằng cách sử dụng văn bản ASCII để tạo thành hình dạng.

Bí danh là hiệu ứng được tạo bởi các "pixel" lớn của nghệ thuật ASCII, là kích thước của các ký tự. Hình ảnh trở nên khối và khó nhìn. Khử răng cưa loại bỏ hiệu ứng này bằng cách tạo một gradient và làm mềm các cạnh cứng của nghệ thuật ASCII.

Các thách thức

Thách thức của bạn là viết chương trình ngắn nhất có thể sẽ lấy một phần của nghệ thuật ASCII và sẽ đưa ra một phiên bản đã được khử răng cưa.

Những loại khử răng cưa?

Tất cả nghệ thuật ASCII sẽ bao gồm hai loại biểu tượng: Không gian và không khoảng trắng. Đối với mỗi ký tự không phải khoảng trắng, chương trình của bạn phải xác định xem nó có ở vị trí cần khử răng cưa hay không. Nếu có, thì bạn cần thay thế nó bằng ký tự chính xác. Nếu không, thì nhân vật vẫn giữ nguyên.

Làm thế nào để bạn biết nếu một nhân vật cần phải được khử răng cưa? Câu trả lời phụ thuộc vào các ký tự ngay phía trên, bên dưới, bên trái và bên phải của nhân vật ( không phải các đường chéo ). Dưới đây là biểu đồ khi cần khử răng cưa, ở đâu ?xcó thể đại diện cho bất kỳ ký tự không phải khoảng trắng nào.

 x? ->  d?
 ?      ? 


?x  -> ?b 
 ?      ? 

 ?      ? 
?x  -> ?F 


 ?      ? 
 x? ->  Y?



 x  ->  ;   Note: This character has been changed from _ to ;
 ?      ? 

 ?      ? 
 x  ->  V 



?x  -> ?> 



 x? ->  <?



 x  ->  @ 

Đầu vào (và ví dụ nghệ thuật ASCII trước khử răng cưa)

Đầu tiên, sẽ có hai dòng đầu vào (tới STDIN), một số H theo sau là một số W. Sau đó sẽ có các dòng H của các ký tự W chính xác mỗi dòng (không bao gồm dòng mới). Những dòng sau đây sẽ là nghệ thuật ASCII cần được khử răng cưa. Dưới đây là một ví dụ đầu vào (không đẹp, nhưng thử nghiệm):

7
9
  888888 
 888888  
999 98  7
 666666  
  666666 
   6666  
    6    

Đầu ra (và ví dụ nghệ thuật chống răng cưa)

Chương trình của bạn sẽ xuất ra STDOUT nghệ thuật ASCII (có cùng kích thước), đã được khử răng cưa. Đây là đầu ra cho đầu vào trên. Lưu ý cách các ký tự viền được coi là khoảng trắng giáp.

  d8888> 
 d8888F  
<99 98  @
 Y6666b  
  Y6666> 
   Y66F  
    V    

Điều này có thể trông không tốt lắm (do khoảng cách giữa các dòng trong khối mã), nó trông đẹp hơn với nghệ thuật ASCII lớn hơn và chất lượng phụ thuộc vào phông chữ chính xác được sử dụng.

Một vi dụ khac

Đầu vào

12
18
   xx  xxx  xxx   
  xxxx  xxx  xxx  
 xxxxxx  xxx  xxx 
xxx  xxx  xxx  xxx
xxxx xxx  xxx  xxx
 xxxxxx  xxx  xxx 
  xxxx  xxx  xxx  
x  xx  xxx  xxx  x
xx    xxx  xxx  xx
xxx  xxx  xxx  xxx
xxxx  xxx  xxx  xx
xxxxx  xxx  xxx  x

Đầu ra

   db  <xb  <xb   
  dxxb  Yxb  Yxb  
 dxxxxb  Yxb  Yxb 
dxx  xxb  xxb  xxb
Yxxb xxF  xxF  xxF
 YxxxxF  dxF  dxF 
  YxxF  dxF  dxF  
;  YF  dxF  dxF  ;
xb    dxF  dxF  dx
xxb  <xF  <xF  <xx
xxxb  Yxb  Yxb  Yx
Yxxx>  Yx>  Yx>  V

Quy tắc, hạn chế và ghi chú

Chương trình của bạn chỉ nên được viết bằng các ký tự ASCII có thể in được, để chúng tôi có thể tạo ra nghệ thuật từ các chương trình. Ngoài ra, các quy tắc golf tiêu chuẩn áp dụng.


Vì chưa có câu trả lời nào, tôi đã thay đổi một ký tự trong biểu đồ khử răng cưa. _đã trở thành ;bởi vì nó hoạt động tốt hơn.
PhiNotPi

Đây có thể là câu hỏi golf mã yêu thích của tôi mọi thời đại. Làm việc trên 4 giải pháp tuyệt vời khác nhau.
captncraig

Mặc dù tôi bối rối. Bạn nói các đường chéo không được tính, nhưng tất cả các sơ đồ của bạn đều hiển thị các dấu hỏi điền vào các đường chéo. Từ những gì tôi thấy trong các ví dụ, có thể an toàn khi chỉ nhìn sang hai bên, nhưng tôi có bị nhầm lẫn không? Làm đường chéo bao giờ quan trọng?
captncraig

Không, các đường chéo không bao giờ quan trọng. Có lẽ sẽ rõ ràng hơn nếu tôi loại bỏ các đường chéo khỏi biểu đồ.
PhiNotPi

Tôi nghĩ rằng có thể có một lỗi đánh máy trong ví dụ của bạn; Tôi tin rằng cột bên tay phải nên có Ys ở cạnh bên trong. Rất thích đến với câu trả lời cho câu hỏi này, câu hỏi hay: D
Ed James

Câu trả lời:


8

Ruby, 180 168 ký tự

gets
w=1+gets.to_i
f=*(readlines*"").chars
f.zip(f[1..-1]+s=[" "],s+f,s*w+f,f[w..-1]+s*w){|a,*b|$><<"@;V#{a}>bF#{a}<dY#{a*5}"[a>" "?(b.map{|y|y>" "?1:0}*"").to_i(2):3]}

Một triển khai Ruby khác có cách tiếp cận zip. Bạn có thể xem ví dụ thứ hai chạy trực tuyến .

Chỉnh sửa: Sử dụng readlineslưu 12 ký tự.


6

Ruby 275 265 263 261 258 254 244 243 214 212 207

H=0...gets.to_i
W=0...gets.to_i
G=readlines
z=->x,y{(H===y&&W===x&&' '!=G[y][x])?1:0}
H.map{|j|W.map{|i|l=G[j][i]
G[j][i]="@V;#{l}>Fb#{l}<Yd#{l*5}"[z[i+1,j]*8+z[i-1,j]*4+z[i,j+1]*2+z[i,j-1]]if' '!=l}}
puts G

Mẫu 1: http://ideone.com/PfNMA

Mẫu 2: http://ideone.com/sWijD


1) Dấu ngoặc quanh định nghĩa phạm vi là không cần thiết. 2) 0..h-1có thể được viết là 0...h. 3) G=[];h.times{G<<gets}có thể được viết dưới dạng G=readlines, tương tự như trong mã C # của bạn. 4) Sau bước 3. biến h trở nên vô dụng, giá trị của h và w chỉ được sử dụng một lần, do đó h=gets.to_i;w=gets.to_i;H=(0..h-1);W=(0..w-1)có thể được viết là H=0...gets.to_i;W=0...gets.to_i. 5) Trong này trường hợp andcó thể được viết như sau &&, mà không cần các không gian xung quanh. 6) Bạn có thêm; và bạn đã đếm dòng mới ở cuối tập tin, không cần thiết. Điều này có nghĩa là 214 ký tự: ideone.com/CiW0l
manatwork

Ồ cảm ơn nhé! Tôi biết đã có những cải tiến được thực hiện, nhưng chưa bao giờ nghĩ là có đó nhiều. Tôi đã thử H=0..gets.to_ikhi tôi viết mã, nhưng nó dường như không hoạt động (rõ ràng là nó phải vì lý do khác).
Cristian Lupascu

1
Vẫn còn hai điểm mà bạn có thể giảm ít nhất 7 ký tự: 1) Bạn có thể sử dụng mapthay vì each2) z=->...thay vì def z...end.
Howard

@Howard Cảm ơn, tôi đã áp dụng mapthay vì eachthay đổi. Tuy nhiên, đối với cú pháp lambda, tôi nghĩ rằng sẽ yêu cầu các cách sử dụng zphải có dạng z.call(args)thay vì z(args), do đó thêm một chút vào số lượng ký tự. Xin vui lòng cho tôi biết nếu tôi thiếu một cái gì đó.
Cristian Lupascu

@Howard Nevermind, tôi chỉ tìm ra những gì tôi đang thiếu. Tôi sẽ cập nhật để sử dụng lambda [].
Cristian Lupascu

4

Javascript, 410 ký tự:

function(t){m={"10110":"b","11100":"d","01101":"Y","00111":"F","10100":";","00101":"V","00110":">","01100":"<","00100":"@"},d="join",l="length",t=t.split('\n').splice(2),t=t.map(function(x)x.split('')),f=function(i,j)t[i]?(t[i][j]||' ')==' '?0:1:0;for(o=t[l];o--;){for(p=t[o][l];p--;){y=[f(o+1,p),f(o,p+1),f(o,p),f(o,p-1),f(o-1,p)],t[o][p]=m[y[d]('')]||t[o][p]}}t=t.map(function(x)x[d](''))[d]('\n');return t;}

vô dụng:

function(t){
    m={
        "10110":"b",
        "11100":"d",
        "01101":"Y",
        "00111":"F",
        "10100":";",
        "00101":"V",
        "00110":">",
        "01100":"<",
        "00100":"@"
    },
    d="join",
    l="length",
    t=t.split('\n').splice(2),
    t=t.map(function(x) x.split('')),
    f=function(i,j) t[i]?(t[i][j]||' ')==' '?0:1:0;

    for(o=t[l];o--;){
        for(p=t[o][l];p--;){
            y=[f(o+1,p),f(o,p+1),f(o,p),f(o,p-1),f(o-1,p)],

            t[o][p]=m[y[d]('')]||t[o][p]
        }
    }
    t=t.map(function(x)x[d](''))[d]('\n');
    return t;
}

Nguyên, 440 ký tự:

function (t){m={"10110":"b","11100":"d","01101":"Y","00111":"F","10100":";","00101":"V","00110":">","01100":"<","00100":"@"},s="split",d="join",l="length",t=t[s]('\n').splice(2),t=t.map(function(x) x[s]('')),f=function(i,j)i<0||i>=t[l]?0:(j<0||j>=t[i][l]?0:t[i][j]==' '?0:1);for(o=t[l];o--;){for(p=t[o][l];p--;){y=[f(o+1,p),f(o,p+1),f(o,p),f(o,p-1),f(o-1,p)],h=m[y[d]('')];if(h){t[o][p]=h}}}t=t.map(function(x) x[d](''))[d]('\n');return t;}

NB Tôi đã giả định rằng hai dòng đầu vào thực sự không liên quan và kích thước của các dòng sau là chính xác. Tôi cũng đang tính toán rằng tôi có thể cắt thêm vài ký tự khi tôi có cơ hội!


1
Thay thế khai báo của m để m={22:"b",28:"d",13:"Y",7:"F",20:";",5:"V",6:">",12:"<",4:"@"}sau đó chuyển đổi chỉ mục của m bằng parseInt(): m[parseInt(y[d](''),2)]. Điều này làm giảm kích thước xuống 373 ký tự.
manatwork

3

Python, 259 ký tự

H=input()
W=input()+1
I=' '.join(raw_input()for i in' '*H)
for i in range(H):print''.join(map(lambda(s,a,b,c,d):(s*5+'dY<'+s+'bF>'+s+';V@'+' '*16)[16*(s==' ')+8*(a==' ')+4*(b==' ')+2*(c==' ')+(d==' ')],zip(I,I[1:]+' ',' '+I,I[W:]+' '*W,' '*W+I))[i*W:i*W+W-1])

Chương trình đọc đầu vào thành một chuỗi I(có khoảng trắng ngăn cách các dòng), mở ra một danh sách gồm 5 bộ dữ liệu chứa ký tự và bốn ký tự xung quanh, sau đó tra cứu ký tự kết quả bằng cách lập chỉ mục chuỗi.


3

PHP - 359 330 282 268 257 ký tự

<?php
$i=fgets(STDIN)+0;$w=fgets(STDIN)+1;$s='';$m='@<;d>0b0VY00F000';
for(;$i--;)$s.=fgets(STDIN);
for(;++$i<strlen($s);){
$b=trim($s[$i])?0:15;
foreach(array($i+1,$i+$w,$i-1,$i-$w)as$k=>$x)
$b|=pow(2,$k)*(isset($s[$x])&&trim($s[$x]));
echo $m[$b]?$m[$b]:$s[$i];}

@PhiNotPi Nó không hoạt động vì các tệp kiểm tra được lưu cục bộ của tôi có EOL kiểu windows \r\n. Tôi đã cập nhật mã của mình để hoạt động với EOL kiểu unix \n.
Rusty Fausak

Ok, có vẻ như bây giờ đang làm việc.
PhiNotPi

2

Con trăn, 246 241

H=input();W=1+input()
S=' '
o=W*S
F=o+'\n'.join((raw_input()+o)[:W-1]for k in range(H))+o
print ''.join((16*x+'@;<d>b'+2*x+'V'+x+'Y'+x+'F'+3*x)[
16*(x>S)|8*(a>S)|4*(l>S)|2*(r>S)|(b>S)]for
x,a,l,r,b in zip(F[W:-W],F,F[W-1:],F[W+1:],F[2*W:]))

WC và thử nghiệm trên mẫu 2, khác với đầu ra của giải pháp Ruby ở đầu:

t:~$ wc trans.py && python trans.py < lala2 > o && diff -q o ruby_out2_sample
  2 11 241 trans.py
t:~$

1

C # 591 563

string A(string t){var s=new StringReader(t);var h=int.Parse(s.ReadLine());var w=int.Parse(s.ReadLine());var lines=s.ReadToEnd().Split(new[]{"\r\n"},StringSplitOptions.None).Select(x=>x.ToCharArray()).ToArray();for(var i=0;i<h;i++)for(var j=0;j<w;j++){var c=lines[i][j];if(c==' ')continue;var n=(i>0?(lines[i-1][j]!=' '?1:0):0)+(i<h-1?(lines[i+1][j]!=' '?2:0):0)+(j>0?(lines[i][j-1]!=' '?4:0):0)+(j<w-1?(lines[i][j+1]!=' '?8:0):0);lines[i][j]=new[]{'@','V',';',c,'>','F','b',c,'<','Y','d',c,c,c,c,c}[n];}return string.Join("\r\n",lines.Select(l=>new string(l)));}
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.