ASCII L-sistem oluşturucu


16

Arka fon

Bir L sistemi (veya Lindenmayer sistemi), diğer şeylerin yanı sıra, fraktalları modellemek için kolayca kullanılabilen paralel bir yeniden yazma sistemidir. Bu soru deterministik, bağlamsız L sistemleri ile ilgilidir . Bunlar bir sembol alfabesi, bir ilk aksiyom dizesi ve her alfabe sembolünü yeni bir dizgiye eşleyen bir yeniden yazma kuralları kümesinden oluşur. Kurallar aksiyoma paralel olarak uygulanır ve yeni bir dize oluşturulur. Bu işlem daha sonra tekrarlanır.

Örneğin, "A" aksiyomuna ve A = ABA; B = BBB kurallarına sahip sistem, "ABA", "ABABBBABA", "ABABBBABABBBBBBBBBABABBBABA", vb. Dizelerin dizisini oluşturur. Kısaca, L sistemini tanımlarken alfabe. Ayrıca, açık bir yeniden yazma kuralı olmayan herhangi bir sembolün değişmediği varsayılır (yani A sembolü için varsayılan kural A = A'dır).

L-sistemleri bir tür kaplumbağa grafiği kullanılarak görselleştirilebilir. Geleneksel olarak, kaplumbağa sağa bakmaya başlar. Daha sonra sembollerinin üzerinde yineleme yapılarak bir dize çizilir: F, "bir üniteyi ileriye doğru çek" anlamına gelir, G, "bir üniteyi ileriye taşı" anlamına gelir, a +, "bir açı birimini sola döndür" anlamına gelir ve a -, "bir açı sağa dönüş anlamına gelir birimi". Dizedeki diğer tüm simgeler yok sayılır. Bu sorunun amacı için, açı birimlerinin her zaman 90 ° olduğu varsayılmaktadır.

Görev

Herhangi bir L-sistemi ve bir dizi yineleme göz önüne alındığında, programınız, kutu çizim karakterlerini kullanarak, sonuçta elde edilen dizenin (yukarıda açıklandığı gibi) ASCII görüntüsünü çıkarmalıdır.

  • Parametreler, aksiyom, yeniden yazma kuralları (bir; ayrılmış denklem listesi olarak) ve yeniden yazma yineleme sayısını içeren boşlukla ayrılmış bir dize olarak geçirilir. Örneğin, "FF = FGF; G = GGG 2" girişi "FGFGGGFGF" dizesini oluşturur ve bu nedenle uygun boşluklara sahip dört çizgi çizer.
  • L sistemi tarafından kullanılan semboller, boşluk ve noktalı virgül dışında herhangi bir ASCII karakteri olabilir. Sembol başına en fazla bir açık kural belirtilir (varsayılan yeniden yazma kuralı yukarıda açıklandığı gibi kimlik eşleme olur).
  • Çıktının her zaman en az bir F içerdiğini varsayabilirsiniz.
  • Çıktı , görselleştirmeyi temsil etmek için aşağıdaki UNICODE kutu çizim karakterlerini kullanmalıdır: ─ (U + 2500), │ (U + 2502), ┌ (U + 250C), ┐ (U + 2510), └ (U + 2514) , ┘ (U + 2518), ├ (U + 251C), ┤ (U + 2524), ┬ (U + 252C), ┴ (U + 2534), ┼ (U + 253C), ╴ (U + 2574), ╵ (U + 2575), ╶ (U + 2576) ve ╷ (U + 2577). Örnekler için aşağıya bakın.
  • Çıktı, en üstteki kutu karakterinin üstünde veya en alttaki karakterin altında boş satırlar içermemelidir. Ayrıca, en soldaki kutu karakterinin solunda veya en sağdaki karakterin sağında boşluk içermemelidir. En sağdaki kutu karakterinin ötesine geçmeyen boşluk içeren satırlara izin verilir.

STDIN (veya en yakın alternatif), komut satırı bağımsız değişkeni veya işlev bağımsız değişkeni ile girdi alarak bir program veya işlev yazabilirsiniz. Sonuçlar STDOUT'a (veya en yakın alternatife) yazdırılmalı, bir dosyaya kaydedilmeli veya dize olarak döndürülmelidir.

Örnekler

# Cantor dust
>> "F F=FGF;G=GGG 0"
╶╴
>> "F F=FGF;G=GGG 1"
╶╴╶╴
>> "F F=FGF;G=GGG 2"
╶╴╶╴  ╶╴╶╴
>> "F F=FGF;G=GGG 3"
╶╴╶╴  ╶╴╶╴        ╶╴╶╴  ╶╴╶╴

# Koch curve
>> "F F=F+F−F−F+F 1"
 ┌┐
╶┘└╴
>> "F F=F+F-F-F+F 2"
    ┌┐
   ┌┘└┐
  ┌┘  └┐
 ┌┼┐  ┌┼┐
╶┘└┘  └┘└╴

Programınızı test etmek için diğer örnekler:

# Dragon curve
>> "FX X=X+YF+;Y=-FX-Y n"

# Hilbert curve
>> "A A=-BF+AFA+FB-;B=+AF-BFB-FA+ n"

# Sierpinski carpet
>> "F F=F+F-F-F-G+F+F+F-F;G=GGG n"

İlk ikisi aşağıdaki gibi görünür (@ edc65'in cevabı kullanılarak üretilir):

resim açıklamasını buraya girin resim açıklamasını buraya girin

Bu sayfadaki sistemlerden herhangi birini test edebilirsiniz .

puanlama

En kısa kod (bayt cinsinden) kazanır. Standart kurallar geçerlidir.

Miscellania

Bu meydan okuma Slashes ile Rastgele Bir Yürüyüş çizin . Aslında, sistemi sembol başına birden çok kurala izin verecek şekilde genişletirsek, genişleme yeniden yazma sırasında belirleyici olmayan bir şekilde seçilirse, L sistemi olarak rastgele bir yürüyüşü temsil etmek mümkündür . Bir formülasyon:

"F F=FF;F=F+F;F=F++F;F=F+++F"

Genellikle bitkileri modellerken kullanılan bir diğer yaygın uzantı, [ve] karakterleri geçerli konumu ve açıyı itmek ve patlatmak olarak yorumlamaktır. Çoğu bitki 90 ° 'den küçük açılar kullanır, ancak burada olmayan bir örnek:

"FAX X=[-FAX][FAX][+FAX];A=AFB;B=A"

Bu örneklerde bu örneklerin hiçbirinin desteklenmesine gerek yoktur.

Bu meydan okuma aynı zamanda "Üzgünüm genç adam, ama kaplumbağalar tamamen aşağı!" . Ancak, bu meydan okuma ASCII yerine satır oluşturmayı kullandı ve daha esnek bir sözdizimine izin verdi.

Yanıtlar:


7

JavaScript (ES6), 440 bayt (410 karakter)

F=p=>([a,r,n]=p.split(' '),t=>{r.split(';').map(x=>r[x[0]]=x.slice(2),r={});for(;n--;)a=[...a].map(c=>r[c]||c).join('');u=x=y=0,g=[];for(c of a)c=='+'?[t,u]=[u,-t]:c=='-'?[u,t]=[t,-u]:c<'F'|c>'G'?0:((y+=u)<0?(g=[[],...g],++y):g[y]=g[y]||[],(x+=t)<0?(g=g.map(r=>[,...r]),++x):0,c>'F'?0:g[g[f=t?0.5:2,y][x]|=(3+t-u)*f,y-u][x-t]|=(3+u-t)*f)})(1)||g.map(r=>[for(c of r)' ╶╴─╵└┘┴╷┌┐┬│├┤┼'[~~c]].join('')).join('\n')

Daha az golf

F=p=>{
  [a,r,n]=p.split(' '),
  r.split(';').map(x=>r[x[0]]=x.slice(2),r={}); // set rules
  for(;n--;)a=[...a].map(c=>r[c]||c).join(''); // build string
  t=1,u=x=y=0, // start pos 0,0 start direction 1,0
  g=[[]]; // rendering in bitmap g
  for(c of a)
    c=='+'?[t,u]=[u,-t] // left turn
    :c=='-'?[u,t]=[t,-u] // right turn
    :c=='F'|c=='G'?(     // move or draw
      (y+=u)<0?(g=[[],...g],++y):g[y]=g[y]||[], // move vertical, enlarge grid if needed
      (x+=t)<0?(g=g.map(r=>[,...r]),++x):0, // move horizontal, enlarge grid if needed
      c=='F'&&( // draw: set bits
        f=t?0.5:2,
        g[y][x]|=(3+t-u)*f,
        g[y-u][x-t]|=(3+u-t)*f
      )
    ):0;
  // render bits as box characters
  return g.map(r=>[' ╶╴─╵└┘┴╷┌┐┬│├┤┼'[~~c]for(c of r)].join('')).join('\n')
}

Test edilecek kod snippet'i (Firefox'ta)


Harika (ve hızlı!) Cevap. Soruya ejderha ve hilbert eğrisi çıktılarının ekran görüntülerini ekledim.
Uri Granta

6

Haskell, 568 bayt

import Data.List.Split
p=splitOn
l=lookup
m=maximum
n=minimum
o[h,x]=(h,x)
Just x#_=x
_#x=x
g[s,r,i]=iterate((\c->lookup[c](map(o.p"=")(p";"r))#[c])=<<)s!!read i
u v@(a,x,y,d,e)c|c=='+'=(a,x,y,-e,d)|c=='-'=(a,x,y,e,-d)|c=='G'=(a,x+d,y+e,d,e)|c=='F'=(s(x,y)(d%e)a:s(x+d,y+e)(d?e)a:a,x+d,y+e,d,e)|1<2=v
s p n a=(p,n+(l p a)#0)
1%0=2;0%1=8;-1%0=1;0%(-1)=4
1?0=1;0?1=4;-1?0=2;0?(-1)=8
f z=unlines[[" ╴╶─╷┐┌┬╵┘└┴│┤├┼"!!(l(x,y)q#0)|x<-[n a..m a]]|y<-[m b,m b-1..n b]]where a=map(fst.fst)q;b=map(snd.fst)q;(q,_,_,_,_)=foldl u([],0,0,1,0)$g$p" "z

Test sürüşü:

*Main> putStr $ f "F F=F-F+F+F-F 3"
╶┐┌┐  ┌┐┌┐        ┌┐┌┐  ┌┐┌╴
 └┼┘  └┼┼┘        └┼┼┘  └┼┘
  └┐  ┌┼┼┐        ┌┼┼┐  ┌┘
   └┐┌┼┘└┘        └┘└┼┐┌┘
    └┼┘              └┼┘   
     └┐              ┌┘
      └┐┌┐        ┌┐┌┘
       └┼┘        └┼┘
        └┐        ┌┘
         └┐┌┐  ┌┐┌┘
          └┼┘  └┼┘
           └┐  ┌┘
            └┐┌┘
             └┘

Nasıl çalışır:

  • rewriting (function g): Kuralları bir ilişkilendirme listesine (mektup -> yedek dize) ayrıştırır ve tekrar tekrar aksiyom üzerinde eşlerim.
  • (fonksiyon yolu oluşturma utek aşama için): Bir matris içinde, ancak 4 temel blok şifreler ve bit desenleri gibi (x, y) pozisyonları ile bir ilişki listesinde yolu depolamaz ( , , ve ) değerleri olarak . Yol boyunca mevcut konumu ve yönü takip ediyorum.
  • yolu çizme (işlev f): önce yol listesinden max / min boyutlarını hesaplarım ve sonra [max y -> min y] ve [min x -> max x] üzerinde yineleme yaparım ve çizilecek blokları ararım.

0

ES7, 394 karakter, 424 bayt

F=p=>([a,r,n]=p.split` `,t=>{r.split`;`.map(x=>r[x[0]]=x.slice(2),r={});for(;n--;)a=[...a].map(c=>r[c]||c).join``;u=x=y=0,g=[];for(c of a)c=='+'||c=='-'?[t,u]=[u,-t]:c<'F'|c>'G'?0:((y+=u)<0?(g=[[],...g],++y):g[y]=g[y]||[],(x+=t)<0?(g=g.map(r=>[,...r]),++x):0,c>'F'?0:g[g[f=t?0.5:2,y][x]|=(3+t-u)*f,y-u][x-t]|=(3+u-t)*f)})(1)||g.map(r=>[for(c of r)'╶╴─╵└┘┴╷┌┐┬│├┤┼'[~~c]].join``).join`
`
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.