[racket] a small programming exercise
Mine's basically the same as everyone else's, except I find the first
digit using math instead of string conversion.
#lang racket
;; Compute the base-10 logarithm of a number
(define (log10 x)
(/ (log x) (log 10)))
; Compute the first (base-10) digit of a number
(define (first-digit n)
(inexact->exact (floor (/ n (expt 10 (floor (log10 n)))))))
; Table of occurrences
(define table (make-vector 10 0))
; Update the table of occurrences
(define (update-table n)
(let ([i (first-digit n)])
(vector-set! table i (add1 (vector-ref table i)))))
; Display the table
(define (distribution count)
(map (lambda (n)
(list n (exact->inexact (/ (vector-ref table n) count))))
'(1 2 3 4 5 6 7 8 9)))
; Display the distribution of first digits in a list
(define (benford l)
(begin
(for-each update-table l)
(distribution (length l))))
; Display the distribution of a list of random numbers
(benford (filter positive? (build-list 1000 (lambda (n) (random (add1 n))))))
==>
'((1 0.25075528700906347)
(2 0.1782477341389728)
(3 0.15709969788519637)
(4 0.11379657603222558)
(5 0.08459214501510574)
(6 0.07653575025176233)
(7 0.050352467270896276)
(8 0.044310171198388724)
(9 0.044310171198388724))