ASCIIヒルベルト曲線


23

整数n出力を与えられ、文字とを使用したASCII nでのヒルベルト曲線の th番目の反復。_|

以下に、最初の4つの反復を示します。

n=1
 _ 
| |

n=2
 _   _ 
| |_| |
|_   _|
 _| |_

n=3
 _   _   _   _ 
| |_| | | |_| |
|_   _| |_   _|
 _| |_____| |_ 
|  ___   ___  |
|_|  _| |_  |_|
 _  |_   _|  _ 
| |___| |___| |

n=4
 _   _   _   _   _   _   _   _ 
| |_| | | |_| | | |_| | | |_| |
|_   _| |_   _| |_   _| |_   _|
 _| |_____| |_   _| |_____| |_ 
|  ___   ___  | |  ___   ___  |
|_|  _| |_  |_| |_|  _| |_  |_|
 _  |_   _|  _   _  |_   _|  _ 
| |___| |___| |_| |___| |___| |
|_   ___   ___   ___   ___   _|
 _| |_  |_|  _| |_  |_|  _| |_ 
|  _  |  _  |_   _|  _  |  _  |
|_| |_| | |___| |___| | |_| |_|
 _   _  |  ___   ___  |  _   _ 
| |_| | |_|  _| |_  |_| | |_| |
|_   _|  _  |_   _|  _  |_   _|
 _| |___| |___| |___| |___| |_ 

明確化

  • 私の質問は、ヒルベルト曲線の描画スラッシュを使用したヒルベルト曲線の描画にています
  • 下線(間の変換_)と垂直バーは、( |)であるu=2*v-1場合 uの数であり、_Sは、とvの数である|S。
  • 私の元の投稿との一貫性を維持するために、曲線は一番下から始まり、最後で終わる必要があります。
  • 完全なプログラムまたは機能を使用できます。
  • stdout(または同様のもの)への出力。
  • 先行または後続の空白を含めることができます。出力は、例のように整列する必要があります。
  • これはコードゴルフなので、バイト単位の最短回答が勝ちです。

3
投稿にヒルベルト曲線の定義と、ASCIIバージョンの作成方法の正確な仕様を含めてください。
Loovjo 16



@Loovjo「明確化」の下にアンダースコア(_)と垂直バー(|)の長さに関するポイントを追加しました。さらに情報や厳密な定義が必要な場合は教えてください。
Bobas_Pett 16

@shooqie私は、タグ削除
Bobas_Pett

回答:


5

Befunge、444 368 323バイト

&1>\1-:v
0v^*2\<_$00p>
_>:10p\:20pv^_@#-*2g00:+1,+55$
^!-<v*2g000<>$#<0>>-\:v
g2*^>>10g20g+v \ ^*84g_$:88+g,89+g,\1+:00
v#*!-1g02!g01_4^2_
>::00g2*-!\1-:10g-\20g-++>v
87+#^\#p01#<<v!`g01/2\+76:_
vv1-^#1-g01:\_$:2/20g`!
_ 2/^>:10g#vv#`g02/4*3:\+77
v>0p^^/2:/2_
<^2-1-g02</2`#*3:
0g+10p2*:^*3_1
! "#%$
%$"#!
 !!##%
|||_
 _ __

オンラインでお試しください!

ヒルベルト曲線を描く一般的な方法は、一連のストロークとターンとしてパスをたどり、結果をビットマップまたはメモリの一部の領域にレンダリングし、パスが完了したらそのレンダリングを書き出すことです。これは、動作するメモリが2000バイトしかない場合、Befungeでは実行不可能であり、プログラム自体のソースが含まれています。

したがって、ここで採用したアプローチは、指定されたx、y座標に対してどの文字を出力するかを正確に示す式を作成することです。どのようにこの作品を理解するためには、で開始するASCIIレンダリングを無視するのが一番簡単だし、ボックスの文字で構成されたとしてだけでカーブを考える:、と

このような曲線を見ると、右側が左側の正確な鏡であることがすぐにわかります。右のキャラクターは、単に左のパートナーを検索し、水平に反映することにより決定することができる(すなわち、発生の交換され、などです)。

垂直軸を横切る反射を示すレベル3ヒルベルト曲線

次に、左下隅を見ると、下半分が上半分を反映していることがわかります。したがって、下部の文字は単に上記のパートナーを検索し、垂直方向にそれを反映して決定されている(すなわち、発生の交換され、などです)。

左下隅の水平軸を横切る反射を示すレベル3ヒルベルト曲線

このコーナーの残りの半分は、少しわかりにくいです。右側のブロックは、斜めに隣接するブロックの垂直反射から導出できます。

左下隅の右上ブロックをどのように導出できるかを示すレベル3ヒルベルト曲線

また、左側のブロックは、曲線全体の一番左上のブロックの垂直反射から導き出すことができます。

左下隅の左上のブロックの導出方法を示すレベル3ヒルベルト曲線

この時点で残っているのは、左上の角だけです。これは、1反復低いヒルベルト曲線です。理論的には、プロセスをもう一度繰り返す必要がありますが、ちょっとした問題があります。このレベルでは、ブロックの左右半分はお互いの正確なミラーではありません。

そのため、トップレベル以外では、下隅の文字を特殊なケースとして処理する必要があります。この場合、文字はとして反映され文字はとして反映されますます。

左下隅の左上のブロックの導出方法を示すレベル3ヒルベルト曲線

しかし、それ以外は、このプロセスを再帰的に繰り返すことができます。最後のレベルでは、左上の文字をとしてハードコーディングし、その下の文字をます。

曲線の残りの部分がどのように導出されるかを示す一連の画像

特定のx、y座標で曲線の形状を決定する方法ができたので、それをどのようにASCIIレンダリングに変換するのでしょうか?実際には、考えられる各タイルを2つのASCII文字に変換する単純なマッピングです。

  • になる  _(スペースとアンダースコア)
  • になる   (2つのスペース)
  • になる |_(垂直バーとアンダースコア)
  • になる (垂直バープラススペース)
  • になる (再び垂直バープラススペース)
  • になる __(2つのアンダースコア)

このマッピングは最初は直感的ではありませんが、2つの対応するレンダリングを並べて見るとどのように機能するかを見ることができます。

ASCIIアートとしてレンダリングされ、ボックスキャラクターを含むレベル2ヒルベルト曲線

基本的にはこれですべてです。Befungeでこのアルゴリズムを実際に実装することはまったく別の問題ですが、その説明は別の機会に残します。


2

C、267バイト

const n=4,s=1<<n,a[]={1,-s,-1,s};l,p,q;
t(d){d&=3;p-q||printf("%.2s",&"__|      _|       |___ _|_| | | "[l*8+d*2]);p+=a[l=d];}
h(d,r,n){n--&&(h(d+r,-r,n),t(d+r),h(d,r,n),t(d),h(d,r,n),t(d-r),h(d-r,-r,n));}
main(){for(;p=s*s-s,l=1,q<s*s;++q%s||putchar(10))h(0,1,n),t(3);}

オンラインでお試しください!

h()再帰を使用して、hlibert曲線のストロークを生成します。t()ペンの位置pが現在の出力位置と等しい場合にのみストローク文字を印刷しqます。

これは非効率的ですが、簡単です。

曲線が左上から始まる場合、コードを256バイトに減らすことができます。


puts("")代わりにputchar(10)"..."+l*8+d*2代わりに、&"..."[l*8+d*2]そして、n--?h(d+r...-r,n):0代わりにn--&&(h(d+r...-r,n))
-ceilingcat
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.