Читая определенную книгу о функциональном программировании и, в частности, схемах (и Ракетах), я натолкнулся на упражнение, в котором говорится следующее: `
"Write a function 'rp' which takes, as an argument, a list 'lp' of pairs '(a . n)',
where 'a' is either a symbol or a number and 'n' is a natural number,
and which returns the list of all the lists, whose elements are the 'a's defined by
the pairs in 'lp', each one appearing exactly 'n' times."
По некоторым причинам это действительно крипти c , но в основном он запрашивает список всех различных перестановок списка, содержащих n умноженных на число / символ a .
Например: [[(rp '((a . 2) (b . 1))]] = '((a a b) (a b a) (b a a))
Генерировать перестановки, игнорируя часть distinct
, довольно легко, поскольку существует относительно прямое рекурсивное определение:
The list of permutations of an empty list, is a list containing an empty list.
The list of permutations of 3 elements a b c is a list containing the lists of all permutations of
a and b where, for each one, c has been inserted in all possible positions.
, которое я перевел в следующем коде ракетки:
(define permut
(lambda(ls)
(if(null? ls) '(())
(apply append
(map (lambda(l) (insert_perm (car ls) l))
(permut (cdr ls)))))))
(define insert_perm
(lambda(x ls)
(if(null? ls) (list (list x))
(cons (cons x ls)
(map (lambda(l) (cons (car ls) l))
(insert_perm x (cdr ls)))))))
Это работает, но не возвращает различных перестановок. С учетом дубликатов мне кажется намного сложнее. Есть ли простая модификация случая простой перестановки, которую я не вижу? Является ли решение совершенно другим? Любая помощь будет оценена.