` perm_comb.awl: Permutations/combinations generators ` ` Permuting numbers from 0..N ` ! permute (N action) : [index total] = { index = array (N); total = 0; ` Recursive permutations generator ` ! r_perm (n) : [i] = n <> N ? { index{n} = n; n ++; for_dec (i, 1..n, index{i} :=: index{i-1}); r_perm (n); for_inc (i, 1..n, { index{i} :=: index{i-1}; r_perm (n) }) } : `... or end of recursion (call 'action' with 'index') ` { action ! index; ++ total; }; ` -- r_perm ` ` Entry point ` r_perm (0); total }; ` -- permute ` ` Enumerating ordered selections of M numbers from 0..N ` ! combine (M N action) : [index total] = { index = array (M); total = 0; ` Recursive combinations generator ` ! r_comb (m n) : [i] = { m <> M ? { for_inc (i, n .. m + N-M + 1, { index {m} = i; r_comb (m+1, i+1); }); } : `... or end of recursion (call 'action' with 'index') ` { action ! index; ++ total; } ` -- r_comb ` }; ` Entry point ` r_comb (0, 0); total }; ` -- combine ` ` Charater at i in str: ` ! char_at (str i) = str$[i .. i+1]; ` Permute characters in the string Str ` ! permute_str (Str) : [Len Total] = { Len = #$Str; <: ["Permutations of " Str " (length=" Len "):\n"]; Total = permute (Len, ! (index) : [i] = { <: "["; for_inc (i, Len, <: char_at(Str, index{i})); <: "]\n"; }); <: ["(total: " Total ")\n"]; }; permute_str ('ABCDF'); <: "\n"; ` Find combinations of Count characters in the string Str ` ! combine_str (Count Str) : [Len Total] = { Len = #$Str; <: ["Combinations of " Str " (length=" Len ") by " Count ":\n"]; Total = combine (Count, Len, ! (index) : [i] = { <: "["; for_inc (i, Count, <: char_at(Str, index{i})); <: "]\n"; }); <: ["(total: " Total ")\n"]; }; combine_str (4, 'ABCDEFGH'); <: "\n"; combine_str (3, 'abcdefg'); <: "\n";