15-112 Fall 2011 Lab 2
Due Sunday, 11-Sep, at 10pm

Read these instructions first!
  1. Happy Numbers
    Background:  read the first paragraph from the Wikipedia page on happy numbers.  After some thought, we see that no matter what number we start with, when we keep replacing the number by the sum of the squares of its digits, we'll always either arrive at 4 (unhappy) or at 1 (happy).  With that in mind, we want to write the function nthHappyNumber(n).  However, to write that function, we'll first need to write isHappyNumber(n) (right?).  And to right that function, we'll first need to write sumOfSquaresOfDigits(n).  And that's top-down design!  Here we go....
     
    1. sumOfSquaresOfDigits(n)
      Write the function sumOfSquaresOfDigits(n) which takes a non-negative integer and returns the sum of the squares of its digits.  Here are some test assertions for you:
      assert(sumOfSquaresOfDigits(5) == 25)   # 5**2 = 25
      assert(sumOfSquaresOfDigits(12) == 5)   # 1**2 + 2**2 = 1+4 = 5
      assert(sumOfSquaresOfDigits(234) == 29) # 2**2 + 3**2 + 4**2 = 4 + 9 + 16 = 29
      print "Passed all tests!"
    2. isHappyNumber(n)
      Write the function isHappyNumber(n) which takes a possibly-negative integer and returns True if it is happy and False otherwise.  Note that all numbers less than 1 are not happy.  Here are some test assertions for you:
      assert(isHappyNumber(-7) == False)
      assert(isHappyNumber(1) == True)
      assert(isHappyNumber(2) == False)
      assert(isHappyNumber(97) == True)
      assert(isHappyNumber(98) == False)
      assert(isHappyNumber(404) == True)
      assert(isHappyNumber(405) == False)
      print "Passed all tests!"
    3. nthHappyNumber(n)
      Write the function nthHappyNumber(n) which takes a non-negative integer and returns the nth happy number (where the 0th happy number is 1).  Here are some test assertions for you:
      assert(nthHappyNumber(0) == 1)
      assert(nthHappyNumber(1) == 7)
      assert(nthHappyNumber(2) == 10)
      assert(nthHappyNumber(3) == 13)
      assert(nthHappyNumber(4) == 19)
      assert(nthHappyNumber(5) == 23)
      assert(nthHappyNumber(6) == 28)
      assert(nthHappyNumber(7) == 31)
      print "Passed all tests!"
    4. nthHappyPrime(n)
      A happy prime is a number that is both happy and prime.  Write the function nthHappyPrime(n) which takes a non-negative integer and returns the nth happy prime number (where the 0th happy prime number is 7). 

     

  2. Counting Primes
    In this exercise, we will observe an amazing property of the prime numbers!
     
    1. The Prime Counting Function:  pi(n)
      Write the function pi(n) (which has nothing much to do with the value "pi", but coincidentally shares its name) that takes an integer n and returns the number of prime numbers less than or equal to n.  Here are some test assertions for you:
      assert(pi(1) == 0)
      assert(pi(2) == 1)
      assert(pi(3) == 2)
      assert(pi(4) == 2)
      assert(pi(5) == 3)
      assert(pi(100) == 25)  # there are 25 primes in the range [2,100]
      print "Passed all tests!"
       
    2. The Harmonic Number:  h(n)
      Write the function h(n) that takes an int n and, if n is positive, returns the sum of the first n terms in the harmonic series:  1/1 + 1/2 + 1/3 + 1/4 + ...  If n is non-positive, the function returns 0.  Here are some test assertions for you:
      assert(almostEquals(h(0),0.0))
      assert(almostEquals(h(1),1/1.0                ))  # h(1) = 1/1
      assert(almostEquals(h(2),1/1.0 + 1/2.0        ))  # h(2) = 1/1 + 1/2
      assert(almostEquals(h(3),1/1.0 + 1/2.0 + 1/3.0))  # h(3) = 1/1 + 1/2 + 1/3
      print "Passed all tests!"
      Note:  here we use "almostEquals" rather than "==" because this function returns a floating-point number.  You should also write almostEquals.
       
    3. Using the Harmonic Number to estimate the Prime Counting Function (Wow!)
      Write the function estimatedPi(n) that uses the Harmonic Number function to estimate the Prime Counting Function.  Think about it.  One counts the number of primes.  The other adds the reciprocals of the integers.  They seem totally unrelated, but they are in fact very deeply related!  In any case, this function takes an integer n and if it is greater than 2,  returns the value (n / (h(n) - 1.5) ), rounded to the nearest integer (and then cast to an int).  If n is 2 or less, the function returns 0.  Here are some test assertions for you:
      assert(estimatedPi(100) == 27)
      print "Passed all tests!"
       
    4. Empirical check that this really works:  estimatedPiError
      Write the function estimatedPiError that takes an integer n and returns the absolute value of the difference between the value of our estimation computed by estimatedPi(n) and the actual number of primes less than or equal to n as computed by pi(n).  If n is 2 or less, then function returns 0.  Here is the start of a test function:
      assert(estimatedPiError(100) == 2) # pi(100) = 25, estimatedPi(100) = 27
      assert(estimatedPiError(200) == 0) # pi(200) = 46, estimatedPi(200) = 46
      assert(estimatedPiError(300) == 1) # pi(300) = 62, estimatedPi(300) = 63
      assert(estimatedPiError(400) == 1) # pi(400) = 78, estimatedPi(400) = 79
      assert(estimatedPiError(500) == 1) # pi(500) = 95, estimatedPi(500) = 94
      print "Passed all tests!"
      Aside:  as you can see, the estimatedPi function is an amazingly accurate estimation of the pi function.  For example, the estimatedPi function predicts that there should be 94 prime numbers up to 500, and in fact there are 95 prime numbers in that range.  And so we must conclude that there is some kind of very deep relationship between the sum of the reciprocals of the integers (1/1 + 1/2 + ...) and the number of prime numbers.  This relationship has been explored in great detail by many mathematicians over the past few hundred years, with some of the most important results in modern mathematics relating to it.

carpe diem   -   carpe diem   -   carpe diem   -   carpe diem   -   carpe diem   -   carpe diem   -   carpe diem   -   carpe diem   -   carpe diem