# По зададено от командния ред число n програмата построява редица от пермутациите # от ред n (т.е. от n члена, в случая букви), в която всеки две съседни пермутации # се отличават една от друга възможно най-малко, а именно – по размяната на само # два, и то съседни, члена. # Пермутациите от ред n за n > 1 се образуват на групи, като при това се използват # пермутациите от ред n-1, също образувани така, че всеки две съседни от тях да се # отличават възможно най-малко. Във всяка група пермутациите от ред n се образуват # от само една пермутация от ред n-1, към която последната по азбучен ред буква се # добавя така, че да заема последователно всички възможни места сред другите букви, # премествайки се отдясно наляво или в обратната посока. При преминаване към следваща # група пермутации от ред n се избира следващата пермутация от ред n-1 и заедно с това # се сменя редът на преместване на последната по азбучен ред буква. # Тази схема на образуване на пермутациите е показана по-долу за редиците при n = 1, # 2, 3 и 4 и по индукция на построението е ясно, че тя наистина осигурява възможно # най-голямата близост между всеки две съседни пермутации във всяка редица. # Удобно е да се приеме, че дори редицата за n = 1 се образува от редицата за n = 0, # която се състои от една пермутация от ред 0 (празна, без членове). # # a──┬─ab──┬─abc──┬─abcd # │ │ │ abdc # │ │ │ adbc # │ │ └─dabc # │ ├─acb──┬─dacb # │ │ │ adcb # │ │ │ acdb # │ │ └─acbd # │ └─cab──┬─cabd # │ │ cadb # │ │ cdab # │ └─dcab # └─ba──┬─cba──┬─dcba # │ │ cdba # │ │ cbda # │ └─cbad # ├─bca──┬─bcad # │ │ bcda # │ │ bdca # │ └─dbca # └─bac──┬─dbac # │ bdac # │ badc # └─bacd # Приема цяло положително число от командния ред, повиквайки perms образува съизраз # за построяване на редицата от пермутации от този ред, поражда и отпечатва тази редица. procedure main(a) local q q := perms(a[1]) every |write(@q) end # По зададено n образува n+1 последователно свързани съизраза, по един за всяка редица # от пермутации – от ред 0, 1, …, n. Всяка от редиците, освен тази за n = 0, се поражда # от съответен екземпляр (повикване) на процедурата genperm, от който е образуван съизраз. # Резултатът от повикването на perms е последният от тези съизрази – той поражда търсената # редица. procedure perms(n) local p, i p := create "" every i := 1 to n do p := create genperm(p,i,&lcase[i]) return p end # От редицата, пораждана от съизраза s, образува следващата редица. Всяка от стойностите, # които доставя съизразът ig, е мястото, което трябва да заеме буквата c сред другите букви # в текущо образуваната пермутация. Следваща пермутация от s се добива само когато получената # от ig стойност е същата като предишната (което става при стойности 1 и m). Всяка породена # пермутация-низ се предава съпрограмно (чрез suspend) на повикващия. procedure genperm(s,m,c) local i, j, ig, t ig := create |((m to 1 by -1) | (1 to m)) j := m while (i := @ig) ~= j | (t := @s) do {j := i; suspend t[1:i]||c||t[i:0]} end