Эту проблему лучше всего рассматривать как матричную проблему, и вложенные циклы for для императивного решения могут быть выполнены функционально.
let Permute n =
let rec Aux (x,y) =
if (x,y) = (n,n) then
[]
else
let nextTuple = if y = n then ((x + 1),1) else (x,(y + 1))
if x = y then
Aux nextTuple
else
(x,y)::(Aux nextTuple)
Aux (1,1)
Это нерекурсивно, поэтому get переполняет стекпримерно на 500, на моей машине.Сделать эту функцию хвостовой рекурсивной почти тривиально.
Время для этого было очень интересным.Эта функция (хвостовая рекурсивная версия) заняла на 50% больше, чем оригинал, а императивное решение снова заняло примерно 3 раза!Да - оригинальное функциональное решение является самым быстрым, это следующее самое быстрое, и понимание императивного списка было самым медленным, приблизительно 1: 1,5 :: 4.Протестировано на самых разных наборах данных.