问题
I would like to code a program that given a list and a percentage, splits the list in two different size lists. It should have random pick of the elements, that way the created lists are always different. These code is able to do that:
(define (clamp x a b)
(max (min x b) a))
(define (split pct xs)
(define pos (exact-round (* (clamp pct 0.0 1.0) (length xs))))
(split-at (shuffle xs) pos))
Here is an example:
(split 0.25 '(1 2 3 4 5 6 7 8 9))
'(6 2)
'(3 7 1 4 5 8 9)
But, instead of "shuffle" I would like to use this function to achieve the same:
(define (get-randomly-no-pair list)
(list-ref list (random (length list))))
so, get-randomly-no-pair takes one element randomly from the initial list. And all the elements are used to create both lists.
回答1:
(define (shuffle-list lst)
(define indexes (shuffle (range (length lst))))
(lambda ()
(begin0
(list-ref lst (car indexes))
(set! indexes (cdr indexes)))))
(define gen (shuffle-list (list 10 12 14 16 18 20))
(gen) ; ==> 14 (e.g.)
Now I see you assume you need to pass the list then I would rather make a mapper:
(define (shuffle-accessor len)
(define indexes (list->vector (shuffle (range len))))
(lambda (lst index)
(list-ref lst (vector-ref indexes index))))
(define lst3-ref (shuffle-accessor 3))
(lst3-ref '(1 2 3) 0) ; ==> 3 (e.g.)
(lst3-ref '(6 7 8) 0) ; ==> 8
来源:https://stackoverflow.com/questions/43406660/racket-split-a-list-in-two-different-size-lists-and-randomly