CISC-280 Program Development Techniques

Homework 2: Linear Recursion, Iteration, and Orders of Growth

Due: Friday, March 5, 2004

Practice with linear recursion and iteration.

Since the only data structure we know now are numbers, we can practice recursion and iteration by operating on the digits that make up numbers. Later in the course, we'll use very similar ideas on a general data structure called a list.

Any positive number n can be written as a sequence of digits dk dk-1 ...d1 d0, where dk is non-zero. Thus the number n is the sum of di times 10 to the i power, for i = 0 to k. For example, if n = 456, then k is 2 and d2 is 4, d1 is 5, and d0is 6. A Scheme program can access the individual digits by using the following basic functions:

(define (units-digit n)
       (remainder n 10))

(define (all-but-units-digit n)
        (quotient n 10))

With those definitions in place, for example,

(unit-digit 456) --> 6
(all-but-units-digit 456) --> 45

By combining these functions, you can access the rightmost (units) digit, the second digit, the third digit, etc. ultimately reaching the most significant (leftmost) digit. If (all-but-the-units-digit n) is zero, you know n is a one-digit number.

Using these access functions, define the following functions:

  1. (decimal-length n) returns k+1, where dkis the leading digit of n. For example,
    (decimal-length 348567) --> 6
  2. (ith-digit n i) returns di of n. For example
    (ith-digit 671835629 3) --> 5
  3. (leading-digit n) returns dk, the most significant digit.
    (leading-digit 534) --> 5
  4. (occurances d n) returns the number of times digit d occurs in n.
    (occurrances 6 5494576548754987587654655478563) --> 4
  5. (digit-sum n) returns the sum of the digits in n.
    (digit-sum 2354) --> 14, (digit-sum 8) --> 8
  6. (digital-root n) returns the result of repeatedly applying digit-sum until the result is a single digit.
    (digital-root 341943) --> 6 (via 3+4+1+9+4+3=24, then 2+4=6)
  7. (backwards n) returns the digits in reverse order. You do not need to handle leading or trailing zeros. For this problem you may use multiplication. For example:
    (backwards 329145) --> 541923

Hand in a printout of your definitions, with each procedure documented briefly, and mention for each one if it implements a linear recursive procedure or an iterative procedure. Also hand in a transcript demonstrating the testing of each procedure. Hint: These should all be fairly short, simple functions. If they get long, re-examine the problem!

8. The Scheme function time allows you to discover the amount of time a procedure takes to execute.
You call it by wrapping it around the call to the procedure that you wish to time, e.g.

(time (fast-expt 2 100))

Use time to compare the running time of the iterative version of expt and fast-expt. You may need to use fairly large numbers to get substantial differences. Show your experimental results in a graph. Do your results bear out the order statistics that we discussed in class for these two algorithms?  Are your results compatible with the notion that programs on your machine run in time proportional to the number of steps required for the computation?
 

9. Write a procedure called nmult-fast-expt that takes one argument, a positive integer, and produces the number of multiplications required to raise something to that power using fast-expt.

As above, hand in a printout of your commented definition and indicate whether it implements a linear recursive procedure or an iterative procedure. Also hand in a transcript demonstrating the testing of nmult-fast-expt  Hint: This function should also be fairly short and simple. If it gets long, re-examine the problem!