雪を作ろう!


18

あなたのタスク:Kochスノーフレークをn番目の深さまで生成します。完全なKochスノーフレークを作成する必要はありません。開始三角形の片側だけです。コッホフレーク上のウィキペディア:https://en.wikipedia.org/wiki/Koch_snowflake

ルール:

  • プログラムは、コッホ雪片の片側をn番目の深さまで生成する必要があります。
  • 出力はASCIIでなければなりません。
  • あなたはあり全体の雪片を生成します。これは必須ではありません。
  • 入力/出力および抜け穴とスタッフの標準ルールが適用されます。
  • すべての文字が互いに適切な場所にある限り、空白は重要ではありません。
  • 最短のコードが勝ちます!

テストケース:

n = 0:

__

n = 1:

__/\__

n = 2:

      __/\__
      \    /
__/\__/    \__/\__

n = 3:

                        __/\__
                        \    /
                  __/\__/    \__/\__
                  \                /
                  /_              _\
                    \            /
      __/\__      __/            \__      __/\__
      \    /      \                /      \    /
__/\__/    \__/\__/                \__/\__/    \__/\__

これが理にかなっているといいのですが。各テストケースで、フラクタルは長さが等しい3つの部分に分割できることに注意してください。また、各スノーフレークの幅は、前世代のスノーフレークの幅の3倍であることに注意してください。


FYI、これはだまされやすい人のいないことが合意された
同志SparklePony

n番目のコッホ曲線の適切なASCII表現が何であるかを適切に定義したとは思わない。
orlp

比率が理にかなっているかどうかはわかりません。__/\__2つの下線で使用される非重複は、各反復を一貫して以前の反復の3倍にしました。下線を1つだけ使用すると、n = 3で本当に厄介になり始める矛盾が生じるようです。中央部分はの結果として、唯一の幅10を有している、例えば、外側部12の幅有する/__\ それがあまりにも窮屈されています。そして、その前でも_/との幅の2倍に拡大しています\
Ørjanヨハンセン

/__\ は、本当に致命的な部分であると思います。アンダースコアは、/andと同じ位置にある必要があるため、下線を引く必要があり\ ます。それが完了すると、物事はn = 1以降から3倍に拡大できます(ただし、n = 0は適合しません。)
ØrjanJohansen

残念ながら、いいえ、n = 3が54 = 2 * 3 ^ 3ではなく52の幅を持っていることから明らかなように、中央部の幅は外側の部分と一致していません。これらのいずれかを試してください。n = 4またはn = 5からしか表示されない部品を含む逆さまのバージョンを含めました。アンダースコアがドロップされる場所は上向きのものとは異なります。
Ørjanヨハンセン

回答:


10

ハスケル308の 300 299バイト

編集:

  • -4バイト:変更zipWith(+)zipWith(-)と調整のエンコーディングとオフセットを、すべて否定記号を処分しました。
  • -1バイト:エンコードをさらに微調整することで、直接パターンマッチングの代わりに複数の変数名を#ドロップできるようになりましたr=reverse
  • -2バイト:にalphanumの代わりに演算子を使用しzipWith(-)ます。
  • -1バイト:o=[0,0]リスト定数を短縮するように定義します。
  • -1バイト:の2つのブランチをマージし?ます。
import Data.List
k n=0?sort(o#(f=<<scanl1(+)(iterate(>>=(:[1,4,1]))[6]!!n)))
x?l@(([_,w],c):r)|x>w='\n':0?l|0<1=([2..w-x]>>" ")++[c|w>x]++w?r
_?_=""
w#((c,l):m)=(l&w,c):r l&(l&w)#m
_#_=[]
f x=zip"_/\\_/\\"([id,r]<*>[0:1:o,[0,1,0,1],o++[1,1]])!!mod x 6<$[1,3..gcd 3x]
(&)=zipWith(-)
r=reverse
o=[0,0]

オンラインでお試しください!(残念なことに、n = 3より大きいものはひどくラップされて読めなくなりますが、それを別のプログラムにコピーして見ることができます。)

バリエーション

使い方

  • kはメイン関数であり、を取り、Int nを返しますString
  • iterate(>>=(:[1,4,1]))[6]名目上との間の数値として、各曲線反復のタートルグラフィックスタイルの連続するライン間のターンを、n個ごとに含む無限リストを生成05ます。各反復は、交互に1,4,1入れ替わった直前の反復です。の6代わりにサブリストが開始する唯一の理由は、回避することによって仕事でトリック0を作ることです。gcdff 0
  • scanl1(+)ターンを「絶対」方向に変換します。モジュロ6までです。A 0は右方向を意味し、それ以降の数値はそれぞれ前から反時計回りに60度です。(まあ、これがASCIIではなく適切な描画であれば、60度になります。)
  • f 絶対方向を(文字、オフセットエンコーディング)ペアのリストに変換します。このペアは、どの文字を曲線に追加するか(水平方向の場合は2ペア、それ以外の場合は1ペア)をエンコードします。
  • #実際の(座標、文字)ペアを生成する(文字、オフセット符号化)対、以前のリストをオペレータ反復。
  • エンコードの原則:
    • からの文字は、_/\名目上、開始コーナーから長方形のセルを通って別の終了コーナーまで引かれた線を表します。
    • セル座標は[y,x]、上から下、左から右の形式であるため、印刷したい順に並べ替えられます。列は1から始まります。を使用した短いベクトル演算には、タプルの代わりにリストが使用され(&)=zipWith(-)ます。
    • コーナーは[y,x]、左上のセルと同じ座標で示されます。これにより、コーナーからその隣接セルへのすべてのオフセットが非負になり、負の定数が回避されます。
    • ただし、すべてのベクトル演算が加算ではなく減算になるように、コーナー座標は否定に渡されます。これにより、他のすべての明示的な符号が回避されます。
    • オフセットエンコードリストである[y1,x1,x2,y2]ところ[y1,x1]文字セルに開始隅から座標オフセットされ、[y2,x2]文字セルに最終コーナーからオフセットされています。これの意味は:
      • 方向のためにエンコードするリスト3。.. 5のためのリストのちょうど逆です0。.. 2、彼らがして生成することができます[id,r]<*>
      • 必要なすべてのベクトル演算は(&)=zipWith(-)、エンコードリストまたはその逆のいずれかを使用して実行できます。
  • (座標、文字)ペアのリストをソートした後、それらはに渡され?、最終的なペアが生成さStringれます。
    • In x?l@(([_,w],c):r) xは、この行に表示される前の文字のx座標です(行0の先頭にある場合)。lは現在のリスト全体、w追加する次の文字のx座標c、文字、r残りのリストです。
    • この段階では、y座標は必要ありません。すべての行には文字が含まれており、すべての行の最初の文字は前の行の終わりの左側にあるため、x座標が減少したかどうかをチェックすることで新しい行の開始が検出されます。
    • アンダースコアのASCII値は\およびよりも大きい/ため、同じ位置にある別の文字と重なる場合は最後にソートされます。したがって、x座標が繰り返されていることを確認することにより、冗長なアンダースコアが検出されます。

いいね!今日、この質問にこれ以上活動がなければ、これを受け入れます。
同志スパークルポニー
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.