creating permutation of a list in scheme

♀尐吖头ヾ 提交于 2019-12-04 09:39:15

The permutation algorithm isn't as simple as you imagine, it'll be really, really tricky to write just in terms of the basic list operations you mention, unless you write your own helpers that mirror built-in functions such as map, append (but why not use the built-ins in the first place?).

To get an idea of what needs to be done, take a look at the Rosetta Code page describing several possible solutions, look under the Scheme or Racket links. Here's an adaptation of one of the implementations from scratch shown in the linked page - and besides the basic list operations mentioned in the question, it uses append and map:

(define (permutations s)
  (cond [(empty? s) empty]
        [(empty? (rest s)) (list s)]
        [else
         (let splice [(l '()) (m (first s)) (r (rest s))]
           (append
            (map (lambda (x) (cons m x))
                 (permutations (append l r)))
            (if (empty? r)
                empty
                (splice (cons m l) (car r) (cdr r)))))]))

See how it works:

(permutations '(1 2 3))
=> '((1 2 3) (1 3 2) (2 1 3) (2 3 1) (3 2 1) (3 1 2))

I know it is an old post but following relatively simple and easy to understand solution based on random number checking could be of interest. It uses the permutation factorial formula to determine if all permutations have been collected.

(define (f n k)  ; lists will be from 0..(n-1)
  (define pl '()) ; all permutations list;
  (let loop ((ol '())) ; one permutation list; 
    (define a (random n))  ; 0 to n-1
    (if (member a ol) (loop ol)
        (begin (set! ol (cons a ol))
               (if (< (length ol) k) (loop ol)
                   (if (member ol pl) (loop '())
                       (begin (set! pl (cons ol pl))
                              (if(< (length pl)
                                    (/(factorial n)
                                      (factorial (- n k))))
                                 (loop '())
                                 pl ))))))))

(above code is in Racket- a Scheme derivative)

Testing:

(f 3 2)
(f 3 3)
(f 4 2)

Output:

'((2 1) (1 0) (0 1) (0 2) (1 2) (2 0))
'((2 1 0) (1 0 2) (0 1 2) (1 2 0) (0 2 1) (2 0 1))
'((2 1) (3 0) (1 0) (1 3) (3 2) (2 3) (0 3) (0 1) (0 2) (2 0) (1 2) (3 1))
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!