앤티 앨리어싱 ASCII 아트


33

배경

ASCII 아트는 ASCII 텍스트를 사용하여 모양을 만들어 이미지를 만드는 방법입니다.

앨리어싱은 문자 크기 인 ASCII 아트의 큰 "픽셀"에 의해 생성되는 효과입니다. 이미지가 고르지 않고 잘 보이지 않습니다. 앤티 앨리어싱은 그래디언트를 만들고 ASCII 아트의 가장자리를 부드럽게하여이 효과를 제거합니다.

도전

당신의 도전은 ASCII 아트를 사용하고 앤티 앨리어싱 된 버전을 출력 할 수있는 가장 짧은 프로그램을 작성하는 것입니다.

어떤 종류의 앤티 앨리어싱?

ASCII 아트는 모두 공백과 공백이 아닌 두 가지 유형의 기호로 구성됩니다. 공백이 아닌 각 문자에 대해 프로그램은 앤티 앨리어싱이 필요한 위치에 있는지 확인해야합니다. 그렇다면 올바른 문자로 바꿔야합니다. 그렇지 않은 경우 캐릭터는 그대로 유지됩니다.

캐릭터를 앤티 앨리어싱해야하는지 어떻게 알 수 있습니까? 답은 문자 바로 위, 아래, 왼쪽 및 오른쪽에있는 문자에 따라 다릅니다 ( 대각선 아님). 여기에 안티 앨리어싱이 필요한 경우의 차트 ?x비 공백 문자에 대한 설 수는.

 x? ->  d?
 ?      ? 


?x  -> ?b 
 ?      ? 

 ?      ? 
?x  -> ?F 


 ?      ? 
 x? ->  Y?



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

 ?      ? 
 x  ->  V 



?x  -> ?> 



 x? ->  <?



 x  ->  @ 

입력 (및 사전 앨리어싱 제거 ASCII 아트 예제)

먼저, 두 줄의 입력 (STDIN에), 숫자 H 뒤에 숫자 W가 있습니다. 그런 다음 정확히 W 문자의 H 행이 있습니다 (줄 바꾸기 제외). 다음 줄은 앤티 앨리어싱이 필요한 ASCII 기술입니다. 다음은 입력 예입니다 (아름답 지 않지만 테스트).

7
9
  888888 
 888888  
999 98  7
 666666  
  666666 
   6666  
    6    

출력 (및 앤티 앨리어싱 된 아트 예제)

프로그램은 앤티 앨리어싱 된 ASCII 아트 (같은 치수의)를 STDOUT으로 출력해야합니다. 위의 입력에 대한 출력은 다음과 같습니다. 경계 문자가 경계 공백으로 처리되는 방식에 주목하십시오.

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

이것은 코드 블록의 줄 간격으로 인해 좋아 보이지 않을 수 있으며 더 큰 ASCII 아트에서는 더 좋아 보이고 품질은 사용 된 정확한 글꼴에 따라 다릅니다.

또 다른 예

입력

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

산출

   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

규칙, 제한 및 참고

귀하의 프로그램은 인쇄 가능한 ASCII 문자로만 작성되어야 프로그램에서 예술을 만들 수 있습니다. 그 외에 표준 코드 골프 규칙이 적용됩니다.


아직 답변이 없으므로 앤티 앨리어싱 차트에서 한 문자를 변경했습니다. 더 잘 작동하기 때문에 _되었습니다 ;.
PhiNotPi

이것은 내가 가장 좋아하는 코드 골프 질문 일 수 있습니다. 4 가지 멋진 솔루션처럼 작업합니다.
captncraig

혼란 스럽지만 대각선은 포함되지 않지만 다이어그램에는 대각선을 채우는 물음표가 모두 표시됩니다. 예제에서 볼 수 있듯이 측면 만 보는 것이 안전 할 수 있지만 혼란스러워합니까? 대각선이 중요합니까?
captncraig

아니요, 대각선은 중요하지 않습니다. 차트에서 대각선을 제거하면 더 분명 할 것입니다.
PhiNotPi

나는 당신의 모범에 오타가 있다고 생각합니다. 오른쪽 열의 안쪽 가장자리에 Y가 있어야한다고 생각합니다. 그래도이 질문에 대한 답을 얻는 것을 즐겼습니다. 좋은 질문 : D
Ed James

답변:


8

루비, (180) 168 자

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

우편 접근 방식을 취하는 또 다른 루비 구현. 두 번째 예제는 온라인으로 실행되는 것을 볼 수 있습니다 .

편집 : 사용 readlines하면 12자를 저장합니다.


6

루비 275 265 263 261 267 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

샘플 1 : http://ideone.com/PfNMA

샘플 2 : http://ideone.com/sWijD


1) 범위 정의 주위의 괄호는 필요하지 않습니다. 2) 0..h-1로 쓸 수 있습니다 0...h. 3) C # 코드와 마찬가지로로 G=[];h.times{G<<gets}작성할 수 있습니다 G=readlines. 4) 3 단계 후 변수 h는 쓸모 없게되고 h와 w의 값은 한 번만 사용되므로 h=gets.to_i;w=gets.to_i;H=(0..h-1);W=(0..w-1)로 쓸 수 있습니다 H=0...gets.to_i;W=0...gets.to_i. 5) 경우 공백이 필요하지 않은 and로 쓸 수 있습니다 &&. 6) 당신은 여분이 있습니다; 파일 끝에서 줄 바꿈을 계산했지만 필요하지 않습니다. 이것은 214 자를
manatwork

와우 고마워! 개선이 필요하다는 것을 알았지 만 수가 많을 것이라고는 생각하지 않았습니다 . H=0..gets.to_i코드를 작성할 때 시도했지만 작동하지 않는 것 같습니다 (분명히 다른 이유로 있었어야합니다).
Cristian Lupascu

1
여전히 7 자 이상 줄일 수있는 두 가지 점 : 1) map대신 each2) z=->...대신 사용할 수 있습니다 def z...end.
Howard

@Howard 감사 합니다. 변경 map대신 적용했습니다 each. 그러나 람다 구문의 경우 사용법이 대신 z형식이어야 하므로 문자 수에 비트를 추가 해야한다고 생각합니다 . 빠진 것이 있으면 알려주세요. z.call(args)z(args)
Cristian Lupascu

@Howard Nevermind, 방금 내가 잃어버린 것을 발견했습니다. 람다 []사용법 을 사용하도록 업데이트하겠습니다 .
Cristian Lupascu

4

자바 스크립트, 410 자 :

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

언 골프 :

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

기발한, 440 자:

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 처음 두 입력 라인은 실제로 관련이 없으며 다음 라인의 크기가 올바른 것으로 가정했습니다. 나는 또한 기회가 생겼을 때 몇 가지 문자를 더 잘라낼 수 있다고 생각합니다!


1
m의 선언 m={22:"b",28:"d",13:"Y",7:"F",20:";",5:"V",6:">",12:"<",4:"@"}을 바꾸고 m의 아래 첨자 를 다음으로 변환 parseInt()하십시오 m[parseInt(y[d](''),2)]. 크기가 373 자로 줄어 듭니다.
manatwork 2016 년

3

파이썬, 259 자

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

프로그램은 입력을 단일 문자열 I(줄을 구분하는 공백 포함) 로 읽고 문자와 그 주변의 4 개의 문자를 포함하는 5 개의 튜플 목록을 압축 한 다음 문자열 색인을 사용하여 결과 문자를 찾습니다.


3

PHP - 359 330 282 268 257 자

<?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 로컬에 저장된 테스트 파일에 Windows 스타일 EOL이있어 작동하지 않았습니다 \r\n. 유닉스 스타일 EOL과 작동하도록 코드를 업데이트했습니다 \n.
Rusty Fausak

좋아, 지금 작동하는 것 같습니다.
PhiNotPi

2

파이썬, 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 및 샘플 2에서 테스트, 맨 위에있는 Ruby 솔루션의 출력과 차이점 :

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)));}
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.