Creative Exercises
2.1.25 Birthday problem. Develop a class with appropriate static methods for studying the birthday problem (see EXERCISE 1.4.38).
2.1.26 Euler’s totient function. Euler’s totient function is an important function in number theory: φ(n) is defined as the number of positive integers less than or equal to n that are relatively prime with n (no factors in common with n other than 1). Write a class with a static method that takes an integer argument n and returns φ(n), and a main() that takes an integer command-line argument, calls the method with that argument, and prints the resulting value.
2.1.27 Harmonic numbers. Write a program Harmonic that contains three static methods harmoinc(), harmoincSmall(), and harmonicLarge() for computing the harmonic numbers. The harmonicSmall() method should just compute the sum (as in PROGRAM 1.3.5), the harmonicLarge() method should use the approximation Hn = loge(n) + γ + 1/(2n) – 1/(12n2) + 1/(120n4) (the number γ = 0.577215664901532... is known as Euler’s constant), and the harmonic() method should call harmonicSmall() for n < 100 and harmonicLarge() otherwise.
2.1.28 Black–Scholes option valuation. The Black–Scholes formula supplies the theoretical value of a European call option on a stock that pays no dividends, given the current stock price s, the exercise price x, the continuously compounded risk-free interest rate r, the volatility σ, and the time (in years) to maturity t. The Black–Scholes value is given by the formula s Φ(a) – x e–r t Φ(b), where Φ(z) is the Gaussian cumulative distribution function, , and . Write a program that takes s, r, σ, and t from the command line and prints the Black–Scholes value.
2.1.29 Fourier spikes. Write a program that takes a command-line argument n and plots the function
(cos(t) + cos(2 t) + cos(3 t) + ... + cos(n t)) / n
for 500 equally spaced samples of t from –10 to 10 (in radians). Run your program for n = 5 and n = 500. Note: You will observe that the sum converges to a spike (0 everywhere except a single value). This property is the basis for a proof that any smooth function can be expressed as a sum of sinusoids.
2.1.30 Calendar. Write a program Calendar that takes two integer command-line arguments m and y and prints the monthly calendar for month m of year y, as in this example:
% java Calendar 2 2009
February 2009
S M Tu W Th F S
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28Hint: See LeapYear (PROGRAM 1.2.4) and EXERCISE 1.2.29.
2.1.31 Horner’s method. Write a class Horner with a method evaluate() that takes a floating-point number x and array p[] as arguments and returns the result of evaluating the polynomial whose coefficients are the elements in p[] at x:
p(x) = p0 + p1x1 + p2 x2 + ... + pn–2 xn–2 + pn–1 xn–1
Use Horner’s method, an efficient way to perform the computations that is suggested by the following parenthesization:
p(x) = p0+ x (p1 + x (p2 + ... + x (pn–2 +x pn–1)) . . .)
Write a test client with a static method exp() that uses evaluate() to compute an approximation to ex, using the first n terms of the Taylor series expansion ex = 1 + x + x2/2! + x3/3! + .... Your client should take a command-line argument x and compare your result against that computed by Math.exp(x).
2.1.32 Chords. Develop a version of PlayThatTune that can handle songs with chords (including harmonics). Develop an input format that allows you to specify different durations for each chord and different amplitude weights for each note within a chord. Create test files that exercise your program with various chords and harmonics, and create a version of Für Elise that uses them.
2.1.33 Benford’s law. The American astronomer Simon Newcomb observed a quirk in a book that compiled logarithm tables: the beginning pages were much grubbier than the ending pages. He suspected that scientists performed more computations with numbers starting with 1 than with 8 or 9, and postulated that, under general circumstances, the leading digit is much more likely to be 1 (roughly 30%) than the digit 9 (less than 4%). This phenomenon is known as Benford’s law and is now often used as a statistical test. For example, IRS forensic accountants rely on it to discover tax fraud. Write a program that reads in a sequence of integers from standard input and tabulates the number of times each of the digits 1–9 is the leading digit, breaking the computation into a set of appropriate static methods. Use your program to test the law on some tables of information from your computer or from the web. Then, write a program to foil the IRS by generating random amounts from $1.00 to $1,000.00 with the same distribution that you observed.
2.1.34 Binomial distribution. Write a function
public static double binomial(int n, int k, double p)
to compute the probability of obtaining exactly k heads in n biased coin flips (heads with probability p) using the formula
f (n, k, p) = pk(1–p)n–k n! / (k!(n–k)!)
Hint: To stave off overflow, compute x = ln f (n, k, p) and then return ex. In main(), take n and p from the command line and check that the sum over all values of k between 0 and n is (approximately) 1. Also, compare every value computed with the normal approximation
f (n, k, p) ≈ ϕ(np, np(1–p))
(see EXERCISE 2.2.1).
2.1.35 Coupon collecting from a binomial distribution. Develop a version of getCoupon() that uses binomial() from the previous exercise to return coupon values according to the binomial distribution with p = 1/2. Hint: Generate a uniformly random number x between 0 and 1, then return the smallest value of k for which the sum of f (n, j, p) for all j < k exceeds x. Extra credit: Develop a hypothesis for describing the behavior of the coupon collector function under this assumption.
2.1.36 Postal bar codes. The barcode used by the U.S. Postal System to route mail is defined as follows: Each decimal digit in the ZIP code is encoded using a sequence of three half-height and two full-height bars. The barcode starts and ends with a full-height bar (the guard rail) and includes a checksum digit (after the five-digit ZIP code or ZIP+4), computed by summing up the original digits modulo 10. Implement the following functions
Draw a half-height or full-height bar on StdDraw.
Given a digit, draw its sequence of bars.
Compute the checksum digit.
Also implement a test client that reads in a five- (or nine-) digit ZIP code as the command-line argument and draws the corresponding postal bar code.