That was pretty fun :)
My solution is in OCaml. I generate the Dyck language directly (which is basically what this is).
type color = P | B | C
type dyck = Fork of color * dyck * dyck | Nil
let fork c i n = Fork (c, i, n)
let colors = List.to_seq [P; B; C]
let color_open = function P -> "(" | B -> "[" | C -> "{"
let color_close = function P -> ")" | B -> "]" | C -> "}"
let rec to_string = function
| Fork (c, i, n) -> color_open c ^ to_string i ^ color_close c ^ to_string n
| Nil -> ""
let memo f =
let t = Hashtbl.create 10 in
let rec g x =
try Hashtbl.find t x with
| Not_found ->
let y = f g x in
Hashtbl.add t x y;
y
in g
let ( let* ) x f = Seq.flat_map f x
let generate' recur = function
| 0 -> Seq.return Nil
| n ->
Seq.memoize @@
let* d = Seq.take n @@ Seq.ints 1 in
let* c = colors in
Seq.map_product (fork c) (recur (d - 1)) (recur (n - d))
let generate = memo generate'
let () =
let n = (int_of_string Sys.argv.(1)) / 2 in
Seq.iter (fun d -> print_endline (to_string d)) (generate n)
You can sort the lines alphabetically before comparing.