アンチエイリアスASCIIアート


33

バックグラウンド

ASCIIアートとは、ASCIIテキストを使用して形状を形成することにより画像を作成する方法です。

エイリアシングは、文字のサイズであるASCIIアートの大きな「ピクセル」によって作成される効果です。画像はブロック状になり、見にくくなります。アンチエイリアスは、グラデーションを作成し、ASCIIアートのハードエッジを柔らかくすることにより、この効果を取り除きます。

チャレンジ

あなたの挑戦は、ASCIIアートの一部を取り、アンチエイリアスされたバージョンを出力する、可能な限り短いプログラムを書くことです。

どのようなアンチエイリアシングですか?

ASCIIアートはすべて、スペースと非空白の2種類のシンボルで構成されます。空白文字以外の文字ごとに、プログラムは、アンチエイリアス処理が必要な位置にあるかどうかを判断する必要があります。正しい場合は、正しい文字に置き換える必要があります。そうでない場合、キャラクターは同じままです。

キャラクターにアンチエイリアスをかける必要があるかどうか、どのようにしてわかりますか?答えは、キャラクターのすぐ上、下、左、右にあるキャラクターに依存します(対角線ではありません)。ここでアンチエイリアシングが、必要とされるときのチャートである?x任意の非空白文字を表すことができますが。

 x? ->  d?
 ?      ? 


?x  -> ?b 
 ?      ? 

 ?      ? 
?x  -> ?F 


 ?      ? 
 x? ->  Y?



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

 ?      ? 
 x  ->  V 



?x  -> ?> 



 x? ->  <?



 x  ->  @ 

入力(および例の事前アンチエイリアシングASCIIアート)

最初に、2行の入力(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文字のみで記述し、プログラムからアートを作成できるようにする必要があります。それ以外は、標準のコードゴルフ規則が適用されます。


まだ答えがないので、アンチエイリアスチャートの1文字を変更しました。良く_なった;からです
PhiNotPi

これは私のお気に入りのコードゴルフの質問かもしれません。4種類の素晴らしいソリューションに取り組んでいます。
captncraig

混乱していますが。対角線はカウントしないと言いますが、ダイアグラムにはすべて対角線を埋める疑問符が表示されます。私が例で見るものから、側面だけを見るのは安全かもしれませんが、私は混乱しますか?対角線は重要ですか?
captncraig

いいえ、対角線は重要ではありません。チャートから対角線を削除すると、おそらくより明確になります。
PhiNotPi

あなたの例にはタイプミスがあるかもしれません。右側の列の内側の端にYがあるはずです。D:しかし、この1、良い質問に答えを考え出す楽しんだ
エド・ジェームズ

回答:


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

zipアプローチを取る別のRuby実装。オンラインで実行されている2番目の例見ることができます

編集:を使用すると、readlines12文字が保存されます。


6

ルビー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

サンプル1:http : //ideone.com/PfNMA

サンプル2:http : //ideone.com/sWijD


1)範囲定義を囲む括弧は不要です。2)0..h-1と書くことができます0...h。3)G=[];h.times{G<<gets}G=readlines、C#コードと同様にとして記述できます。4)ステップ3の後、変数hは使用できなくなり、hとwの値は1回だけ使用されるため、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文字を意味します:ideone.com/CiW0l
manatwork

わあ、ありがとう!私が行うべき改善点があった知っていたが、そこにいたとは思わなかったその多くが。私はH=0..gets.to_iコードを書いたときに試しましたが、うまくいかないようでした(明らかに、他の理由のためだったに違いありません)。
クリスチャンルパスク

1
それでもあなたは、少なくとも7つの文字で減らすことができる2つのポイント:1)あなたが使用できるmapのではなく、each2)z=->...の代わりにdef z...end
ハワード

@Howardありがとう、変更のmap代わりに適用しましたeach。ただし、ラムダ構文の場合、の代わりにを使用する必要があり、文字カウントにビットが追加zされると思います。何か足りない場合は教えてください。z.call(args)z(args)
クリスチャンルパスク

@Howard Nevermind、不足しているものを見つけました。ラムダの[]使用法を使用するように更新します。
クリスチャンルパスク

4

Javascript、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最初の2つの入力行は実際には無関係であり、後続の行のサイズは正しいと仮定しました。また、チャンスがあれば、これからさらにいくつかのチャーを切り落とすことができるかもしれないと考えています!


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文字に縮小されます。
マナトワーク

3

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

プログラムは入力を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。UNIXスタイルのEOLで動作するようにコードを更新しました\n
さびたFausak

わかりました、それは今働いているようです。
PhiNotPi

2

Python、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:]))

サンプル2のWCとテストは、上部の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.