# CMU 15-112 Spring 2016 Homework 1 Practice (Due never)

• Do not use strings, loops, lists, or recursion this week.
• Do not hardcode the test cases in your solutions.

1. isLegalTriangle(s1, s2, s3)
Write the function isLegalTriangle(s1, s2, s3) that takes three int or float values representing the lengths of the sides of a triangle, and returns True if such a triangle exists and False otherwise. Note from the triangle inequality that the sum of each two sides must be greater than the third side, and further note that all sides of a legal triangle must be positive.
def isLegalTriangle(s1, s2, s3): return True # replace with your solution def testIsLegalTriangle(): print("Testing isLegalTriangle()...", end="") assert(isLegalTriangle(3, 4, 5)) assert(isLegalTriangle(5, 4, 3)) assert(isLegalTriangle(3, 5, 4)) assert(isLegalTriangle(0.3, 0.4, 0.5)) assert(not isLegalTriangle(3, 4, 7)) assert(not isLegalTriangle(7, 4, 3)) assert(not isLegalTriangle(3, 7, 4)) assert(not isLegalTriangle(5, -3, 1)) assert(not isLegalTriangle(-3, -4, -5)) print("Passed.") print("(Add more tests to be more sure!)") testIsLegalTriangle()

2. nthFibonacci(n)
Background: The Fibonacci numbers are defined by F(n) = F(n-1) + F(n-2). There are different conventions on whether 0 is a Fibonacci number, and whether counting starts at n=0 or at n=1. Here, we will assume that 0 is not a Fibonacci number, and that counting starts at n=0, so F(0)=F(1)=1, and F(2)=2. With this in mind, write the function nthFibonacci(n) that takes a non-negative int n and returns the nth Fibonacci number. Some test cases are provided for you. Hint: you may wish to use Binet's Fibonacci Number Formula (see here), which (amazingly) uses the golden ratio to compute this result, though you may have to make some small change to account for the assumptions noted above.
def nthFibonacci(n): return 42 # replace with your solution def testNthFibonacci(): print("Testing nthFibonacci()...", end="") assert(nthFibonacci(0) == 1) assert(nthFibonacci(1) == 1) assert(nthFibonacci(2) == 2) assert(nthFibonacci(3) == 3) assert(nthFibonacci(4) == 5) assert(nthFibonacci(5) == 8) assert(nthFibonacci(6) == 13) print("Passed.") print("(Add more tests to be more sure!)") testNthFibonacci()

3. circlesIntersect(x1, y1, r1, x2, y2, r2)
Write the function circlesIntersect(x1, y1, r1, x2, y2, r2) that takes 6 numbers (ints or floats) -- x1, y1, r1, x2, y2, r2 -- that describe the circle centered at (x1,y1) with radius r1, and the circle centered at (x2,y2) with radius r2, and returns True if the two circles intersect and False otherwise.
def circlesIntersect(x1, y1, r1, x2, y2, r2): return True # replace with your solution def testCirclesIntersect(): print("Testing circlesIntersect()...", end="") assert(circlesIntersect(0, 0, 2, 3, 0, 2) == True) assert(circlesIntersect(0, 0, 2, 4, 0, 2) == True) assert(circlesIntersect(0, 0, 2, 5, 0, 2) == False) print("Passed.") print("(Add more tests to be more sure!)") testCirclesIntersect()

4. leastPiError(n)
Background: for any positive integer n, we can form integer ratios of the form m/n with the intent of approximating pi. For example, if n=7, we could try 22/7, which is about 3.1429 (not bad). For each integer n, there exists some integer m such that m/n produces the best approximation of pi, with the least error. With this in mind, write the function leastPiError(n) that takes a positive integer n, calculates the optimal m, and then returns the smallest such error. That is, it returns the smallest distance from pi to m/n for any positive integer m. Note that you may wish to use math.pi in your solution.
import math def leastPiError(n): return 42 # replace with your solution def almostEqual(d1, d2): epsilon = 10**-8 return (abs(d1 - d2) < epsilon) def testLeastPiError(): print("Testing leastPiError()...", end="") assert(almostEqual(leastPiError( 7), 0.0012644893)) # at 22/7 assert(almostEqual(leastPiError( 43), 0.0020577699)) # at 135/43 assert(almostEqual(leastPiError(113), 0.0000002668)) # at 355/113 print("Passed.") print("(Add more tests to be more sure!)") testLeastPiError()

5. nearestOdd(n)
Write the function nearestOdd(n) that takes an int or float n, and returns as an int value the nearest odd number to n. In the case of a tie, return the smaller odd value.
def nearestOdd(n): return 42 # replace with your solution def testNearestOdd(): print("Testing nearestOdd()...", end="") assert(nearestOdd(13) == 13) assert(nearestOdd(12.001) == 13) assert(nearestOdd(12) == 11) assert(nearestOdd(11.999) == 11) assert(nearestOdd(-13) == -13) assert(nearestOdd(-12.001) == -13) assert(nearestOdd(-12) == -13) assert(nearestOdd(-11.999) == -11) print("Passed.") print("(Add more tests to be more sure!)") testNearestOdd()

6. eggCartons(eggs)
Write the function eggCartons(eggs) that takes a non-negative integer number of eggs, and returns the smallest integer number of cartons required to hold that many eggs, where a carton may hold up to 12 eggs.
def eggCartons(eggs): return 42 # replace with your solution def testEggCartons(): print("Testing eggCartons()...", end="") assert(eggCartons(0) == 0) assert(eggCartons(1) == 1) assert(eggCartons(12) == 1) assert(eggCartons(13) == 2) assert(eggCartons(24) == 2) assert(eggCartons(25) == 3) print("Passed.") print("(Add more tests to be more sure!)") testEggCartons()

7. pittsburghHour(londonHour)
Write the function pittsburghHour(londonHour) that takes a non-negative integer, the current hour in London, and returns as an integer the current hour in Pittsburgh (which is 5 hours behind London). However, London time is given in 24-hour time (so londonHour is between 0 and 23, inclusive), but Pittsburgh time must be returned in 12-hour time (so the result must be between 1 and 12, inclusive, where "am" and "pm" are ignored). See the test cases in the code below for some examples.
def pittsburghHour(londonHour): return 42 # replace with your solution def testPittsburghHour(): print("Testing pittsburghHour()...", end="") # London Pittsburgh assert(pittsburghHour( 0) == 7) # midnight 7pm assert(pittsburghHour( 5) == 12) # 5am 12am (midnight) assert(pittsburghHour(10) == 5) # 10am 5am assert(pittsburghHour(12) == 7) # noon 7am assert(pittsburghHour(17) == 12) # 5pm 12pm (noon) assert(pittsburghHour(18) == 1) # 6pm 1pm print("Passed.") print("(Add more tests to be more sure!)") testPittsburghHour()

8. areCollinear(x1, y1, x2, y2, x3, y3)
Write the function areCollinear(x1, y1, x2, y2, x3, y3) that takes six integer values representing three points (x1,y1), (x2,y2), and (x3,y3), and returns True if those points all lie on a single line, and False otherwise. Don't crash when checking for a vertical line!
def areCollinear(x1, y1, x2, y2, x3, y3): return False # replace with your solution def testAreCollinear(): print("Testing testAreCollinear()...", end="") assert(areCollinear(0, 0, 1, 1, 2, 2) == True) assert(areCollinear(0, 0, 1, 1, 2, 3) == False) assert(areCollinear(1, 1, 0, 0, 2, 2) == True) assert(areCollinear(1, 1, 0, -1, 2, 2) == False) assert(areCollinear(2, 0, 2, 1, 2, 2) == True) assert(areCollinear(2, 0, 2, 1, 3, 2) == False) assert(areCollinear(3, 0, 2, 1, 3, 2) == False) print("Passed.") print("(Add more tests to be more sure!)") testAreCollinear()

9. numberOfPoolBalls(rows)
Pool balls are arranged in rows where the first row contains 1 pool ball and each row contains 1 more pool ball than the previous row. Thus, for example, 3 rows contain 6 total pool balls (1+2+3). Write the function numberOfPoolBalls(rows) that takes a non-negative int value, the number of rows, and returns another int value, the number of pool balls in that number of full rows. For example, numberOfPoolBalls(3) returns 6.
def numberOfPoolBalls(rows): return 42 # replace with your solution def testNumberOfPoolBalls(): print("Testing numberOfPoolBalls()...", end="") assert(numberOfPoolBalls(0) == 0) assert(numberOfPoolBalls(1) == 1) assert(numberOfPoolBalls(2) == 3) # 1+2 == 3 assert(numberOfPoolBalls(3) == 6) # 1+2+3 == 6 assert(numberOfPoolBalls(10) == 55) # 1+2+...+10 == 55 print("Passed.") print("(Add more tests to be more sure!)") testNumberOfPoolBalls()

10. numberOfPoolBallRows(balls)
This problem is the inverse of the previous problem. Write the function numberOfPoolBallRows(balls) that takes a non-negative int number of pool balls, and returns the smallest int number of rows required for the given number of pool balls. Thus, numberOfPoolBallRows(6) returns 3. Note that if any balls must be in a row, then you count that row, and so numberOfPoolBallRows(7) returns 4 (since the 4th row must have a single ball in it).
def numberOfPoolBallRows(balls): return 42 # replace with your solution def testNumberOfPoolBallRows(): print("Testing numberOfPoolBallRows()...", end="") assert(numberOfPoolBallRows(0) == 0) assert(numberOfPoolBallRows(1) == 1) assert(numberOfPoolBallRows(2) == 2) assert(numberOfPoolBallRows(3) == 2) assert(numberOfPoolBallRows(4) == 3) assert(numberOfPoolBallRows(6) == 3) assert(numberOfPoolBallRows(7) == 4) assert(numberOfPoolBallRows(10) == 4) assert(numberOfPoolBallRows(11) == 5) assert(numberOfPoolBallRows(55) == 10) assert(numberOfPoolBallRows(56) == 11) print("Passed.") print("(Add more tests to be more sure!)") testNumberOfPoolBallRows()

11. dayOfWeek(month, day, year)
Write the function dayOfWeek(month, day, year) that takes a date represented by three integers, the month (1-12), the day (1-31), and the year, and returns an integer representing the day-of-week for that date, where Sunday is 1, Monday is 2, and so on, and Saturday is 7.

While there are several ways to do this, you must use this formula (from mathforum.org):
```      N = d + 2m + [3(m+1)/5] + y + [y/4] - [y/100] + [y/400] + 2
```
Then the remainder when you divide N by 7 is the day-of-week, where Saturday is 0 and Friday is 6. Note that these values for the days are not quite the same as those returned by this method.

Here is mathforum's description of the formula: "d is the number or the day of the month, m is the number of the month, and y is the year. The brackets around the divisions mean to drop the remainder and just use the integer part that you get. Also, a very important rule is the number to use for the months for January and February. The numbers of these months are 13 and 14 of the previous year. This means that to find the day of the week of New Year's Day [of 1998], 1/1/98, you must use the date 13/1/97."

Note: you must make the adjustment to the month and year when appropriate. So, for example, the date of New Year's Day for 1998 would be obtained in the natural way: dayOfWeek(1, 1, 1998). You may ignore the cases where the month, day, or year are out of bounds.
def dayOfWeek(month, day, year): return 42 # replace with your solution def testDayOfWeek(): print("Testing dayOfWeek()...", end="") # On 2/5/2006, the Steelers won Super Bowl XL on a Sunday! assert(dayOfWeek(2, 5, 2006) == 1) # On 6/15/1215, the Magna Carta was signed on a Monday! assert(dayOfWeek(6, 15, 1215) == 2) # On 3/11/1952, the author Douglas Adams was born on a Tuesday! assert(dayOfWeek(3, 11, 1952) == 3) # on 4/12/1961, Yuri Gagarin became the first man in space, on a Wednesday! assert(dayOfWeek(4, 12, 1961) == 4) # On 7/4/1776, the Declaration of Independence was signed on a Thursday! assert(dayOfWeek(7, 4, 1776) == 5) # on 1/2/1920, Isaac Asimov was born on a Friday! assert(dayOfWeek(1, 2, 1920) == 6) # on 10/11/1975, Saturday Night Live debuted on a Saturday (of course)! assert(dayOfWeek(10, 11, 1975) == 7) print("Passed.") print("(Add more tests to be more sure!)") testDayOfWeek()

12. sphereVolumeFromSurfaceArea(surfaceArea)
Write the function sphereVolumeFromSurfaceArea(surfaceArea) that takes a non-negative int or float surfaceAra, and returns as a float the volume of a sphere with the given surface area. You may wish to look up the formulas for the surface area and volume of a sphere.
import math def sphereVolumeFromSurfaceArea(surfaceArea): return 42 # replace with your solution def almostEqual(d1, d2): epsilon = 10**-4 return (abs(d1 - d2) < epsilon) def testSphereVolumeFromSurfaceArea(): print("Testing sphereVolumeFromSurfaceArea()...", end="") # From http://www.aqua-calc.com/calculate/volume-sphere, with r=3, we see: assert(almostEqual(sphereVolumeFromSurfaceArea(452.38934), 904.77868) == True) # r=6 assert(almostEqual(sphereVolumeFromSurfaceArea(113.09734), 113.09734) == True) # r=3 assert(almostEqual(sphereVolumeFromSurfaceArea(452.38934), 904) == False) # r=6 assert(almostEqual(sphereVolumeFromSurfaceArea(452.38934), 905) == False) # r=6 assert(almostEqual(sphereVolumeFromSurfaceArea(113.09734), 113) == False) # r=3 assert(almostEqual(sphereVolumeFromSurfaceArea(113.09734), 113.1) == False) # r=3 print("Passed.") print("(Add more tests to be more sure!)") testSphereVolumeFromSurfaceArea()

13. isRightTriangle(x1, y1, x2, y2, x3, y3)
Write the function isRightTriangle(x1, y1, x2, y2, x3, y3) that takes 6 int or float values that represent the vertices (x1,y1), (x2,y2), and (x3,y3) of a triangle, and returns True if that is a right triangle and False otherwise. You may wish to write a helper function, distance(x1, y1, x2, y2), which you might call several times. Also, remember to use almostEqual (instead of ==) when comparing floats.
import math def almostEqual(d1, d2): epsilon = 10**-8 return (abs(d1 - d2) < epsilon) def isRightTriangle(x1, y1, x2, y2, x3, y3): return 42 # replace with your solution def testIsRightTriangle(): print("Testing isRightTriangle()...", end="") assert(isRightTriangle(0, 0, 0, 3, 4, 0) == True) assert(isRightTriangle(1, 1.3, 1.4, 1, 1, 1) == True) assert(isRightTriangle(9, 9.12, 8.95, 9, 9, 9) == True) assert(isRightTriangle(0, 0, 0, math.pi, math.e, 0) == True) assert(isRightTriangle(0, 0, 1, 1, 2, 0) == True) assert(isRightTriangle(0, 0, 1, 2, 2, 0) == False) assert(isRightTriangle(1, 0, 0, 3, 4, 0) == False) print("Passed.") print("(Add more tests to be more sure!)") testIsRightTriangle()