5

我将创建一个可以从L 系统语法生成字符串的程序。

Astrid Lindenmayer 用于模拟藻类生长的原始 L 系统是:

变量:AB  
常数:无  
公理:A  
规则:(A→AB),(B→A)

产生:

迭代 | 结果模型
        0 | 一个
        1 | AB
        2 | ABA
        3 | ABAAB
        4 | 阿里巴巴
        5 | ABAABABABAAB

这是我自己在J中天真地实现的,如下所示:

   algae =: 1&algae : (([: ; (('AB'"0)`('A'"0) @. ('AB' i. ]))&.>"0)^:[) "1 0 1
   (i.6) ([;algae)"1 0 1 'A'
┌─┬─────────────┐
│0│A            │
├─┼─────────────┤
│1│AB           │
├─┼─────────────┤
│2│ABA          │
├─┼─────────────┤
│3│ABAAB        │
├─┼─────────────┤
│4│ABAABABA     │
├─┼─────────────┤
│5│ABAABABAABAAB│
└─┴─────────────┘

分步说明:

   ('AB' i. ]) 'ABAAB' NB. determine indices of productions for each variable
0 1 0 0 1
   'AB'"0`('A'"0)@.('AB' i. ])"0 'ABAAB' NB. apply corresponding productions 
AB
A 
AB
AB
A
   'AB'"0`('A'"0)@.('AB' i. ])&.>"0 'ABAAB' NB. the same &.> to avoid filling
┌──┬─┬──┬──┬─┐
│AB│A│AB│AB│A│
└──┴─┴──┴──┴─┘
   NB. finally ; and use ^: to iterate

以此类推,这是生成 Thue-Morse 序列的 L 系统第四次迭代的结果

   4 (([: ; (0 1"0)`(1 0"0)@.(0 1 i. ])&.>"0)^:[) 0
0 1 1 0 1 0 0 1 1 0 0 1 0 1 1 0

这是迄今为止我能做到的最好的。我认为这里的装箱-拆箱方法是不够的。这是我第一次错过 J 中的链表——没有它们,编写语法要困难得多。

我真正在想的是:
a)构建构建最终字符串的那些函数的动名词列表(在我的示例中,这些函数是常量,'AB'"0但在树建模函数的情况下是海龟图形命令)并唤起(`:6)它,
或者我能够编码的东西:
b)构建一个合法的J句子字符串,构建最终字符串并执行(".)它。
但我不确定这些程序是否有效。

  • 你能告诉我一个更好的方法吗?

非常感谢任何关于a)b)的提示和评论!

4

2 回答 2

5

The following will pad the rectangular array with spaces:

   L=: rplc&('A';'AB';'B';'A')
   L^:(<6) 'A'
A            
AB           
ABA          
ABAAB        
ABAABABA     
ABAABABAABAAB

Or if you don't want padding:

   L&.>^:(<6) <'A'
┌─┬──┬───┬─────┬────────┬─────────────┐
│A│AB│ABA│ABAAB│ABAABABA│ABAABABAABAAB│
└─┴──┴───┴─────┴────────┴─────────────┘

Obviously you'll want to inspect rplc / stringreplace to see what is happening under the covers.

于 2014-11-18T07:29:53.627 回答
2

您可以在左侧参数中使用复数值#来扩展数组而不进行装箱。

对于这个特定的 L 系统,我可能会跳过动名词并使用临时替换:

to  =: 2 : 'n (I.m=y) } y'        NB. replace n with m in y
ins =: 2 : '(1 j. m=y) #!.n y'    NB. insert n after each m in y
L =:  [: 'c'to'A' [: 'A'ins'B' [: 'B'to'c' ]

然后:

    L^:(<6) 'A'
A
AB
ABA
ABAAB
ABAABABA
ABAABABAABAAB

这是一种更通用的方法,它通过使用数字和由常量函数组成的动名词来简化代码:

   'x'-.~"1 'xAB'{~([:,(0:`(1:,2:)`1:)@.]"0)^:(<6) 1
A
AB
ABA
ABAAB
ABAABABA
ABAABABAABAAB

AB 填写在最后以供显示。这里没有装箱,因为我使用 0 作为空值。这些分散在相当多的地方,但-.~"1将它们移除。它确实在右侧用空值填充所有结果字符串。如果您不希望这样,您可以使用<@-.~"1将结果装箱:

   'x'<@-.~"1 'xAB'{~([:,(0:`(1:,2:)`1:)@.]"0)^:(<6) 1
┌─┬──┬───┬─────┬────────┬─────────────┐
│A│AB│ABA│ABAAB│ABAABABA│ABAABABAABAAB│
└─┴──┴───┴─────┴────────┴─────────────┘
于 2014-11-17T18:03:18.137 回答