2014-11-17 3 views
5

Я собираюсь создать программу, которая может генерировать строки из L-system грамматик. оригинальный L-SystemJ и L-системы

Астрид Lindenmayer для моделирования роста водорослей:

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

, который производит:

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

, который наивно реализуется себя в 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 

По аналогии, здесь является результатом 4-й итерации 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 

Это лучшее, что я могу сделать до сих пор. Я считаю, что метод бокса-распаковки здесь недостаточен. Это первый раз, когда я пропустил связанные списки в J - гораздо сложнее кодировать грамматики без них.

Что я на самом деле думаю о том:
а) построение списка герундии тех функций, которые создают конечную строку (в моих примерах этих функциями являются константами, как 'AB'"0 но в случае моделирования функций дерева черепахи графических команд) и вызывая (`:6) его,
или что-то, что я могу ввести в код:
b) построение строки юридического J-предложения, которое строит окончательную строку и делает (".).
Но я не уверен, эффективны ли эти программы.

  • Можете ли вы показать мне лучший подход, пожалуйста?

Любые намеки, а также комментарии о а) и б) высоко ценятся!

ответ

5

Ниже будет коврик прямоугольный массив с пробелами:

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

Или, если вы не хотите, обивка :

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

Очевидно, что вы будете хотеть, чтобы проверить rplc/stringreplace, чтобы увидеть, что происходит под одеялом.

+0

Если производительность не является проблемой, 'rplc' является самым простым способом. – Eelvex

+0

Спасибо, Тикканц. –

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

Чем вы, ваш ответ полезен для меня, однако ответ Тикканца оказался более эффективным как во времени, так и в пространстве. И спасибо, что указали конструкцию '^: (

Смежные вопросы