(define-macro (ASSERT ?form)
'(begin) )
(use srfi-4)
(use iset)
(eval-when (compile)
(declare
(usual-integrations)
(inline)
(fixnum)
(no-procedure-checks-for-usual-bindings)
(export
make-chase-sequence
make-chase-sequence-index-swapper
for-each-permutation
fold-permutation) ) )
(define (make-chase-sequence cnt cut #!optional (swpprc noop))
(let* ([n (if (positive? cnt) cnt 1)]
[k (if (< 0 cut n) cut n)]
[s (- n k)]
[r (if (positive? s) s k)] )
(let ([fence (make-bit-vector (add1 n) #t)] [delta (make-bit-vector n #f)] ) (do ([i s (add1 i)])
[(= i n)]
(bit-vector-set! delta i #t) )
(letrec (
[exchange
(lambda (lt rt)
(ASSERT (bit-vector-ref delta lt))
(bit-vector-set! delta lt #f)
(ASSERT (not (bit-vector-ref delta rt)))
(bit-vector-set! delta rt #t)
(swpprc lt rt) ) ]
[move-right-one
(lambda (j)
(ASSERT (> j 0))
(let ([r1 (sub1 j)])
(exchange j r1)
(cond [(and (= r j) (> j 1))
(set! r r1) ]
[(= r r1)
(set! r j) ] ) ) ) ]
[move-right-two
(lambda (j)
(ASSERT (> j 1))
(let ([r2 (- j 2)])
(if (bit-vector-ref delta r2)
(move-right-one j)
(begin
(exchange j r2)
(cond [(= r j)
(set! r (if (> j 2) r2 1)) ]
[(= r r2)
(set! r (sub1 j)) ] ) ) ) ) ) ]
[move-left-one
(lambda (j)
(ASSERT (> j 0))
(let ([r1 (sub1 j)])
(exchange r1 j)
(cond [(and (= r j) (> j 1))
(set! r r1) ]
[(= r r1)
(set! r j) ] ) ) ) ]
[move-left-two
(lambda (j)
(ASSERT (> j 0))
(if (bit-vector-ref delta (sub1 j))
(move-left-one j)
(begin
(ASSERT (> j 1))
(let ([r2 (- j 2)])
(exchange r2 j)
(cond ((= r r2)
(set! r j) )
((= r (sub1 j))
(set! r r2) ) ) ) ) ) ) ]
[gen-partition
(lambda ()
(swpprc 'init)
(let ([j (do ([i r (add1 i)])
[(bit-vector-ref fence i) i]
(bit-vector-set! fence i #t) ) ] )
(and (not (= j n))
(let ([aj (bit-vector-ref delta j)])
(bit-vector-set! fence j #f)
(if (odd? j)
(if aj
(move-right-one j)
(move-left-two j) )
(if aj
(move-right-two j)
(move-left-one j) ) ) ) ) ) ) ]
[next-partition
(lambda ()
(set! next-partition gen-partition)
#t ) ] )
(lambda ()
(and (next-partition)
delta) ) ) ) ) )
(define (u32vector-swap! u32v i j)
(let ([oi (u32vector-ref u32v i)])
(u32vector-set! u32v i (u32vector-ref u32v j))
(u32vector-set! u32v j oi) ) )
(define (make-chase-sequence-index-swapper cnt cut)
(let* ([n (if (positive? cnt) cnt 1)]
[k (if (< 0 cut n) cut n)]
[s (- n k)] )
(let ([swaps 0]
[comb (make-u32vector n)]
[ix (make-u32vector n)])
(do ([i 0 (add1 i)])
[(= i n)]
(u32vector-set! comb i i)
(u32vector-set! ix i i) )
(letrec (
[adjacent-swap
(lambda (i)
(ASSERT (and (<= 0 i) (< i (sub1 n))))
(let ([i1 (add1 i)])
(u32vector-set! ix (u32vector-ref comb i) i1)
(u32vector-set! ix (u32vector-ref comb i1) i)
(u32vector-swap! comb i i1)
(ASSERT (= (u32vector-ref ix (u32vector-ref comb i)) i))
(ASSERT (= (u32vector-ref ix (u32vector-ref comb i1)) i1))
(set! swaps (add1 swaps)) ) ) ]
[move
(lambda (f t)
(ASSERT (and (>= f 0) (< f n)))
(ASSERT (and (>= t 0) (< t n)))
(if (< f t)
(do ([i f (add1 i)])
[(= i t)]
(adjacent-swap i) )
(do ([i (sub1 f) (sub1 i)])
[(< i t)]
(adjacent-swap i) ) ) ) ]
[exchange
(lambda (lt rt)
(ASSERT (and (>= lt 0) (< lt n)))
(ASSERT (and (>= rt 0) (< rt n)))
(ASSERT (>= (u32vector-ref ix lt) s)) (move (u32vector-ref ix lt) s) (ASSERT (< (u32vector-ref ix rt) s)) (move (u32vector-ref ix rt) (sub1 s)) (adjacent-swap (sub1 s)) ) ] [get-index
(lambda (i)
(and (< -1 i n)
(u32vector-ref comb i) ) ) ] )
(lambda args
(cond [(null? args)
get-index]
[(= 2 (length args))
(exchange (car args) (cadr args))]
[else
(set! swaps 0)] ) ) ) ) ) )
(define (for-each-permutation idxfnc prc)
(let loop ([i 0])
(and-let* ([j (idxfnc i)])
(prc i j)
(loop (add1 i)) ) ) )
(define (fold-permutation idxfnc fnc int)
(let loop ([i 0] [acc int])
(let ([j (idxfnc i)])
(if j
(loop (add1 i) (fnc i j acc))
acc ) ) ) )
(define (bit-vector-display bv #!optional (len (bit-vector-length bv)))
(display "#<")
(let ([len1 (sub1 len)])
(let loop ([i 0])
(display (bit-vector-ref bv i))
(if (< i len1)
(begin
(display #\space)
(loop (add1 i)) )
(display #\>) ) ) ) )
(define (print-indicies idxfnc)
(for-each-permutation idxfnc (lambda (i j) (print i #\space j))) )
(define (print-permutation prmprc #!optional swpprc vec)
(and-let* ([delta (prmprc)])
(bit-vector-display delta 5) (newline)
(when swpprc
(if vec
(begin
(for-each-permutation (swpprc)
(lambda (i j)
(display (vector-ref vec j)) (display #\space)))
(newline) )
(print-indicies (swpprc)) ) )
#t ) )
(define (factorial n)
(let loop ([n n] [m 1])
(if (zero? n)
m
(loop (sub1 n) (* m n)) ) ) )
(define (permutation-count n r)
(/ (factorial n) (factorial (- n r))) )
(define (combination-count n r)
(/ (factorial n) (* (factorial r) (factorial (- n r)))) )