; the 37% rule
(define (take n xs)
(let loop ((n n) (xs xs) (ys '()))
(if (or (zero? n) (null? xs))
(reverse ys)
(loop (- n 1) (cdr xs)
(cons (car xs) ys)))))
(define (drop n xs)
(let loop ((n n) (xs xs))
(if (or (zero? n) (null? xs)) xs
(loop (- n 1) (cdr xs)))))
(define (range . args)
(case (length args)
((1) (range 0 (car args) (if (negative? (car args)) -1 1)))
((2) (range (car args) (cadr args) (if (< (car args) (cadr args)) 1 -1)))
((3) (let ((le? (if (negative? (caddr args)) >= <=)))
(let loop ((x(car args)) (xs '()))
(if (le? (cadr args) x)
(reverse xs)
(loop (+ x (caddr args)) (cons x xs))))))
(else (error 'range "unrecognized arguments"))))
(define random
(let ((a 16807) (m 2147483647) (seed 20180921))
(lambda args (if (pair? args) (set! seed (modulo (car args) m)))
(set! seed (modulo (* a seed) m)) (/ seed m))))
(define (randint n)
(round (* (random) n)))
(define (shuffle x)
(do ((v (list->vector x)) (n (length x) (- n 1)))
((zero? n) (vector->list v))
(let* ((r (randint n)) (t (vector-ref v r)))
(vector-set! v r (vector-ref v (- n 1)))
(vector-set! v (- n 1) t))))
(define (37percent n)
(let* ((candidates (shuffle (range n)))
(size (round (* 37/100 n)))
(cutoff (apply max (take size candidates))))
(display candidates) (display " ")
(let loop ((cs (drop size candidates)) (prev #f))
(cond ((null? cs) prev)
((< cutoff (car cs)) (car cs))
(else (loop (cdr cs) (car cs)))))))
(display (37percent 20)) (newline)