スラッシュを使用してヒルベルト曲線を描く


30

ヒルベルト曲線はとして表すことができる空間充填フラクタルであるLindenmayerシステムの連続した世代と、このようになります。
ヒルベルト曲線
おかげhttp://www.texample.net/tikz/examples/hilbert-curve/画像のため。

ゴール

stdinから正の整数nを取り、スラッシュ、バックスラッシュ、スペース、改行のみを使用してn次のヒルベルト曲線をstdoutに描画する、可能な最短のプログラム(バイト単位)を記述します。

たとえば、入力が1出力である場合、

 \
\/

入力が2出力の場合

  /
  \/\
/\   \
 / /\/
 \ \
  \/

入力が3出力の場合

       \
     /\/
    /   /\
    \/\ \ \
  /\  / / /
 / /  \/  \/\
 \ \/\  /\   \
\/   / / / /\/
  /\/ /  \ \
  \   \/\ \/
   \/\   \
     / /\/
     \ \
      \/

等々。(行間隔の少ないものに貼り付けると見栄えがよくなります。)

出力には、曲線の端の上または下の改行も、行の末尾のスペースも含めないでください。

回答:


10

ルビー、247 230 205文字

r=?D
y=d=0
z=(1..2*x=2**gets.to_i.times{r.gsub!(/\w/){$&<?H?'-H~+D~D+~H-':'+D~-H~H-~D+'}}-1).map{' '*2*x}
r.bytes{|c|c>99?(z[y-=s=-~d/2%2][x-=1-d/2]='/\\'[d%2]
x+=d/2
y+=1-s):d-=c
d%=4}
puts z.map &:rstrip

Lindenmayer表現を使用したASCII-turtleアプローチ(こちらをお試しください)。

@Venteroにゴルフをありがとう。


もう少しこれをGolfed、あなたが気にしないことを望む:ideone.com/kvcPWT - .map(&:rstrip)「ノー末尾のスペース」の要件を満たすために添加しなければなりませんでした。
Ventero

@Venteroありがとうございます。あなたが私があなたの解決策をとったことを気にしないことを願っています-あなたはマップ引数の周りの括弧を捨てることさえできます。
ハワード14

ああ、もちろん!また、私はちょうどそれがの定義をインライン化することは可能だと認識xしてへの割り当てを短縮yし、d(前と同じリンクを参照)、205文字の合計。
Ventero

12

Python、282

from numpy import*
def r(n):
 x=2**n-2;b=3*x/2+1;c=x/2+1;a=zeros((x*2+2,)*2,int);a[x+1,x+1]=1;a[b,x/2]=a[x/2,b]=-1
 if n>1:s=r(n-1);a[:x,c:b]=rot90(s,3)*-1;a[c:b,:x]|=rot90(s)*-1;a[c:b,x+2:]|=s;a[x+2:,c:b]|=s
 return a
for l in r(input()):print''.join(' /\\'[c] for c in l).rstrip()

これは、再帰的なアプローチを使用して、前の曲線からn次のヒルベルト曲線を構築します。曲線は、スライスと操作を改善するために、2D numpy配列として表されます。

ここではいくつかの例を示します。

$ python hilbert.py
2
  /
  \/\
/\   \
 / /\/
 \ \
  \/
$ python hilbert.py
3
       \
     /\/
    /   /\
    \/\ \ \
  /\  / / /
 / /  \/  \/\
 \ \/\  /\   \
\/   / / / /\/
  /\/ /  \ \
  \   \/\ \/
   \/\   \
     / /\/
     \ \
      \/
$ python hilbert.py
4
              /
              \/\
            /\   \
           / / /\/
           \ \ \  /\
         /\/  \/  \ \
        /   /\  /\/ /
        \/\ \ \ \   \/\
      /\  / /  \ \/\   \
     / /  \/ /\/   / /\/
     \ \/\  /   /\/ /   /\
   /\/   /  \/\ \   \/\ \ \
  /   /\/ /\  / / /\  / / /
  \/\ \  / /  \/ / /  \/  \/\
/\   \ \ \ \/\   \ \/\  /\   \
 / /\/  \/   / /\/   / / / /\/
 \ \  /\  /\/  \  /\/ /  \ \
  \/  \ \ \  /\/  \   \/\ \/
    /\/ / / /   /\ \/\   \
    \   \/  \/\ \ \  / /\/
     \/\  /\  / / /  \ \
       / / /  \/  \/\ \/
       \ \ \/\  /\   \
        \/   / / / /\/
          /\/ /  \ \
          \   \/\ \/
           \/\   \
             / /\/
             \ \
              \/

5

Malsys- 234 221文字

ここでいくつかのLシステムの匂いがします:) MalsysはオンラインのLシステムインタープリターです。これは本当に深刻なエントリではありませんが、このソリューションはやや興味深いと感じました。

Malsysの構文は、多くの長いキーワードが含まれているため、ゴルフにはあまり適していませんが、それでも非常に短く、読みやすく、表現力があります。

lsystem HilbertCurveAscii {
    set symbols axiom = R;
    set iterations = 5;
    set rightAngleSlashMode = true;
    interpret F as DrawLine;
    interpret + as TurnLeft;
    interpret - as TurnRight;
    rewrite L to + R F - L F L - F R +;
    rewrite R to - L F + R F R + F L -;
}
process all with HexAsciiRenderer;

http://malsys.cz/g/3DcVFMWn

通訳者:http : //malsys.cz/Process

ゴルフバージョン:

lsystem H{set symbols axiom=R;set iterations=3;set
rightAngleSlashMode=1;interpret.as DrawLine;interpret+as
TurnLeft;interpret-as TurnRight;rewrite L to+R.-L.L-.R+;rewrite
R to-L.+R.R+.L-;}process H with HexAsciiRenderer;

そして、アスキーの六角形のゴスパー曲線はどうですか?:)

      ____
 ____ \__ \
 \__ \__/ / __
 __/ ____ \ \ \
/ __ \__ \ \/
\ \ \__/ / __
 \/ ____ \/ /
    \__ \__/
    __/

http://malsys.cz/g/ae5v5vGB


2

JavaScript(ES6)313 340

編集 本当に悪い習慣を使用していくつかの文字を削除しました-関数Hからの戻り値の代わりにグローバル変数wのように

各x、yのx、y位置を距離d(Wikipediaを参照)に変換し、最も近い位置が接続されているかどうかを確認します。

FireFoxコンソールでテストします。ポップアップを介した入力、console.logを介した出力。

画像の上または下に後続スペースや改行はありません。しかし、各行は改行で終了しています。これがアスキーのアートイメージを作成する正しい方法だと思います。

n=1<<prompt(),d=n-1
H=(s,x,y)=>{for(w=0;s>>=1;)p=x&s,q=y&s,w+=s*s*(3*!!p^!!q),q||(p&&(x=s-1-x,y=s-1-y),[x,y]=[y,x])}
for(r=t='';++r<d+n;t+='\n')for(r>d?(x=r-d,f=x-1):(f=d-r,x=0),t+=' '.repeat(f),z=r-x;x<=z;)
h=H(n,y=r-x,x)|w,H(n,y,x-1),x?t+=' \\'[h-w<2&w-h<2]:0,H(n,y-1,x++),y?t+=' /'[h-w<2&w-h<2]:0
console.log(t)

alert代わりにを使用して、一部の文字を保存できますconsole.log。またfor、4行目の後に余分なスペースがあり、最後の改行を削除できるはずです。
ボブ14

@Bobはい、実際には15文字以上を節約できますが、とにかく300を超えるIMを見ることはあきらめました。画像が固定ピッチフォントなしで完全に認識できないので、私は「警告」を使用して好きではない
edc65

2

Perl、270文字

スーパーゴルフ

$_=A,%d=<A -BF+AFA+FB- B +AF-BFB-FA+>,$x=2**($n=<>)-2;eval's/A|B/$d{$&}/g;'x$n;s/A|B//g;map{if(/F/){if($r+$p==3){$y+=$p<=>$r}else{$x+=$r<2?$r-$p:$p-$r}$s[($r-1)%4>1?$x--:$x++][$r>1?$y--:$y++]=qw(/ \\)[($p=$r)%2]}else{($r+=2*/-/-1)%=4}}/./g;map{print map{$_||$"}@$_,$/}@s

それほどゴルフではない

$_=A,%d=<A -BF+AFA+FB- B +AF-BFB-FA+>,$x=2**($n=<>)-2;
eval's/A|B/$d{$&}/g;'x$n;
s/A|B//g;
map{if(/F/){
    if($r+$p==3){$y+=$p<=>$r}else{$x+=$r<2?$r-$p:$p-$r}
        $s[($r-1)%4>1?$x--:$x++][$r>1?$y--:$y++]=qw(/ \\)[($p=$r)%2]
    }else{
        ($r+=2*/-/-1)%=4
    }
}/./g;
map{print map{$_||$"}@$_,$/}@s

Perlをもっとよく理解していれば、おそらくもっとゴルフができるでしょう。1行目に定義された生産ルールを使用して、Lindenmayerシステムアプローチを使用します。


2

APL(Dyalog Unicode)、90バイトSBCS

⎕∘←¨' +$'r''¨↓1↓∘⍉∘⌽⍣4' /\'[{3|(⊢+⍉)2@(¯1 0+3 1×s÷2)s⊢(¯.5×≢⍵)⊖(2×s←⍴⍵)↑⍵,⍨-⊖⍵}⍣⎕⊢2 2⍴0]

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

2 2⍴0 ゼロの2x2行列

{ }⍣⎕ Nを入力し、関数をN回適用します

⍵,⍨-⊖⍵ マトリックスの左に、それ自体の垂直に反転した否定されたコピーを連結します

(2×s←⍴⍵)↑次元(として記憶されるs)が引数の2倍になるようにゼロで埋める

¯.5×≢⍵ パディングゼロの間に挟まれて、垂直方向に中央に配置するために下に回転します

2@(¯1 0+3 1×s÷2) 特定の位置に2を置く-これらは、フラクタルの小さなインスタンス間のリンクスラッシュです。

(⊢+⍉) 転置された自己の行列を追加する

3|モジュロ3; 否定を使用したため、-1≡2(mod 3)および-2≡1(mod 3)に注意してください。

' /\'[ ] 文字列のインデックスとして行列要素を使用します ' /\'

1↓∘⍉∘⌽⍣4 すべての辺から1要素幅の空の余白を切り取ります

行に分割する

' +$'⎕r''¨ それぞれから末尾のスペースを削除します(このチャレンジでは必須です)

⎕∘←¨ それぞれ出力する

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.