組み合わせパズルなんかを解くときに楽。かも
permutations-any,permutations*-any
。util.combinationsに追加って感じで*1
(define (but-kth lis k) (receive (head tail) (split-at lis k) (append! head (cdr tail)))) (define (any-with-index pred lis1 . lists) (let1 index -1 (apply any (lambda (item1 . items) (apply pred `(,(inc! index) ,item1 . ,items))) lis1 lists))) (define (permutations-any pred set) (cond ((null? set) (pred set)) ((null? (cdr set)) (pred set)) (else (any-with-index (lambda (ind elt) (permutations-any (lambda (subperm) (pred (cons elt subperm))) (but-kth set ind))) set)))) (define (permutations*-any pred set . maybe-eq) (cond ((null? set) (pred set)) ((null? (cdr set)) (pred set)) (else (let1 eq (get-optional maybe-eq eqv?) (let loop ((i 0) (seen '()) (p set)) (cond ((null? p) #f) ((member (car p) seen eq) (loop (+ i 1) seen (cdr p))) (else (or (permutations*-any (lambda (subperm) (pred (cons (car p) subperm))) (but-kth set i) eq) (loop (+ i 1) (cons (car p) seen) (cdr p))))))))))
まーちゃんと動くかどうかは検証してないんだけれども。
(permutations-any (pa$ apply >) '(10 9 8 7 6 5 4 3 2 1))
はすぐに#t
を返すけど、
(any (pa$ apply >) (permutations '(10 9 8 7 6 5 4 3 2 1)))
はまず10!個のリストを生成するんで終わんない。
-every
も作れよ!ってな!
*1:てかソースがモロパクり