ドラゴンカーブを描く


19

今日のタスク:ドラゴンカーブを描く!

場合は、あなたがドラゴンカーブがあるかわからない、ここに入門ViHartビデオです(本当にクールな、見てください!)

あなたの仕事:ドラゴンカーブを描き、少なくとも9回繰り返します。1〜9の反復を表示する必要はありません。(少なくとも)9つの反復を完了した後に生成される最終曲線を表示するだけです。曲線は、曲線上の点を結ぶ直線として描画する必要があります。出力は、9回以上の繰り返し(反射、回転、スケーリング、線幅、線の色、背景色の変化まで)を示す以下の画像のいずれかに一致する必要があります。出力は、個々の行とそれらが形成する「ボックス」を互いに区別できるほど十分に大きくなければなりません。曲線内で2本の線が交差しない場合、それらは出力の同じピクセルまたは隣接するピクセルを占有してはなりません(それらの間に背景のピクセルが少なくとも1つ表示されている必要があります)。画像を画面に表示するか、画像をファイルに保存することができます。出力はグラフィカルでなければなりません-ASCIIアートにすることはできません。

ただし、バイト単位の最短コードが優先されますが、ライブラリのディレクティブをバイトカウントに含めることはできません。また、投稿前に記述されている場合は、選択した言語用に記述されたグラフィックライブラリまたはその他のライブラリを使用できます。

プログラムの出力の画像を含めてください。

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

ビデオを視聴した場合は、この段落をスキップしてください。ビデオを視聴しないことにした人のために、ドラゴンカーブの最初の12回の繰り返しを以下に示します。このタスクの目的上、ドラゴンカーブは次のルールによって生成されるカーブです。現在のカーブの終点を取得し、その終点を中心に90度回転した2つ目のカーブを作成して、オリジナルの終点が曲線は新しい曲線の開始点であり、2つの曲線を結合してそれらが交わる単一の曲線にします。以下に示す画像では、各反復の終点を中心に前の反復を時計回りに90度回転させることにより、新しい反復がそれぞれ生成されます。曲線が画面に表示されるとき、どの終点が「終点」としてカウントされるかは明らかではありませんが、曲線が点の配列として格納される場合、「終点」を最後の点として定義するのは簡単です配列。

アスキーアートは高く評価されていますが、受け入れられていません。これはアスキーアートではなく、グラフィック出力です。


3
サイジング、色付けなどに関する仕様はありますか?正確な出力なので、少し不明瞭です。
Rɪᴋᴇʀ


6
私は削除ドラゴン・カーブ、何も追加していないようでしたので、タグを
ブルー


3
これは複製ではありません。それを解決するためのプログラミング手法はかなり異なります(ただし、チャコールを除く)。ほとんどの回答では、タートルグラフィックライブラリを使用していますが、これはASCIIコンテキストではまったく機能しません。

回答:


2

x86、MSDOS、16バイト

少し前に、フラクタルを生成するための最小のルーチンとして、これを書いた。実際の反復を使用せず、フラクタル内に含まれるすべての離散ピクセルを直接プロットし、最終画像を表示します。このパックには、他の多くの小さな制作物に含まれています。16バイト版は2014年と、可能な限り小さくドラゴンフラクタルを得るために、私の努力の終わりだった。この32バイトの生産を

六角

14 10 19 CA D1 FA 10 DE 01 D1 CD 10 B4 0C EB F0

コード

S: 
adc al,0x10
sbb dx,cx       
sar dx,0x01 
adc dh,bl
add cx,dx
int 0x10
mov ah,0x0C
jmp short S

スクリーンショット


1
これは...控えめに言っても驚くべきことです。実行するにはどうすればよいですか?
J.アントニオペレス

最も簡単な方法は、オンラインのDosBox twt86.co?c=FBAZytH6EN4B0c0QtAzr8A%3D%3Dです。ここでソースをコピーして、自分でコンパイルできます。古典的な方法は、自分でDosBox(0.74)をダウンロードして実行することです。最も現実的な方法は、MSDosまたはFreeDosブートスティック(Rufus)を取得し、それを実際の#noemuで実行することです;)
HellMood

9

Pythonの2/3、169 167 150 111 98 78バイト

チャレンジ仕様に従って、インポートはバイトカウントに含まれないことに注意してください。

39(!)バイトを保存してくれた@AlexHallと、さらに13バイトを保存してくれた@ nedla2004に感謝します。

from turtle import*
o=[90]
for z in o*9:o+=[90]+[-x for x in o[::-1]]
fd(5)
for i in o:rt(i);fd(5)

リストを生成するか、右(90)と左(-90)を回して開始し、リストを調べてタートルを移動します。

生成された出力: ここに画像の説明を入力してください

編集:これがあまりにも退屈すぎる場合はspeed(0)、最初の直前に追加しfd(5)ます。カメがはるかに速く動くことを除いて、同じように動作します。


写真はいいだろう:)
Kritixi Lithos

出力の写真またはスクリーンショットを投稿できますか?それは、このコードは、画面には何も出力していることでも明らかではない
J.アントニオ・ペレス

あなたのイメージが切り取らしまった
J.アントニオ・ペレス

今すぐ修正する必要があります:)
テオ

@AlexHallありがとう!そのループを短くする方法があったに違いないことを知っていました:)
テオ

8

ロゴ、43バイト

for[i 1 512][fd 9 lt :i/(bitand :i -:i)*90]

http://www.calormen.com/jslogo/#のインタープリターで試してください

これは、質問の画像に一致するように方向を逆にしたことを除いて、私の以前のASCIIアートの答えウィキペディアの式と同じ原理を使用しています。

まず、nをk*(2^m)kが奇数の形式で表現します。n番目のターンの方向は、k mod 4によって決まります。つまり、kを4で割ったときの残りの部分です。kmod 4が1の場合、n番目のターンはR Lです。k mod 4が3の場合、n番目のターンはL R

bitand :i -:iの最下位ビットを見つけiます。我々は分裂ishitftするために、このことにより、i必要な奇数を与え、右の必要量をk。左折と右折を区別する必要はありません。k*90度だけ左に曲がり、回転がモジュロ360演算であるという事実に基づいてモジュロを実行します。

出力

ht必要に応じてカメを隠すために使用します。

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

出力(変更)

以下は、曲線がどのように一本鎖であるかを示しています。

bk 6 for[i 1 512][fd 6 rt :i/(bitand :i -:i)%4*45-90 fd 3 rt :i/(bitand :i -:i)%4*45-90]

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


4

LindenMASM、51バイト

LindenMASMは、私が少し前にチャレンジのために作成した言語であり、Sandboxに永遠に生き続けます。それはの概念を利用しますリンデンマイヤーシステムドラゴンカーブ、フラクタル植物、シェルピンスキーの三角形などを描画します

ソースコードは次のとおりです。

STT
AXI FX
INC 9
SET F 0
RPL X X+YF+
RPL Y -FX-Y
END

これを設定するには n = 6たとえば、は:

STT
AXI FX
INC 6
SET F 0
RPL X X+YF+
RPL Y -FX-Y
END

これにより、Python 3を介して次の画像が生成されますturtle

6世代

Lindenmayerシステムでは最初の反復は単一行であるため、反復にはわずかな番号の違いがあります。これは次のようなものですn = 10

10世代

楽しみのために、これは15世代でどのように見えるかです(MOV 2少し小さくするための命令が追加されています):

15世代

最大20世代(でMOV 0.5)になると、実際に行を見ることができなくなり、作成に多くの手順が必要になります(ペア+--+最適化されません)。以下が得られます。

20代

現在のインタプリタは、より少ない世代のグラフィカルな問題、つまり画面に描画されない可能性があることに注意してください。残念ながら、このインタープリターが作成されたとき、問題はありませんでした。Python3の変更の可能性がこれを引き起こした可能性があります。


4

アンダーロード、196バイト

()()(<svg width="99" height="147">)S(<g transform="translate):S((33,33)">)S((3,0)rotate)*a(*a(~*)*~("><path d="M0h3" stroke="#"/>)~*a(*)**:(-90)a~^~(90)a~^)*::*:**:*^S(</g>)(:*)::*:**:*^S(</svg>)S

低電力のエソランでこの挑戦を試みることは面白いかもしれないと思いました。アンダーロードは、このようなコマンド数が少ない言語ではかなりうまく機能します。

出力は、非常に大きくネストされたタグといくつかのゴルフのショートカットを含むSVGファイルです。これまでのところ、それを表示できるブラウザは見つかりませんでした(Firefoxはロードしようとして数分間ハングし、FirefoxとChromiumの両方が空白の画面を表示します)。ほとんどの画像処理プログラムもロードできません(別の形式への変換が困難になります)が、画像ビューアーEye of Gnome(Ubuntuのデフォルトインストールの一部)にロードできました。それで、私はあなたがそれを見ることができるように画像のスクリーンショットを撮りました(実際の画像は透明な背景を持っていますが、あなたは本当にスクリーンショットを透明にすることはできません):

Underloadのドラゴンカーブのスクリーンショット

画像サイズを明示的に指定する必要があります。画像の適切な方向を選択し、すべてを最小の法定サイズで描画し、チャレンジで指定された最小反復回数を実行すると、99ピクセル幅にちょうど収まる画像が得られ、1バイトを節約できます。そのようにうまくいくといいですね。

画像の描画に使用される一般的なアルゴリズムは、2つの変数を保持することです(Underloadは変数に名前を付けませんが、変数をxおよびyと考えました)。両方とも最初は空です。その後、我々は繰り返し(置き換えるのxyは(と)のx、左折し、前方に移動し、Y)と(X、右折して前進し、Y)。10回の反復後、xyの両方が9反復のドラゴンカーブを保持します。

いくつかのマイクロ最適化とアンダーロード固有のトリックもあります。ループの繰り返しごとにスタックの最上部を乱雑にしないために、xyを関数に結合することから始めます。「連結によって作成された文字列を返す:x、ターン命令、関数引数、move-前方指示、およびy。」この関数はスタック上で1つのスペースしか占有しないため、それを複製し、-90引数として呼び出し、複製の下の戻り値を交換90し、引数としてを呼び出して、xおよび yのスタックの上位2つの要素(これが最も一般的にアクセスしやすい)を超える要素に触れる必要はありません。この関数は実行時にコード生成されます。ジェネレーター自体も実行時にコード生成され<g transform="translate、イメージの原点の設定にも使用される文字列を再利用できるようにします。最初にすべての開始タグを生成し、次にすべての終了タグがjustであるため</g>、単純に文字列を繰り返すことで1024個の終了タグを出力できます。(Underloadで効率的に数字を書くことはそれ自体興味深い問題です。(:*)::*:**:*ただし、おそらく1024を記述する最も効率的な方法であり、「2の(1 + 2×2)×2のべき乗」に変換します。

Underloadにはグラフィックライブラリがないため、固定位置に線を描画し、特定のポイントを中心に画像を回転させる組み合わせを使用してSVGを生成します。ペンを回す代わりに、紙を回します。アイデアは、線を描画する、画像全体を回転する、別の線を描画する、画像を再度回転するなどにより、すべての線が描画されるため、算術やグラフィックライブラリを使用することなく、タートルグラフィックを効果的にシミュレートできることです同じ場所に。もちろん、これは、非常に重くネストされた画像回転タグがいくつかあることを意味し、多くのSVGビューアを混乱させます。

画像のスタイルを設定すると、バイトカウントに対してカウントされるため、画像を表示するために必要な最小限のスタイルを指定する必要がありました。これはであることが判明し、これはstroke="#"多かれ少なかれ「線は何らかの色である必要がある」と解釈されます。これは、黒で描画するように拡張されているようです。(通常、たとえば「#000」などの色を指定します。)デフォルトでは、背景は透明です。ストロークの幅は指定しませんが、Gnomeの目で選択したものはすべて表示されます。

多くのアンダーロードインタープリターはこのプログラムに苦労します。たとえば、Try It Onlineのものは、内部で非常に大きな文字列を生成するためクラッシュします。ただし、元のオンラインのアンダーロードインタープリターは機能します。(興味深いことに、最初の通訳はオンラインであったため、言語はオフラインで使用可能になる前にオンラインで使用可能でした。)

私が少し不安なのは、ここには1023の線分しかないと思われることで、1024が予想されます。最後の線分の1つがこのアルゴリズムで描画されていない可能性があります(代わりに次の反復で描画されます)。それが失格である場合、プログラムを適合させることは可能かもしれませんが、かなり長くなる可能性があります。(とにかく、このチャレンジが競争に勝つというわけではありません。すでにいくつかの短いエントリーがあります。)


4

MATL、26バイト

0J1_h9:"tPJ*h]hYsXG15Y01ZG

2つの軸の異なるスケールが受け入れられる場合、コードは19バイトに削減できます。

0J1_h9:"tPJ*h]hYsXG

以下の図は、等スケール(26バイト)バージョンに対応しています。

上記のコードは、9番目(0ベース)の反復、つまりチャレンジの10番目のイメージを生成します。

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

他の値の場合9は、コードを変更iするか、ユーザー入力として数値を使用するように置き換えます。たとえば、の結果13は次のとおりです。

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

説明

これは、ループを使用して、複雑な平面の曲線が続くステップの配列を徐々に作成します。たとえば、最初の2つのステップは1j(上)と-1(左)です。

各反復で、これまでのステップの配列がコピーされます。配列のコピーが反転され、(90度回転するために)乗算され、元の配列に連結されます。1j

ループの後、ステップの累積合計が実際のポイントを提供し、それが複素平面にプロットされます。

0                          % Push 0
 J1_h                      % Push array [1j, -1]. This defines the first two steps
     9:                    % Push [1, 2, ..., 9]
       "                   % For each
        t                  %   Duplicate the array of steps so far
         P                 %   Reverse
          J*               %   Multiply by 1j
            h              %   Concatenate horizontally to previous steps
             ]             % End
              h            % Concatenate with the initial 0
               Ys          % Cumulative sum
                 XG        % Plot. Complex numbers are plotted with real and imag as x and y
                   15Y0    % Push string 'equal'
                       1ZG % Set equal scale in the two axes

あなたの答えは印象的です:)コードの説明を提供してもいいですか?
J.アントニオペレス

@Jorgeありがとう!完了
ルイスメンドー

指定する「19バイト」バージョンと「26バイト」バージョンは同じです。ここにコピーアンドペーストエラーがあると思いますか?

@ ais523確かに!修正しました。気づいてくれてありがとう。ところで、ここで実際に見ることができます(実験コンパイラ。ページの
更新

3

Mathematica 86バイト

{1,-1}
r=Reverse;Graphics@Line@Nest[Join[l=Last@#;h=#-l&/@#,r[r@#%&/@h]]&,{{0,0},%},9]

それがどのように動作: {1,-1}出力{1,-1}。基本的に「スタックにプッシュ」します。この値はで呼び出すことができます%r=Reverseコードで2回使用しているため、基本的にReverse関数の名前を変更します。Graphics@Line@ちょうどポイントのリストを受け取り、それらを結ぶ線を描画します。問題の本質は、次のコードセグメントで発生しますNest[Join[l=Last@#;h=#-l&/@#,r[r@#%&/@h]]&,{{0,0},%},9]。Lemmeが教えてくれます-そのセグメントはf ****** ckのように複雑です。実行内容NestNest[f,x,9]を呼び出した結果を出力しますf[f[f[f[f[f[f[f[f[x]]]]]]]]]

私のコードでは、この最初の引数fは:Join[l=Last@#;h=#-l&/@#,r[r@#%&/@h]]&、2番目の引数x{{0,0},%}(に評価されます{{0,0},{1,-1}})、3番目の引数はn、ちょうど9(最初の引数を2番目の引数に9回だけ適用します)です。

すべての中で最も複雑な部分は、この最初の引数ですJoin[l=Last@#;h=#-l&/@#,r[r@#%&/@h]]&。これは、ほぼ純粋な構文糖の巨大な混乱です。私はこれのために数学の構文糖を本当に乱用していました。そのコード行は、匿名関数の数学バージョンを表しますが、物事を短縮するために、その匿名関数内で2つの個別の匿名関数を実際に定義しました。うん、合法だよ。分解しましょう。

Join2つの引数を取ります。最初はl=Last@#;h=#-l&/@#で、2番目はr[r@#%&/@h]です。

Joinの最初の引数:「メイン」匿名関数内で#は、曲線の現在の反復におけるすべてのポイントのリストです。つまりl=Last@#;、「入力として受け取ったポイントのリスト内のポイントを取得し、そのポイントを変数に割り当てますl。次のセグメント、h=#-l&/@#もう少し複雑です。それは、「機能があります。この関数は、入力としてポイントを取り、lそこから減算し、結果を返します。次に、入力として受け取ったポイントのリスト内のすべての要素にその関数を適用して、シフトされたポイントのリストを生成し、その新しいリストを変数に割り当てますh

Join:の2番目の引数に r[r@#%&/@h]は、文字通り、これまでに書いた中で最も複雑な構文があります。コードセグメント@#%&/@に次のようなものが含まれているとは信じられません-プログラムの途中で漫画のキャラクターのように呪われているようです!しかし、それを分解することは可能です。要確認- r[x]ポイントのリストを取得し、そのリストを逆の順序で返します。r@#%&は、入力を反転した匿名関数であり、それを格納されている値%(つまり{1,-1})で乗算し、結果を返します。基本的には、入力を90度回転しますが、コードでは可能な限り短くします。次にr@#%&/@h、「h90度回転したすべてのポイントである新しいリストを出力する」ことを意味します。

全体Join[l=Last@#;h=#-l&/@#,r[r@#*%&/@h]]&として、入力としてポイントのリストを受け取り、90度回転したポイントの同じリストに追加して、曲線の次の反復を取得する関数です。これを9回繰り返して、ドラゴンカーブを取得します。次に、結果のポイントのリストが線として画面に描画されます。そして出力:

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


3
私は、ヌルベクトルを記述するための奇妙なトリックが見つかりました:0{,}...ので、作品0 xである0ほぼすべてのためにx{,}のためのシンタックスシュガーです{Null,Null}
マーティンエンダー

3

Python 2、43バイト

この回答は、インポートステートメントを含まない43バイトであり、主にLevel River Stのロゴの回答i/(i&-i)コードでの使用に基づいています。trinket.ioでオンラインでお試しください

from turtle import*
for i in range(1,513):fd(9);rt(90*i/(i&-i))

これが出力の写真です。

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


私の知る限り、総バイト数にimportステートメントのバイト数を含める必要があります。
テオ

1
@Theo、チャレンジ仕様から引用:The shortest code in bytes wins, however include directives for libraries shouldn't be included in the byte count, and you may use graphics libraries or other libraries written for your language of choice if they were written before the posting.
Sherlock9

3

Mathematica、56 55バイト

Graphics@Line@AnglePath[Pi/2JacobiSymbol[-1,Range@512]]

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

説明:OEIS A034947

楽しみのために、ここに19回目の反復のカラーバージョンがあります。

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


2

Mathematica、63バイト

を使用して AnglePath

Graphics@Line@AnglePath[Pi/2Nest[Join[#,{1},-Reverse@#]&,{},9]]

9回の繰り返し


1

HTML + JavaScript、182

<canvas id=C></canvas><script>c=C.getContext("2d")
C.width=C.height=400
s=n=9
x=y=200
for(i=d=0;i<=1<<n;d+=++i/(i&-i))
c.lineTo(x,y),
d&1?y+=d&2?s:-s:x+=d&2?-s:s
c.stroke()</script>


0

Haskell +図、179バイト

import Diagrams.Prelude
import Diagrams.Backend.SVG
d 1=hrule 1<>vrule 1
d n=d(n-1)<>d(n-1)#reverseTrail#rotateBy(1/4)
main=renderSVG"d"(mkWidth 99)$strokeT(d 9::Trail V2 Double)

出力は、透明な背景を持つ99ピクセル幅のsvgファイルです(9ピクセル幅の画像は、太さが大きすぎて何も認識できません)。ここでは、白い背景の上に再スケーリングおよび構成されています。

ドラゴン番号9


0

トッシュ、518バイト

トッシュは Scratchですが、ブロックではなくテキストを使用します。518バイトでは、この答えはおそらくJavaよりもさらに悪いでしょう。

この答えは、@ TheoのPythonの答えと同じロジックを使用していますしますが、Scratch(およびtosh)のリスト機能がひどいため、数字ではなく「L」と「R」の文字列を使用します。

ここでスクラッチプロジェクトとして実行できます。(toshはScratchプロジェクトにコンパイルします)

when flag clicked
set path to "R"
go to x: -50 y: 100
point in direction 90
pen down
set pen size to 2
clear
repeat 9
    set path copy to path
    set path to join (path) "R"
    set i to length of path copy
    repeat length of path copy
        if letter i of path copy = "R" then
            set path to join (path) "L"
        else
            set path to join (path) "R"
        end
        change i by -1
    end
end
set i to 0
repeat length of path
    change i by 1
    if letter i of path = "R" then
         turn cw 90 degrees
    else
         turn ccw 90 degrees
    end
    move 7 steps
end  

説明:

when flag clicked
set path to "R"
go to x: -50 y: 100
point in direction 90
pen down
set pen size to 2
clear

この最初の部分は、緑のフラグがクリックされたときにプログラムを実行させ(when flag clicked)、パス変数を「R」に設定し、スプライトとステージを適切な状態にして描画準備を整えます。

repeat 9
    set path copy to path
    set path to join (path) "R"
    set i to length of path copy
    repeat length of path copy
        if letter i of path copy = "R" then
            set path to join (path) "L"
        else
            set path to join (path) "R"
        end
        change i by -1
    end
end

次に、パス生成コードに進みます。@TheoのPython answerと同じロジックを使用しますが、数字の代わりに「R」と「L」の文字列を使用します。リスト内包表記の代わりにネストされたループを使用します。

set i to 0
repeat length of path
    change i by 1
    if letter i of path = "R" then
         turn cw 90 degrees
    else
         turn ccw 90 degrees
    end
    move 7 steps
end  

最後に、パス変数の各文字を通過し、文字に応じて左または右に回してパスを描画します。

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