danbaron
22-12-2011, 13:50
On my computer, it takes Racket 604 seconds to calculate 200,000 factorial.
The number has 973,351 digits.
And, it ends in 49,998 zeroes.
Why do big factorials have so many zeroes at the right end?
During the multiplications, if a zero appears at the right end, then, it will stay there, right?
And then, if a zero appears next to it, it will stay there too, right?
And so on.
' code --------------------------------------------------------------------------------------------------------------
#lang racket
(define value 0)
(define (num-digits n)
(add1 (order-of-magnitude n)))
(define (time-function f n)
(let ((t1 (current-milliseconds)))
(set! value (f n))
(let ((t2 (current-milliseconds)))
(let ((tt (/ (- t2 t1) 1000.0)))
tt))))
(define (fact n)
(define prod 1)
(define (loop m)
(cond
((> m n) prod)
(else
(set! prod (* prod m))
(loop (+ m 1)))))
(loop 1))
(define (num-right-end-zeroes n)
(define sum 0)
(define (loop m)
(cond
((= (remainder m 10) 0)
(set! sum (add1 sum))
(loop (/ m 10)))
(else
sum)))
(loop n))
' REPL interactions -------------------------------------------------------------------------------------------------
Welcome to DrRacket, version 5.1 [3m].
Language: racket.
> (time-function fact 200000)
604.141
> (num-digits value)
973351
> (num-right-end-zeroes value)
49998
>
The number has 973,351 digits.
And, it ends in 49,998 zeroes.
Why do big factorials have so many zeroes at the right end?
During the multiplications, if a zero appears at the right end, then, it will stay there, right?
And then, if a zero appears next to it, it will stay there too, right?
And so on.
' code --------------------------------------------------------------------------------------------------------------
#lang racket
(define value 0)
(define (num-digits n)
(add1 (order-of-magnitude n)))
(define (time-function f n)
(let ((t1 (current-milliseconds)))
(set! value (f n))
(let ((t2 (current-milliseconds)))
(let ((tt (/ (- t2 t1) 1000.0)))
tt))))
(define (fact n)
(define prod 1)
(define (loop m)
(cond
((> m n) prod)
(else
(set! prod (* prod m))
(loop (+ m 1)))))
(loop 1))
(define (num-right-end-zeroes n)
(define sum 0)
(define (loop m)
(cond
((= (remainder m 10) 0)
(set! sum (add1 sum))
(loop (/ m 10)))
(else
sum)))
(loop n))
' REPL interactions -------------------------------------------------------------------------------------------------
Welcome to DrRacket, version 5.1 [3m].
Language: racket.
> (time-function fact 200000)
604.141
> (num-digits value)
973351
> (num-right-end-zeroes value)
49998
>