; rng147

(define (uniq-c eql? xs)
  (if (null? xs) xs
    (let loop ((xs (cdr xs)) (prev (car xs)) (k 1) (result '()))
      (cond ((null? xs) (reverse (cons (cons prev k) result)))
            ((eql? (car xs) prev) (loop (cdr xs) prev (+ k 1) result))
            (else (loop (cdr xs) (car xs) 1 (cons (cons prev k) result)))))))

(define rand
  (let ((seed 0.3141592654))
    (lambda args
      (set! seed
        (if (pair? args)
            (sin (car args))
            (let ((x (* seed 147.0)))
              (- x (floor x)))))
      seed)))

(define (randlist n . args)
  (when (pair? args) (rand (car args)))
  (do ((n n (- n 1))
       (rs (list) (cons (rand) rs)))
      ((zero? n) rs)))

(define (freq n k)
  (uniq-c =
    (sort
      (map inexact->exact
        (map floor
          (map (lambda (x) (* x (expt 10 k)))
            (randlist n)))) <)))

(define (dir n)
  (let loop ((rs (randlist n)) (up 0) (down 0))
    (cond ((null? (cdr rs))
            (list up (- n up down 1) down))
          ((< (car rs) (cadr rs))
            (loop (cdr rs) (+ up 1) down))
          ((< (cadr rs) (car rs))
            (loop (cdr rs) up (+ down 1)))
          (else (loop (cdr rs) up down)))))

(display (freq 10000 1)) (newline)
(display (freq 100000 2)) (newline)
(display (dir 100000)) (newline)