Seni ASCII Hari Ini # 2 - Flow Snakes

32

Sebuah Arus Ular, juga dikenal sebagai kurva Gosper , adalah kurva fraktal, tumbuh secara eksponensial dalam ukuran dengan setiap pesanan / iterasi dari proses yang sederhana. Di bawah ini adalah detail tentang konstruksi dan beberapa contoh untuk berbagai pesanan:

Pesanan 1 Alur Ular :

____
\__ \
__/

Pesanan 2 Flow Snake :

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

Pesanan 3 Flow Snake :

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

Konstruksi

Pertimbangkan urutan 1 Alur Ular yang akan dibangun dari jalur yang berisi 7 tepi dan 8 simpul (berlabel di bawah. Diperbesar untuk kelayakan):

4____5____6
 \         \
 3\____2   7\
       /
0____1/

Sekarang untuk setiap pesanan berikutnya, Anda cukup mengganti tepi dengan versi yang diputar dari pola pesanan 1 asli ini. Gunakan 3 aturan berikut untuk mengganti tepi:

1 Untuk tepi horizontal, gantikan dengan bentuk aslinya seperti:

________
\       \
 \____   \
     /
____/

2 Untuk /tepi ( 12dalam konstruksi di atas), ganti dengan versi yang dirotasi berikut:

 /
/   ____
\  /   /
 \/   /
     /
____/

3 Untuk \tepi ( 34dan di 67atas), ganti dengan versi yang dirotasi berikut:

 /
/   ____ 
\   \   \
 \   \   \
  \  /
   \/

Jadi misalnya, urutan 2 dengan simpul dari urutan 1 berlabel akan terlihat seperti

            ________
            \       \
  ________   \____   \6
  \       \      /   /
   \____   \5___/   /   ____
       /            \   \   \
  4___/   ________   \   \   \7
 /        \       \   \  /
/   ____   \____   \2  \/
\   \   \      /   /
 \   \   \3___/   /   ____
  \  /            \  /   /
   \/   ________   \/   /
        \       \      /
         \____   \1___/
             /
        0___/

Sekarang untuk urutan yang lebih tinggi, Anda cukup memecah level saat ini menjadi tepi dengan panjang 1 /, 1 \atau 2 _dan ulangi prosesnya. Perhatikan bahwa bahkan setelah penggantian, simpul umum antara dua tepi berurutan masih bertepatan.

Tantangan

  • Anda harus menulis fungsi dari program penuh yang menerima integer tunggal Nmelalui argumen fungsi STDIN / ARGV / atau yang setara terdekat dan mencetak urutan NSnake Flow pada STDOUT.
  • Bilangan bulat input selalu lebih besar dari 0.
  • Seharusnya tidak ada ruang utama yang bukan bagian dari pola.
  • Seharusnya tidak ada ruang trailing atau ruang trailing yang cukup untuk membentuk pola untuk mengisi persegi panjang batas minimum sepenuhnya.
  • Mengejar baris baru adalah opsional.

Fakta menyenangkan

  • Flow Snakes adalah permainan kata Snow Flakes, yang menyerupai pola ini untuk urutan 2 dan di atasnya
  • Aliran dan Ular benar-benar memainkan bagian dalam pola karena polanya terdiri dari jalur tunggal yang mengalir di seluruh.
  • Jika Anda perhatikan dengan seksama, pola urutan 2 (dan lebih tinggi juga) terdiri dari rotasi pola urutan 1 yang diputar pada simpul umum arus dan tepi sebelumnya.
  • Ada varian Non ASCII dari Flow Snakes yang dapat ditemukan di sini dan di beberapa lokasi lain.

Ini adalah sehingga kode terpendek dalam byte menang!


Papan peringkat

Posting pertama dari seri menghasilkan leaderboard.

Untuk memastikan jawaban Anda muncul, mulailah setiap jawaban dengan tajuk utama, menggunakan templat Penurunan harga berikut:

# Language Name, N bytes

di mana Nukuran kiriman Anda. Jika Anda meningkatkan skor Anda, Anda dapat menyimpan skor lama di headline, dengan mencoretnya. Contohnya:

# Ruby, <s>104</s> <s>101</s> 96 bytes
Pengoptimal
sumber
Jika saya mengerti dengan benar, bentuk 1,2,3 diperbesar 2x, jadi baris bawah dalam 2 harus dibuat dari 4 undescores, bukan 3.
edc65
@ edc65 Bentuk dalam contoh berukuran sempurna. Jika Anda berbicara tentang bagian Konstruksi, ya, itu diperbesar dan ada 3 garis bawah sehingga nomor tepi mengambil tempat ke-4
Pengoptimal
Tetapi tidak ada angka tepi dalam bentuk 2 (di bagian konstruksi, ya). Bagian bawah bentuk 2 harus sama dengan bagian bawah bentuk 1.
edc65
@ edc65 Oh, ini !. Tetap!
Pengoptimal
3
Saya membaca judulnya sebagai "Serpihan Salju" dan bahkan tidak memperhatikan judul sebenarnya sampai Anda meminta perhatian pada perbedaannya.
mbomb007

Jawaban:

4

CJam, 144 byte

0_]0a{{_[0X3Y0_5]f+W@#%~}%}ri*{_[YXW0WW]3/If=WI6%2>#f*.+}fI]2ew{$_0=\1f=~-
"__1a /L \2,"S/=(@\+\~.+}%_2f<_:.e>\:.e<:M.-:)~S*a*\{M.-~3$3$=\tt}/zN*

Baris baru ditambahkan untuk menghindari pengguliran. Cobalah online

Program ini bekerja dalam beberapa langkah:

  1. Fraktal awal (urutan 1) dikodekan sebagai urutan 7 sudut (secara konseptual, kelipatan 60 °) yang mewakili arah gerakan
  2. Fraktal "diterapkan" ke segmen horisontal (urutan 0 fraktal) N kali untuk menghasilkan semua "gerakan" dalam urutan N fraktal
  3. Mulai dari [0 0], gerakan diterjemahkan ke dalam urutan titik dengan koordinat [xy]
  4. Setiap segmen (sepasang poin) dikonversi menjadi 1 atau 2 [xyc] kembar tiga, mewakili karakter c pada koordinat x, y
  5. Persegi pembatas ditentukan, koordinat disesuaikan dan matriks spasi dihasilkan
  6. Untuk setiap triplet, karakter c ditempatkan pada posisi x, y dalam matriks, dan matriks akhir disesuaikan untuk output
aditsu
sumber
Jawaban ini cukup panjang untuk mendapat manfaat dari pengodean byte: goo.gl/D1tMoc
Dennis
@ Dennis Saya tidak yakin saya selesai bermain golf ... dan mengapa Anda meletakkannya di blok?
aditsu
Saya tidak begitu yakin ... Jawaban Anda cukup mengesankan. Saya menghabiskan satu hari penuh untuk mencoba memperbaiki ini.
Dennis
@Dennis Terima kasih; btw, menurut Anda apakah boleh menggunakan karakter yang tidak dapat dicetak / kontrol? Saya biasanya mencoba menghindarinya
aditsu
Jika saya dapat menghindari mereka tanpa menambah jumlah byte, saya lakukan. Tetapi lebih pendek lebih pendek. : P Dalam kasus seperti ini di mana saya kompres kode itu sendiri daripada beberapa string atau array, saya biasanya memasukkan kedua versi dalam jawabannya.
Dennis
16

Python 2, 428 411 388 byte

Yang ini cukup rumit. Pola tidak mempertahankan rasio mereka setelah setiap langkah yang berarti sangat sulit untuk secara prosedural menghasilkan gambar dari pendahulunya. Apa yang dilakukan kode ini, meskipun tidak terbaca setelah beberapa matematika matematika yang intens, sebenarnya menarik garis dari awal sampai selesai menggunakan Dfungsi yang didefinisikan secara rekursif .

Ukurannya juga menjadi masalah, dan saya akhirnya baru mulai di tengah-tengah kotak 5*3**nsisi dan memotong hal-hal setelahnya, meskipun jika saya bisa memikirkan cara yang lebih baik untuk menghitung ukuran saya mungkin mengubahnya.

n=input();s=5*3**n
r=[s*[" "]for i in[0]*s]
def D(n,x,y,t=0):
 if n<1:
    x-=t%2<1;y+=t%3>1;r[y][x]='_/\\'[t/2]
    if t<2:r[y][x+2*t-1]='_'
    return[-1,2,0,1,0,1][t]+x,y-(2<t<5)
 for c in[int(i)^t%2for i in"424050035512124224003"[t/2::3]][::(t^1)-t]:x,y=D(n-1,x,y,c)
 return x,y
D(n,s/2,s/2)
S=[''.join(c).rstrip()for c in r]
for l in[c[min(c.find('\\')%s for c in S):]for c in S if c]:print l
KSab
sumber
Wow, ini luar biasa. Ingin mencoba AAoD # 1?
Pengoptimal
r=[s*[" "]for i in range(s)]-> r=[[" "]*s]*s]akan mencukur beberapa byte
sirpercival
1
@sirpercival sayangnya itu tidak akan berhasil karena cara *mengulangi objek yang bisa berubah .
grc
oh, benar, saya lupa
sirpercival
Anda dapat menyimpan beberapa byte dengan cara inlining l, beralih print'\n'.join()ke mencetak di dalam for for loop, menggunakan return[...][t]+x,, dan menghapus tanda kurung (t%2). Juga, Anda dapat menggunakan min(c.find('\\')%s for c in S)jika Anda mengubah nama daftar Ssehingga tidak menimpa nilai awal s.
grc
12

JavaScript ( ES6 ), 356 362 370

Itu yang sulit ...

Setiap bentuk disimpan sebagai jalur. Ada 6 blok bangunan dasar (3 + 3 mundur)

  • 0diagonal ke kiri ke kanan bawah ( 4mundur)
  • 1bawah diagonal kiri ke atas ( 5ke belakang)
  • 2horizontal kiri ke kanan ( 6mundur)

Untuk masing-masing, ada langkah penggantian yang diterapkan ketika meningkatkan pesanan:

  • 0-> 0645001(mundur 4-> 5441024)
  • 1-> 2116501(mundur 5-> 5412556)
  • 2-> 2160224(mundur 6-> 0664256)

nilai prefilled dalam harray, bahkan jika elemen 4..6 dapat diperoleh dari 0..2 menggunakan

;[...h[n]].reverse().map(x=>x^4).join('')

Untuk mendapatkan bentuk untuk urutan yang diberikan, jalur dibangun dalam variabel p yang menerapkan penggantian berulang kali. Kemudian loop utama iterates pada variabel p dan menggambar bentuk di dalam array g [], di mana setiap elemen adalah baris.
Mulai dari posisi (0,0), setiap indeks dapat menjadi negatif (indeks y pada pesanan tinggi). Saya menghindari indeks y negatif menggeser semua array g setiap kali saya menemukan nilai y negatif. Saya tidak peduli jika indeks x menjadi negatif, karena di JS indeks negatif diizinkan, hanya sedikit lebih sulit untuk dikelola.
Pada langkah terakhir, saya memindai array utama menggunakan .map, tetapi untuk setiap baris saya perlu menggunakan loop eksplisit untuk (;;) menggunakan bvariabel yang menahan indeks x paling sedikit (yaitu <0).
Dalamconsole.log versi ada baris baru yang berguna, yang dapat dengan mudah dibuat baris baru bertukar 2 baris, seperti dalam versi potongan.

f=o=>{
  g=[],x=y=b=0,
  h='064500192116501921602249954410249541255690664256'.split(9);
  for(p=h[2];--o;)p=p.replace(/./g,c=>h[c]);
  for(t of p)
    z='\\/_'[s=t&3],
    d=s-(s<1),
    t>3&&(x-=d,y+=s<2),
    y<0&&(y++,g=[,...g]),r=g[y]=g[y]||[],
    s?s>1?r[x]=r[x+1]=z:r[x]=z:r[x-1]=z,
    t<3&&(x+=d,y-=s<2),
    x<b?b=x:0;
  g.map(r=>
  {
    o+='\n';
    for(x=b;x<r.length;)o+=r[x++]||' '
  },o='');
  console.log(o)
}

Cuplikan berguna untuk menguji (di Firefox):

f=o=>{
  g=[],x=y=b=0,
  h='064500192116501921602249954410249541255690664256'.split(9);
  for(p=h[2];--o;)p=p.replace(/./g,c=>h[c]);
  for(t of p)
    z='\\/_'[s=t&3],
    d=s-(s<1),
    t>3&&(x-=d,y+=s<2),
    y<0&&(y++,g=[,...g]),r=g[y]=g[y]||[],
    s?s>1?r[x]=r[x+1]=z:r[x]=z:r[x-1]=z,
    t<3&&(x+=d,y-=s<2),
    x<b?b=x:0;
  g.map(r=>
  {
    for(x=b;x<r.length;)o+=r[x++]||' ';
    o+='\n'
  },o='');
  return o
}

// TEST

fs=9;
O.style.fontSize=fs+'px'

function zoom(d) { 
  d += fs;
  if (d > 1 && d < 40)
    fs=d, O.style.fontSize=d+'px'
}
#O {
  font-size: 9px;
  line-height: 1em;
}
<input id=I value=3><button onclick='O.innerHTML=f(I.value)'>-></button>
<button onclick="zoom(2)">Zoom +</button><button onclick="zoom(-2)">Zoom -</button>
<br>
<pre id=O></pre>

edc65
sumber
6

Haskell, 265 byte

(?)=div
(%)=mod
t[a,b]=[3*a+b,2*b-a]
_#[0,0]=0
0#_=3
n#p=[352,6497,2466,-1]!!((n-1)#t[(s+3)?7|s<-p])?(4^p!!0%7)%4
0&_=0
n&p=(n-1)&t p+maximum(abs<$>sum p:p)
n!b=n&[1,-b]
f n=putStr$unlines[["__ \\/   "!!(2*n#t[a?2,-b]+a%2)|a<-[b-n!2+1..b+n!2+0^n?3]]|b<-[-n!0..n!0]]

(Catatan: pada GHC sebelum jam 7.10, Anda perlu menambah import Control.Applicativeatau mengganti abs<$>dengan map abs$.)

Jalankan online di Ideone.com

f n :: Int -> IO ()menggambar level nflownake. Gambar dikomputasi dalam urutan bitmap daripada sepanjang kurva, yang memungkinkan algoritma untuk berjalan di ruang O (n) (yaitu, logaritmik dalam ukuran gambar). Hampir setengah dari byte saya digunakan untuk menghitung persegi panjang untuk menggambar!

Anders Kaseorg
sumber
Saya masuk dan berfungsi sekarang! Bagus!
Pengoptimal
Ternyata ini sebelumnya tidak berjalan di Ideone.com karena saya mengasumsikan 64-bit Int. Diperbaiki sekarang (mengorbankan 2 byte).
Anders Kaseorg
Tidak apa-apa karena hal login hanya memerlukan id email saya untuk konfirmasi ..
Pengoptimal
5

Perl, 334 316 309

$_=2;eval's/./(map{($_,"\1"x7^reverse)}2003140,2034225,4351440)[$&]/ge;'x($s=<>);
s/2|3/$&$&/g;$x=$y=3**$s-1;s!.!'$r{'.qw($y--,$x++ ++$y,--$x $y,$x++ $y,--$x
$y--,--$x ++$y,$x++)[$&]."}=$&+1"!eeg;y!1-6!//__\\!,s/^$x//,s/ *$/
/,print for
grep{/^ */;$x&=$&;$'}map{/^/;$x=join'',map$r{$',$_}||$",@f}@f=0..3**$s*2

Parameter diambil pada input standar. Ujilah aku .

nutki
sumber
5

Haskell, 469 419 390 385 365 byte

fungsi f :: Int-> IO () mengambil bilangan bulat sebagai input dan mencetak ular aliran

e 0=[0,0];e 5=[5,5];e x=[x]
f n=putStr.t$e=<<g n[0]
k=map$(53-).fromEnum
g 0=id
g n=g(n-1).(=<<)(k.(words"5402553 5440124 1334253 2031224 1345110 2003510"!!))
x=s$k"444666555666"
y=s$k"564645554545"
r l=[minimum l..maximum l]
s _[]=[];s w(x:y)=w!!(x+6):map(+w!!x)(s w y)
t w=unlines[["_/\\\\/_ "!!(last$6:[z|(c,d,z)<-zip3(x w)(y w)w,c==i&&d==j])|i<-r.x$w]|j<-r.y$w]
Damien
sumber
Ini menghasilkan 2 × angka yang diperbesar. Saya pikir pertanyaannya adalah meminta angka yang lebih kecil di bagian atas, dan hanya menggunakan 2 × angka yang diperbesar untuk menjelaskan bagaimana flownake dibangun.
Anders Kaseorg
Kamu benar. Saya memperbaikinya
Damien
Anda dapat menggunakan $definisi k, dan mengganti (!!)adengan (a!!)yang dapat menghilangkan beberapa tanda kurung. Selain itu, Anda tampaknya tahu banyak trik sendiri. Nice
bangga haskeller
4

C, 479 474 468 427 byte

Saya rasa tidak ada yang mengalahkan Perl dan Haskell, tapi karena belum ada pengiriman C di sini:

#define C char
C *q="053400121154012150223433102343124450553245";X,Y,K,L,M,N,i,c,x,y,o;F(C*p,
int l,C d){if(d){l*=7;C s[l];for(i=0;i<l;i++)s[i]=q[(p[i/7]%8)*7+i%7];return F
(s,l,d-1);}x=0;y=0;o=32;while(l--){c=*p++%8;for(i=!(c%3)+1;i--;) {K=x<K?x:K;L=
y<L?y:L;M=x>M?x:M;N=y>N?y:N;y+=c&&c<3;x-=c%5>1;if(x==X&y==Y)o="_\\/"[c%3];y-=c
>3;x+=c%5<2;}}return X<M?o:10;}main(l){F(q,7,l);for(Y=L;Y<N;Y++)for(X=K;X<=M;X
++)putchar(F(q,7,l));}

Untuk menghemat ruang pada panggilan atoi (), jumlah argumen yang diteruskan ke program digunakan untuk level tersebut.

Program berjalan dalam O (n ^ 3) atau lebih buruk; pertama jalur dihitung sekali untuk menemukan koordinat min / maks, kemudian untuk setiap pasangan (x, y) dihitung sekali untuk menemukan karakter pada lokasi tertentu. Sangat lambat, tetapi menghemat administrasi memori.

Contoh dijalankan di http://codepad.org/ZGc648Xi

Zevv
sumber
Gunakan X,Y,K,L,M,N,i,j,c;sebagai ganti int X,Y,K,L,M,N,i,j,c;dan main(l)bukannyavoid main(int l)
Spikatrix
Ya, terima kasih, saya sudah mencukurnya dan sedikit lagi, saya akan memasang versi baru.
Zevv
Output dalam versi terbaru tampaknya akan dipangkas dan sedikit di ujungnya.
Pengoptimal
Saya mengunggah gumpalan yang salah, ini seharusnya baik-baik saja.
Zevv
4

Python 2, 523 502 475 473 467 450 437 byte

l=[0]
for _ in l*input():l=sum([map(int,'004545112323312312531204045045050445212331'[t::6])for t in l],[])
p=[]
x=y=q=w=Q=W=0
for t in l:T=t|4==5;c=t in{2,4};C=t<3;q=min(q,x);Q=max(Q,x+C);w=min(w,y);W=max(W,y);a=C*2-1;a*=2-(t%3!=0);b=(1-T&c,-1)[T&1-c];x+=(a,0)[C];y+=(0,b)[c];p+=[(x,y)];x+=(0,a)[C];y+=(b,0)[c]
s=[[' ']*(Q-q)for _ in[0]*(W-w+1)]
for t,(x,y)in zip(l,p):x-=q;s[y-w][x:x+1+(t%3<1)]='_/\_'[t%3::3]
for S in s:print''.join(S)

Pffft, menghabiskan biaya 3 jam, tapi menyenangkan untuk dilakukan!

Idenya adalah untuk membagi tugas dalam beberapa langkah:

  1. Hitung semua tepi (dikodekan sebagai 0-5) sesuai urutan penampilan (jadi dari awal ular ke ujung)
  2. Hitung posisi untuk masing-masing tepi (dan simpan nilai min dan maks untuk x dan y)
  3. Bangun string yang terdiri dari (dan gunakan nilai min untuk mengimbangi, sehingga kami tidak mendapatkan indeks negatif)
  4. Cetak senarnya

Berikut adalah kode dalam bentuk ungolfed:

# The input
n = int(input())

# The idea:
# Use a series of types (_, /, \, %), and positions (x, y)
# Forwards:   0: __  1: /  2: \
# Backwards:  3: __  4: /  5: \

# The parts
pieces = [
    "0135002",
    "0113451",
    "4221502",
    "5332043",
    "4210443",
    "5324551"
]
# The final types list
types = [0]
for _ in range(n):
    old = types
    types = []
    for t in old:
        types.extend(map(int,pieces[t]))

# Calculate the list of positions (and store the mins and max')
pos = []
top = False
x = 0
y = 0
minX = 0
minY = 0
maxX = 0
maxY = 0
for t in types:
    # Calculate dx
    dx = 1 if t < 3 else -1
    if t%3==0:
        dx *= 2         # If it's an underscore, double the horizontal size
    # Calculate dy
    top = t in {1, 5}
    dy = 0
    if top and t in {0, 3, 1, 5}:
        dy = -1
    if not top and t in {2, 4}:
        dy = 1
    # If backwards, add dx before adding the position to the list
    if t>2:
        x += dx
    # If top to bottom, add dy before adding the position to the list
    if t in {2,4}:
        y += dy
    # Add the current position to the list
    pos += [(x, y)]
    # In the normal cases (going forward and up) modify the x and y after changing the position
    if t<3:
        x += dx
    if t not in {2, 4}:
        y += dy
    # Store the max and min vars
    minX = min(minX, x)
    maxX = max(maxX, x + (t<3)) # For forward chars, add one to the length (we never end with __'s)
    minY = min(minY, y)
    maxY = max(maxY, y)

# Create the string (a grid of charachters)
s = [[' '] * (maxX - minX) for _ in range(maxY - minY + 1)]
for k, (x, y) in enumerate(pos):
    x -= minX
    y -= minY
    t = types[k]
    char = '/'
    if t % 3 == 0:
        char = '__'
    if t % 3 == 2:
        char = '\\'
    s[y][x : x + len(char)] = char

# Print the string
for printString in s:
    print("".join(printString))

Sunting: Saya mengubah bahasa menjadi python 2, agar kompatibel dengan jawaban saya untuk # 3 (dan juga menghemat 6 byte lebih banyak)

Matty
sumber
Pekerjaan yang baik; satu perbaikan sederhana yang bisa Anda lakukan akan berubah l.extend(x)menjadi l+=x. Anda juga mungkin dapat menggunakan codegolf.stackexchange.com/questions/54/... alih-alih yang .split()Anda gunakan (saya melakukan sesuatu yang serupa dalam jawaban saya)
KSab
@ Berbohong Terima kasih, saya merasa benar-benar bodoh sekarang karena menggunakanextend
Matty
0

Pari / GP, 395

Melompati posisi karakter x, y, dan menghitung karakter apa yang akan dicetak. Upaya moderat untuk meminimalkan, mencetak dengan spasi putih dan komentar dilucuti.

k=3;
{
  S = quadgen(-12);  \\ sqrt(-3)
  w = (1 + S)/2;     \\ sixth root of unity
  b = 2 + w;         \\ base

  \\ base b low digit position under 2*Re+4*Im mod 7 index
  P = [0, w^2, 1, w, w^4, w^3, w^5];
  \\ rotation state table
  T = 7*[0,0,1,0,0,1,2, 1,2,1,0,1,1,2, 2,2,2,0,0,1,2];
  C = ["_","_",  " ","\\",  "/"," "];

  \\ extents
  X = 2*sum(i=0,k-1, vecmax(real(b^i*P)));
  Y = 2*sum(i=0,k-1, vecmax(imag(b^i*P)));

  for(y = -Y, Y,
     for(x = -X+!!k, X+(k<3),  \\ adjusted when endpoint is X limit
        z = (x- (o = (x+y)%2) - y*S)/2;
        v = vector(k,i,
                   z = (z - P[ d = (2*real(z) + 4*imag(z)) % 7 + 1 ])/b;
                   d);
        print1( C[if(z,3,
                     r = 0;
                     forstep(i=#v,1, -1, r = T[r+v[i]];);
                     r%5 + o + 1)]) );  \\ r=0,7,14 mod 5 is 0,2,4
     print())
}

Setiap arang adalah sel pertama atau kedua dari sel segi enam. Lokasi sel adalah bilangan kompleks z yang dipecah menjadi basis b = 2 + w dengan digit 0, 1, w ^ 2, ..., w ^ 5, di mana w = e ^ (2pi / 6) akar keenam akar persatuan. Digit-digit tersebut dipertahankan hanya sebagai pembeda 1 sampai 7 kemudian diambil tinggi ke rendah melalui tabel keadaan untuk rotasi net. Ini dalam gaya kode flownake oleh Ed Shouten (xytoi) tetapi hanya untuk rotasi bersih, tidak membuat angka menjadi indeks "N" di sepanjang jalan. Luasnya relatif terhadap asal 0 di tengah bentuk. Selama batas bukanlah titik akhir, ini adalah tengah dari segi enam 2 karakter dan hanya 1 karakter yang diperlukan. Tetapi ketika ular mulai dan / atau akhir adalah batas X 2 karakter diperlukan, yaitu k = 0 mulai dan k <3 akhir. Pari memiliki "paha depan" seperti sqrt (-3) builtin tetapi hal yang sama dapat dilakukan dengan bagian nyata dan imajiner secara terpisah.

Kevin Ryde
sumber
1
Ini tidak cukup memenuhi aturan tentang spasi putih memimpin dan tertinggal.
Anders Kaseorg
Terima kasih, saya diubah. Haskell Anda mengalahkan saya satu jam hingga x, y loop melakukannya. Seharusnya diposting sebelum menunggu untuk melihat apakah inspirasi lebih lanjut akan datang :-).
Kevin Ryde
Sekarang ujung ular dipotong untuk k = 0, 1, 2. (Matematika itu menjengkelkan seperti itu — aku juga harus menghadapinya.)
Anders Kaseorg
Ah sayang, ketika titik akhir adalah x maksimum. Hmm.
Kevin Ryde