Introduction
to the Design and Analysis of Algorithms
Textbook
 CS 3343/3341
 Analysis of Algorithms
 Fall 2012

 Recitation 2
 Recursion, Etc.

    Partial Answers  


  1. The first problem will be made accessible during the Recitation hour: Rec 2, In-Class Problem 1 (password protected, use "CS3343" without quotes for "User Name" and password from class just before the recitation).

    [See Cascade of Recursive Calls. Denote by An the total number of function calls needed to calculate Fn. (These are called "Leonardo numbers".) It is easy to count initial values for An:

    n01234 5678910...
    An11359 15254167109177...

    After staring at the binary trees of function calls one might guess that the numbers An can be defined by the recurrence:

    A0 = 1
    A1 = 1
    An = An-1 + An-2 + 1

    It is not hard to see that this recurrence is correct. Picture the tree of recursive calls for Fn. The two children from the root are Fn-1 and Fn-2, and these each have An-1 and An-2 calls. Then add one more call for the root.

    It might be hard to solve the recurrence, but if one guesses that

    An = 2 * Fn+1 -1, for all n >= 0

    then the formula can be proved by induction:


  1. Look at the page Recursive Calculation of Fibonacci Numbers. Consider the excessive execution time taken in calculating Fibonacci numbers using recursion, and in the second program, the extremely short times for the same calculation using iteration.

    From the above page, you can see that it took about 70000 sec. to calculate F[60] using recursion. Suppose you have a machine 100 times as fast as the one used for the above calculation. Looking at the data, give a very rough estimate of the biggest Fibonacci number you could calculate in the same time on this faster machine, using the same recursive algorithm. Suppose instead your machine was a million times as fast. Again very roughly give the biggest Fibonacci number you could then calculate. [From the data you can see that increasing n by 5 takes roughly 10 times as long (a little more than that). So a machine 100 times as fast would be able to calculate F(70) in about the same time as this machine calculated F(60). Similarly, a machine a million times as fast would be able to calculate F(90) in about the same time as this machine calculated F(60).]


  1. The program on the xor page shows how to use three assignments involving exclusive-or to interchange the contents of two variables without using a third temporary location. Fill in the remaining values for the truth table below. Then explain how this truth table is proving that the program correctly interchanges 32-bit integer values.

    +---+---+------------+-------------+--------------+
    | 1 | 2 |  column 3  |   column 4  |    column 5  |
    +---+---+------------+-------------+--------------+
    | a | b | a1=a xor b | b1=a1 xor b | a2=a1 xor b1 |
    +---+---+------------+-------------+--------------+
    | 0 | 0 |     0      |      0      |      0       |
    | 0 | 1 |     1      |      0      |      1       |
    | 1 | 0 |     1      |      1      |      0       |
    | 1 | 1 |     0      |      1      |      1       |
    +---+---+------------+-------------+--------------+
    

    [Notice that b1 is the final value that b will have after executing the 3 statements, and a1 is the similar final value of a. For each of the four possible cases for values of a and b, we see that the a and b values have been interchanged after executing the 3 statements. This applies to single bits, but also bit-by-bit to 32-bit integers.]


  1. Look at Weird Topic 1: WOM Storage.
    1. Suppose you have the following information as bits: 01 11 10 11 00 10. Show the result of burning this to storage in the manner of the topic. Then burn the following information as a second generation and show the result: 10 01 00 11 10 10.

      [In each case below the red bits are burned. In rows 4 and 6 the 2nd generation information was the same as the 1st, so the 1st gen bits are left the same.]

      1st Info1st Burn 2nd Info2nd Burn
      0100110101
      1110001110
      1001000111
      1110011100
      0000010101
      1001010010

      [In each case below the red bits are burned. In rows 4 and 6 the 2nd generation information was the same as the 1st, so the 1st gen bits are left the same.]

    2. Show that the formula involving xor lets you recover the original first two information bits correctly, both first and second generations (01 and 10). (See the xor page.) [For burned bits < a , b , c >, we can use the formula:
      a ⊕ b , a ⊕ c >,  where is exclusive-or to recover the original information. In the case of burned bits <0,0,1> above, the formula gives <0⊕0, 0⊕1> = <0,1> for the info bits. In the case of <1,0,1> above, the formula gives <1⊕0, 1⊕1> = <1,0>.]


  1. Study the page Number Base Conversion carefully.

    1. The "difficulty" in the original program was that the numbers came out in the opposite order from what we wanted. The page shows two ways around this: pushing the numbers on a stack and then popping the stack, or using recursion (with an implicit stack in the background). In either Java or C describe briefly (without a full program) at least one other simple way around this problem. [It's easy to concatenate in the opposite direction or to stash digits in an array.]

    2. Adapt one of the programs given so that you can convert the base 10 integer "123456789" to base 8. Change it again slightly so that you can convert this integer to base 16 (hexadecimal). You don't need to write a general program, but you will have to produce the hex digits somehow. [To get the hex digits, you can use a string alf="0123456789abcdef"; Then in C, if you want to print digit i (an int variable), instead print alf[i]. In Java print alf.charAt(i).]


  1. In each case below, solve for x: [You must show your work. Beware of extraneous solutions. Formulas (1) and (2) on the logs page should come in handy.]

    1. log3(x) = 6. [The equation mean the same as 36 = x, or x = 729.]

    2. 2*log9(√x) - log9(6x-1) = 0. [Rewritten:
      log9( (√x)2/(6x - 1) ) = 0 , or x/(6x-1) = 1, or x = 1/5.
      (The base 9 had no effect on the solution.)

      Each expression above is equal to log9(0.2) = loge(0.2)/loge(9) = -0.73248676.]

    3. log x + log(x - 1) = log(3x + 12). [Simplying, we get the quadratic equation x2 - 4x -12 = 0, with roots x = 6, and x = -2. The second root is extraneous, since we can't take the log of a negative number.]

    4. ln(10) - ln(7-x) = ln(x). [Simplying, we get the quadratic equation x2 - 7x +10 = 0, with roots x = 5, and x = 2. Each root is a solution.]


  2. Calculate log3/2(10). [You must show your work. Logs base 3/2 occur on page 91 of your text.] [log3/2(10) = log10(10)/log10(1.5) = 1/log10(1.5) = 1/0.17609126 = 5.6788736.]


  3. Prove that the equation log2(x + y) = log2(x) + log2(y) is not a correct identity. Can you find positive values of x and y for which the equation is true? [The "identity" fails for almost all pairs of numbers. but x = 2, y = 2 works.]


  4. How many bits are needed to represent a number that is 100 decimal digits long? [Ans: 333.] How many decimal digits are needed to represent a number that is 1000 bits long? [Ans: 302.] You must show where these answers come from. [log2(x) is the number of bits needed to represent x. If x has 100 digits, then x = (very roughly) 10100, so log2(10100) = 100 * log2(10) = 100 * 3.321928 = 332.2 bits (or 333 to get the final 0.2 bit).

    If x has 1000 bits, then it is (very roughly) equal to 21000. The number of digits required to represent x is roughly log10(x) = log10(21000) = 1000 * log10(2) = 1000 * 0.30103 = 301.03 (or 302 to get the final 0.03 bit).

    One of my favorite numbers is log10(2) = 0.3010299956639812 (because of the three 9's).]


Revision date: 2012-09-15. (Please use ISO 8601, the International Standard.)