arrayslistjl-systems

J and L-systems


I'm going to create a program that can generate strings from L-system grammars.

Astrid Lindenmayer's original L-System for modelling the growth of algae is:

variables : A B  
constants : none  
axiom     : A  
rules     : (A → AB), (B → A)

which produces:

iteration | resulting model
        0 | A
        1 | AB
        2 | ABA
        3 | ABAAB
        4 | ABAABABA
        5 | ABAABABAABAAB

that is naively implemented by myself in J like this:

   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│
└─┴─────────────┘

Step-by-step illustration:

   ('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

By analogy, here is a result of the 4th iteration of L-system that generates Thue–Morse sequence

   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

That is the best that I can do so far. I believe that boxing-unboxing method is insufficient here. This is the first time I've missed linked-lists in J - it's much harder to code grammars without them.

What I'm really thinking about is:
a) constructing a list of gerunds of those functions that build final string (in my examples those functions are constants like 'AB'"0 but in case of tree modeling functions are turtle graphics commands) and evoking (`:6) it,
or something that I am able to code:
b) constructing a string of legal J sentence that build final string and doing (".) it.
But I'm not sure if these programs are efficient.

Any hints as well as comments about a) and b) are highly appreciated!


Solution

  • 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.