let rec flipfold f h acc = function
| [] -> acc
| y::ys -> flipfold h f (f y acc) ys;;
let flipmap f h = flipfold (fun x a -> (f x)::a) (fun y a -> (h y)::a) [];;
let rec wordpath alphabet length =
if length <= 1 then map (fun x -> [x]) alphabet
else
let prep xs x = map (fun y -> x::y) @@ wordpath xs (length - 1) in
flatten @@ flipmap (prep alphabet) (prep @@ rev alphabet) alphabet;;
let rec print_path = function
| [] -> ()
print_path @@ wordpath ['a'; 'b'; 'c'] 3;;
b3BlbiBMaXN0OzsKCmxldCByZWMgZmxpcGZvbGQgZiBoIGFjYyA9IGZ1bmN0aW9uCiAgfCBbXSAgICAtPiBhY2MKICB8IHk6OnlzIC0+IGZsaXBmb2xkIGggZiAoZiB5IGFjYykgeXM7OwoKbGV0IGZsaXBtYXAgZiBoID0gZmxpcGZvbGQgKGZ1biB4IGEgLT4gKGYgeCk6OmEpIChmdW4geSBhIC0+IChoIHkpOjphKSBbXTs7CgpsZXQgcmVjIHdvcmRwYXRoIGFscGhhYmV0IGxlbmd0aCA9CiAgaWYgbGVuZ3RoIDw9IDEgdGhlbiBtYXAgKGZ1biB4IC0+IFt4XSkgYWxwaGFiZXQKICBlbHNlCiAgICBsZXQgcHJlcCB4cyB4ID0gbWFwIChmdW4geSAtPiB4Ojp5KSBAQCB3b3JkcGF0aCB4cyAobGVuZ3RoIC0gMSkgaW4KICAgIGZsYXR0ZW4gQEAgZmxpcG1hcCAocHJlcCBhbHBoYWJldCkgKHByZXAgQEAgcmV2IGFscGhhYmV0KSBhbHBoYWJldDs7CgpsZXQgcmVjIHByaW50X3BhdGggPSBmdW5jdGlvbgogIHwgW10gICAgLT4gKCkKICB8IHg6OnhzIC0+IGl0ZXIgcHJpbnRfY2hhciB4OyBwcmludF9jaGFyICdcbic7IHByaW50X3BhdGggeHM7OwoKcHJpbnRfcGF0aCBAQCB3b3JkcGF0aCBbJ2EnOyAnYic7ICdjJ10gMzs7