;;; random-project.ss: How often must fractions be reduced? ;;; John David Stone ;;; Department of Mathematics and Computer Science ;;; Grinnell College ;;; stone@math.grin.edu ;;; Original version: February 7 -- 9, 1997 ;; When Chez Scheme constructs an exact rational number, it always reduces ;; the fraction to lowest terms immediately. (For instance, if you type in ;; 100/75, Chez Scheme will immediately reduce the fraction to 4/3 and ;; store the value in that form.) ;; ;; In many cases, of course, the fraction will already be so reduced; if ;; you type in 5/7, the number is stored as 5/7, and that's that. This ;; suggests a question: How often -- in what proportion of the cases -- ;; will a reduction be necessary? To make it a little more exact, we could ;; choose some enormous upper bound (one trillion, for instance) -- (define enormous-upper-bound 1000000000000) ;; -- and consider all of the fractions with numerators and denominators in ;; the range from 0 to this upper bound. (Actually, we shouldn't allow the ;; denominator to be 0, but apart from that we'll allow both the numerator ;; and the denominator to range over this enormous interval.) How many of ;; these fractions can be reduced? ;; ;; It would take too long to type in each of these fractions or even to ;; have Scheme generate them all; there are nearly a septillion of them. ;; But if we're satisfied with an approximate answer we can construct a ;; reliable estimate by taking a moderately large random sample of the ;; fractions and determining how many of the fractions in the sample must ;; be reduced. ;; ;; A random numerator would be any non-negative integer less than the upper ;; bound plus one: (define choose-random-numerator (lambda () (random (+ 1 enormous-upper-bound)))) ;; A random denominator would be any positive integer less than that upper ;; bound plus one. To ensure a positive result, we can use RANDOM to give ;; us a value one unit smaller than the one we want, and then add 1 to it: (define choose-random-denominator (lambda () ; Complete this procedure. )) ;; Notice the difference between these two definitions: ;; CHOOSE-RANDOM-NUMERATOR can return 0, CHOOSE-RANDOM-DENOMINATOR cannot. ;; A fraction can be reduced if, and only if, its numerator and its ;; denominator have a common divisor greater than 1. Scheme's built-in ;; GCD function can therefore be put to good use in this project: (define reducible? (lambda (numer denom) (< 1 (gcd numer denom)))) ;; A call such as (REDUCIBLE? 100 75) yields #T, because the greatest ;; common divisor of 100 and 75 is 25, and 1 is less than 25. On the other ;; hand, (REDUCIBLE? 5 7) is #F, because the greatest common divisor of ;; 5 and 7 is 1, and 1 is not less than itself. ;; We can construct and test a random fraction from among nearly a ;; septillion possibilities by invoking CHOOSE-RANDOM-NUMERATOR and ;; CHOOSE-RANDOM-DENOMINATOR to get the arguments for REDUCIBLE?: (define test-random-fraction (lambda () ; Complete this procedure. )) ;; Given a non-negative integer TEST-COUNT, the MULTIPLE-TEST procedure ;; invokes TEST-RANDOM-FRACTION the specified number of times and reports ;; the number of cases in which the fraction was reducible: (define multiple-test (lambda (test-count) (cond ((zero? test-count) 0) ; Complete this procedure. ))) ;; Given the same non-negative integer TEST-COUNT, the REDUCING-RATE ;; procedure computes the ratio between the number of reducible fractions ;; generated and the total number of test cases. (define reducing-rate (lambda (test-count) (/ (multiple-test test-count) test-count))) ;; Theory says that values returned by this last procedure should be ;; approximately equal to 1 - 6/pi^2, which is about 0.39207. Theory ;; in this case is personified by G. Lejeune Dirichlet, who proved the ;; mathematical version of this result in 1849, in a paper cited by ;; Donald E. Knuth on p. 324 of his _Seminumerical algorithms_ (Reading, ;; Massachusetts: Addison-Wesley Publishing Company, 1981). (define pi 3.14159265358979323846264338327950288419716939937510) ; according to the _CRC standard mathematical tables_ (define expected-value (- 1 (/ 6 pi pi))) ;; Given a non-negative integer TEST-COUNT, the INACCURACY procedure ;; determines the absolute value of the difference between the reduction ;; frequency as determined by REDUCING-RATE and the expected value ;; predicted by Dirichlet. (define inaccuracy (lambda (test-count) ; Complete this procedure. ))