<commit_before>;;;; random number generator
(define-library (otus random!)
(export
   ; (rand! n)
   ; generate random number in range [0 .. n) - from 0 to n-1
   rand!

   ; (rand-range! a b)
   ; generate random number in range [a .. b) - from a to b-1
   rand-range!

   ; (shuffle! t)
   ; shuffle a vector, list (destructive)
   shuffle!


)

(import (otus lisp))

(begin

; (rand limit)
;(define rand!
;   (let* ((ss ms (clock))
;          (seed (cons ms ss)))
;      (lambda (limit)
;         (let* ((x (car seed))
;                (a _ (vm:mul x 214013))
;                (b _ (vm:add a 2531011))
;                (c _ (vm:shr b 16))
;                (o p d (vm:div 0 c limit)))
;            (set-car! seed c)
;            d))))

(define rand!
   (let* ((ss ms (clock))
          (seed (band (+ ss ms) #xffffffff))
          (seed (cons (band seed #xffffff) (>> seed 24))))
      (lambda (limit)
         (let*((next (+ (car seed) (<< (cdr seed) 24)))
               (next (+ (* next 1103515245) 12345)))
            (set-car! seed (band     next     #xffffff))
            (set-cdr! seed (band (>> next 24) #xffffff))

            (mod (mod (floor (/ next 65536)) 32768) limit)))))

(define (rand-range! lo hi)
   (if (< lo hi)
      (let* ((o (rand! (- hi lo))))
         (+ o lo))
      (runtime-error "rand-range! bad range: " (list lo hi))))

(define (shuffle! o) ; перемешивалка для vector, list, string
   (cond
      ((vector? o)
         (for-each (lambda (i)
               (let ((a (ref o i))
                     (j (+ 1 (rand! i))))
                  (set-ref! o i (ref o j))
                  (set-ref! o j a)))
            (reverse (iota (size o) 1)))
         o)
      ((list? o)
         (vector->list (shuffle! (make-vector o))))
      ((string? o)
         (runes->string (shuffle! (string->runes o))))))


; based on Marsaglia's letter: http://www.cse.yorku.ca/~oz/marsaglia-rng.html

; The MWC generator concatenates two 16-bit multiply-
;   with-carry generators, x(n)=36969x(n-1) + carry,
;   y(n)=18000y(n-1)+carry mod 2^16, has period about
;   2^60 and seems to pass all tests of randomness. A
;   favorite stand-alone generator.
; #define znew (z=36969*(z&65535)+(z>>16))
; #define wnew (w=18000*(w&65535)+(w>>16))
; #define MWC ((znew<<16)+wnew)

;      (define rand!
;         (let* ((ss ms (clock))
;                (seed (cons ms ss)))
;            (lambda (limit)
;               (let* ((x (car seed))
;                      (a _ (vm:mul x 214013))
;                      (b _ (vm:add a 2531011))
;                      (c _ (vm:shr b 16))
;                      (o p d (vm:div 0 c limit)))
;                  (set-car! seed c)
;                  d))))


))<commit_msg>cleanup<commit_after>;;;; random number generator
(define-library (otus random!)
(export
   ; (rand! n)
   ; generate random number in range [0 .. n) - from 0 to n-1
   rand!
)

(import (otus lisp))

(begin

(define rand!
   (let* ((ss ms (clock))
          (seed (band (+ ss ms) #xffffffff))
          (seed (cons (band seed #xffffff) (>> seed 24))))
      (lambda (limit)
         (let*((next (+ (car seed) (<< (cdr seed) 24)))
               (next (+ (* next 1103515245) 12345)))
            (set-car! seed (band     next     #xffffff))
            (set-cdr! seed (band (>> next 24) #xffffff))

            (mod (mod (floor (/ next 65536)) 32768) limit)))))

))
{'fraction_non_alphanumeric': 0.17758671805514378, 'fraction_numerical': 0.04417432552623777, 'mean_word_length': 1.8163606010016695, 'pattern_counts': {'":': 0, '<': 10, '<?xml version=': 0, '>': 18, 'https://': 0, 'lorem ipsum': 0, 'www.': 1, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 2, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7197793', 'n_tokens_mistral': 1306, 'n_tokens_neox': 1159, 'n_words': 367}