RosettaCodeData/Task/File-size-distribution/Racket/file-size-distribution.rkt
2023-07-01 13:44:08 -04:00

28 lines
1 KiB
Racket

#lang racket
(define (file-size-distribution (d (current-directory)) #:size-group-function (sgf values))
(for/fold ((rv (hash)) (Σ 0) (n 0)) ((f (in-directory d)) #:when (file-exists? f))
(define sz (file-size f))
(values (hash-update rv (sgf sz) add1 0) (+ Σ sz) (add1 n))))
(define (log10-or-so x) (if (zero? x) #f (round (/ (log x) (log 10)))))
(define number-maybe-<
(match-lambda** [(#f #f) #f]
[(#f _) #t]
[(_ #f) #f]
[(a b) (< a b)]))
(define ...s? (match-lambda** [(one 1) one] [(one n) (string-append one "s")]))
(define ((report-fsd f) fsd Σ n)
(for/list ((k (in-list (sort (hash-keys fsd) number-maybe-<))))
(printf "~a(size): ~a -> ~a ~a~%"
(object-name f)
k
(hash-ref fsd k) (...s? "file" (hash-ref fsd k))))
(printf "Total: ~a ~a in ~a ~a~%" Σ (...s? "byte" Σ) n (...s? "file" n)))
(module+ test
(call-with-values (λ () (file-size-distribution #:size-group-function log10-or-so))
(report-fsd log10-or-so)))