ヒルベルト曲線を描く


12

ヒルベルト曲線は空間充填曲線の一種であり、基本的に線を平面にマッピングします。線の各点は平面の1つの点にのみ対応し、平面の各点は線の1つの点に対応します。ヒルベルト曲線の反復0〜4が示されています。

0から4までの反復

このタスクの目的:上記で定義したように、ヒルベルト曲線の4番目の反復を描くコードを作成します。コードは完成している必要があります。つまり、ヒルベルト曲線を描く関数を作成する場合、コードはその関数を呼び出す必要があります。出力は、画面に直接表示するか、出力を画像ファイルに書き込むことができます。曲線は回転または反転できますが、線は直角に交差する必要があり、出力を引き伸ばすことはできません。ASCIIアートは高く評価されていますが、受け入れられません。バイト単位の最短コードが勝ちです!


回数は入力ですか?または、少なくとも4つの値を選択できますか?
ルイスメンドー

ASCIIアートはグラフィカルと見なされますか?
ガブリエルベナミー

番号; 申し訳ありません-それは別の質問の重複になるだろう
J.アントニオ・ペレス

@JorgePerez曲線の向きを変えることはできますか?サンプルの垂直反転または90度回転バージョンのように
ルイスメンドー

はい!全体形状は依然として正方形でなければならないが
J.アントニオ・ペレス

回答:


7

R、90バイト

n=scan();a=1+1i;b=1-1i;z=0;for(k in 1:n)z=c((w<-1i*Conj(z))-a,z-b,z+a,b-w)/2;plot(z,t="s")

@Luis Mendoが投稿したリンクで使用されるアルゴリズムの恥知らずなRポート。

以下のためにn=5私たちを得ます:

enter image description here


7

MATL39 38バイト

O5:"tZjJ*JQ-wJq+t2+&y2j+_v2/]XG25Y01ZG

これは、入力として反復回数を取ります。ハードコーディングする場合はi、数字で置き換えます。

プログラムは、ここに示すJonas LundgrenによるMatlabコードの移植版です

結果を以下に示します。MATL Onlineで試すこともできます出力を生成するのに数秒かかります。このコンパイラは実験的なものです。最初に機能しない場合は、ページを更新し、もう一度「実行」を押す必要がある場合があります。

enter image description here

説明

O          % Push 0. This is the initial value of "z" in the original code
5:"        % Do 5 times
  t        %   Duplicate
  Zj       %   Complex conjugate
  J*       %   Multiply by 1j (imaginary unit). This is "w" in the original code
  JQ-      %   Subtract 1+1j
  w        %   Swap: brings copy of "z" to top
  Jq+      %   Add 1-1j
  t        %   Duplicate
  2+       %   Add 2
  &y       %   Duplicate the third element from top
  2j+_     %   Add 2j and negate
  v        %   Concatenate the three matrices vertically
  2/       %   Divide by 2
]          % End
XG         % Plot (in complex plane). The numbers are joined by straight lines
25Y0       % Push string 'square'
1ZG        % Make axis square

あなたのコードがどのように機能するか説明できますか?
J.アントニオペレス

アルゴリズムはリンクとまったく同じです。しかし、説明を追加します
ルイスメンドー

@Jorgeの説明を追加
ルイスメンドー

omg、あなたのベースは私のものよりもはるかに簡単です= /
flawr

@flawr Jonas Lundgrenのクレジット:-)
ルイスメンドー

6

MATLAB、264 262 161バイト

これは、ヒルベルト曲線の「微分」を基本的に計算し、それから「cumsum」を介して「積分」することを除いて、ほとんど同じです。これにより、かなりのバイト数だけコードサイズが削減されます。

function c;plot(cumsum([0,h(1,1+i,4)]));axis equal;end function v=h(f,d,l);v=d*[i*f,1,-i*f];if l;l=l-1;D=i*d*f;w=h(f,d,l);x=h(-f,D,l);v=[x,D,w,d,w,-D,-x];end;end

古いバージョン

これは単なる再帰的なアプローチです。簡単にするために、複素数を使用してベクトル情報を保存しました。部分の曲線を変更できますh(0,1,1+i,4)。最初の引数p=0は初期位置、2番目の引数fは方向(+1または-1)のフラグ、3番目の引数dは曲線を描画する方向/回転、4番目lは再帰の深さです。

function c;hold on;h(0,1,1+i,4);axis equal;end function p=h(p,f,d,l);q=@plot;if l;l=l-1;d=i*d*f;p=h(p,-f,d,l);q(p+[0,d]);p=p+d;d=-i*d*f;p=h(p,f,d,l);q(p+[0,d]);p=p+d;p=h(p,f,d,l);d=-i*d*f;q(p+[0,d]);p=p+d;p=h(p,-f,d,l);else;q(p + d*[0,i*f,1+i*f,1]);p=p+d;end;end

これは、古いバージョンでは次のようになります。

これは、2015bでは次のようになります。

->

1
Matlab R2015bでは、色が 3 未満でプロットされます
ルイスメンドー

ハハとてもクール:)
flawr

@LuisMendo素晴らしいcumsumアイデアでゴルフをすることができました!
-flawr

3

MATLAB / Octave、202バイト

リンクされて いる@LuisMendoバージョン、以前の「手作り」ソリューションよりもずっと短いが、まったく異なるアプローチを使用している。私は今、CWとしてゴルフバージョンをここに投稿しています:

このバージョンは、Lindenmayerシステムアプローチに基づいています。

A=zeros(0,2);B=A;C=A;D=A;n=[0,1];e=[1,0];for k=1:4;a=[B;n;A;e;A;-n;C];b=[A;e;B;n;B;-e;D];c=[D;-e;C;-n;C;e;A];D=[C;-n;D;-e;D;n;B];A=a;B=b;C=c;end;A=[0,0;cumsum(A)];plot(A(:,1),A(:,2));axis off;axis equal

ここに画像の説明を入力してください


3

JavaScript(ES6)、266 ... 233 232バイト

ヒルベルト曲線のSVGレンダリング。

document.write('<svg><path fill=none stroke=red d="M8 8'+(f=(i,s='2',d=x=y=8)=>i?f(i-1,s.replace(/./g,c=>[32410401423,,10432423401][+c]||c)):s.replace(/./g,c=>c-4?(d+=c&1&&c-2,''):`L${x+=4-'4840'[d&=3]} ${y+=4-'0484'[d]}`))(5)+'">')

ニールのおかげで1バイト節約


1
試してくださいfill=none
ニール

2

Python 3、177 175 171バイト

ヒルベルト曲線のLindenmayerシステムの簡単な実装。ゴルフの提案を歓迎します!

編集: Kadeのおかげで-2バイト。ヒルベルト曲線の構築方法の再構築から-3バイト。ETHproductionsのおかげで-1バイト。

from turtle import*;s="a";exec('t=""\nfor c in s:t+=c>"F"and"+-abFF-+baFFba-+FFab+-"[c<"b"::2]or c\ns=t;'*5)
for c in s:
 if"-">c:rt(90)
 elif"F">c:lt(90)
 elif"a">c:fd(9)

ここに画像の説明を入力してください

アンゴルフ

import turtle

hilbert_seq = "a"

for _ in range(5):
    new_seq = ""
    for char in hilbert_seq:
        if char == "a":
            new_seq += "-bF+aFa+Fb-"
        elif char == "b":
            new_seq += "+aF-bFb-Fa+"
        else:
            new_seq += char
    hilbert_seq = new_seq

for char in hilbert_seq:
    if char == "F":
        turtle.forward(9)
    elif char == "+":
        turtle.right(90)
    elif char == "-":
        turtle.left(90)

フォームの作成方法を変更するとt、2バイト節約できますt+=[[c,"+AF-BFB-FA+"][c=="B"],"-BF+AFA+FB-"][c=="A"]。パターンは、ほぼその..使用するためのいくつかの方法があります場合、私は疑問に思う彼ら二人のために同じであるので
カーデ

おそらくに変更if c>"E":if"E"<c:てバイトを保存しますか?
ETHproductions 16

1

MSWLogo(バージョン6.5b)、136バイト

ここで最終的なヒルベルト曲線プログラムに基づいています

to h :n :a :l
if :n=0[stop]
rt :a
h :n-1(-:a):l
fd :l
lt :a
h :n-1 :a :l
fd :l
h :n-1 :a :l
lt :a
fd :l
h :n-1(-:a):l
rt :a
end
h 5 90 9

h反復回数:n(1ベース)、角度:a、長さをとる関数が定義されています:l。これは再帰的であり、:a2つのインスタンスで角度を無効にして自身の下位反復を呼び出して、正しい方向を取得します。

  • rt :alt :aカメ(パスがトレースされている三角形のもの)を右、左に回転させます:aます。
  • fd :l亀を:lステップごとに前進させます。

最後に、関数が呼び出されますh 5 90 9。タートルは2バイト余分に隠すことができますht

(5-1)番目の反復


左上隅で何が起こっていますか?
-flawr

@flawrそれはカメです。を追加することで非表示にできますht
モニカの場合

1

Mathematica 128バイト

Graphics[Line@AnglePath[Total/@Split[Cases[Nest[#/.{-2->(s=##&@@#&)[l={-1,2,0,1,-2,0,-2,1,0,2,-1}],2->s@-l}&,{-2},4],-1|1|0],#!=0&][[;;-2,;;-2]]*Pi/2]]

必要に応じて、上記の4を異なる反復回数に置き換えます。

文字列シーケンスではなく整数シーケンスを使用してLindenmayerシステムとして実行されるため、2番目の生成規則は最初の規則の否定にすぎません。このバージョンは151バイトです。

Jonas LundgrenのMATLABコードのポートはわずか128バイトです。

z=0;Graphics[Line[{Re[#],Im[#]}&/@Flatten[Table[w=I*Conjugate[z];z={w-(a=1+I),z-(b=1-I),z+a,b-w}/2,{k,5}][[5]]]],AspectRatio->1]

Mathematicaの将来のバージョンでは、これは次のように非常に短くなる可能性があります。

Graphics@HilbertCurve[n]

http://mathworld.wolfram.com/HilbertCurve.html


1

LindenMASM、63バイト

LindenMASMの回答を含む別の質問?驚くばかり!

STT
AXI A
INC 5
SET F 0
RPL A -BF+AFA+FB-
RPL B +AF-BFB-FA+
END

繰り返しますが、Pythonのいくつかの描画バグのため、turtleこれを実行しても描画全体が存在しない場合があります。ただし、実際に機能することがわかります。

4回目の反復

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