shuffling.scm 1.1 KB

1234567891011121314151617181920212223242526272829
  1. (define-module (shuffling)
  2. #:export (fisher-yates-shuffle)
  3. #:use-module (rnrs base)
  4. #:use-module ((guile) #:select (lambda* λ record-constructor))
  5. #:use-module ((random-number-generator) #:select (make-random-integer-generator))
  6. #:pure)
  7. (define fisher-yates-shuffle
  8. (lambda* (lst #:key (rng (make-random-integer-generator #:seed 12345)))
  9. "Shuffle the given list LST using the optional keyword argument
  10. provided random number generator RNG. If no random number generator is
  11. given, a predetermined one will be used."
  12. (let ([lst-as-vec (list->vector lst)])
  13. (let loop ([result '()]
  14. [elements-to-pick (vector-length lst-as-vec)])
  15. (cond
  16. [(zero? elements-to-pick) result]
  17. [else
  18. (let* ([rand-int (rng elements-to-pick)]
  19. [val (vector-ref lst-as-vec rand-int)])
  20. (vector-set! lst-as-vec
  21. rand-int
  22. (vector-ref lst-as-vec
  23. (- elements-to-pick 1)))
  24. (loop
  25. (cons val result)
  26. (- elements-to-pick 1)))])))))