CMU 15-112 Fall 2017: Fundamentals of Programming and Computer Science
Homework 1 (Due Saturday 2-Sep, at 8pm)

  1. hotdogPurchase(numHotdogs) [20 pts]
    Hot dogs are an American tradition. Each year, Americans eat up to 20 Billion hot dogs. A classic hot dog is made up of two components: A frank (the meat) and a bun. Yet, for reasons that mystify mankind, the franks are typically sold in packs of ten and the buns in packs of eight. And, of course, you must buy full packages. Write the function hotdogPurchase(numHotdogs) that takes the total number of hot dogs you want to make, and returns the number of packages of franks and the number of packages of buns you need to purchase. You may assume that the argument, numHotdogs, is a non-negative int and the function returns as ints the smallest number of packages of franks and buns that must be purchased.

    For example:
      hotdogPurchase(50) returns 5, 7. (Meaning 5 packs of franks and 7 packs of buns.)

  2. hotdogExcess(numHotdogs) [25 pts]
    Write the function hotdogExcess(numHotdogs) that takes the total number of hot dogs you want to make (as a non-negative integer) and returns the number of excess franks and buns you will need to purchase. Hint: you may want to use hotDogPurchase, which you just wrote!

    For example:
      hotdogPurchase(50) returns 0, 6.

  3. isRightTriangle(x1, y1, x2, y2, x3, y3) [25 pts]
    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.

  4. threeLinesArea(m1, b1, m2, b2, m3, b3) [30 pts]
    Write the function threeLinesArea(m1, b1, m2, b2, m3, b3) that takes six int or float values representing the 3 lines:
       y = m1*x + b1
       y = m2*x + b2
       y = m3*x + b3
    First find where each pair of lines intersects, then return the area of the triangle formed by connecting these three points of intersection. If no such triangle exists (if any two of the lines are parallel), return 0.

    To do this, you must write three helper functions: one to find where two lines intersect (which you will call three times), a second to find the distance between two points (perhaps already covered in the notes or in class), and a third to find the area of a triangle given its side lengths (which you will call once). You may write other helper functions if you think they would be useful, but you must at least write these three exactly as described below, and then you must use them appropriately in your solution.

    The first required helper function is:
       lineIntersection(m1, b1, m2, b2)
    This function takes four int or float values representing two lines and returns the x value of the point of intersection of the two lines. If the lines are parallel, or identical, the function should return None.

    The second required helper function is:
       distance(x1, y1, x2, y2)
    This function takes four int or float values representing two points and returns the distance between those points.

    The third required helper function is:
       triangleArea(s1, s2, s3)
    This function takes three int or float values representing side lengths of a triangle, and returns the area of that triangle. To do this, you may wish to to use Heron's Formula.

    Once you have written and tested your helper functions, then move on to writing your threeLinesArea function, which of course should use your helper functions. That's the whole point of helper functions. They help! They help in several ways. First, they are logically simpler -- they break down your logic into smaller chunks that are easier to reason over. Second, they are independently testable, so you can more easily isolate and fix bugs. And third, they are reusable, so you can use them as helper functions for other functions in the future. All good things!

  5. Bonus/optional: bonusFindIntRootsOfCubic(a,b,c,d) [3 pts]
    Write the function bonusFindIntRootsOfCubic(a,b,c,d) that takes the int or float coefficients a, b, c, d of a cubic equation of this form:
         y = ax3 + bx2 + cx + d
    You are guaranteed the function has 3 real roots, and in fact that the roots are all integers.  Your function should return these 3 roots in increasing order.  How does a function return multiple values?  Like so:
        return root1, root2, root3
    To get started, you'll want to read about Cardano's cubic formula here (great stuff!).  Then, from that page, use this formula:
    x   =   {q + [q2 + (r-p2)3]1/2}1/3   +   {q - [q2 + (r-p2)3]1/2}1/3   +   p


    p = -b/(3a),   q = p3 + (bc-3ad)/(6a2),   r = c/(3a)

    This isn't quite as simple as it seems, because your solution for x will not only be approximate (and not exactly an int, so you'll have to do something about that), but it may not even be real!  Though the solution is real, the intermediate steps may include some complex values, and in these cases the solution will include a (possibly-negligibly-small) imaginary value.  So you'll have to convert from complex to real (try c.real if c is complex), and then convert from real to int.

    Great, now you have one root.  What about the others?  Well, we can divide the one root out and that will leave us with a quadratic equation, which of course is easily solved.  A brief, clear explanation of this step is provided here.  Don't forget to convert these to int values, too!

    So now you have all three int roots.  Great job!  All that's left is to sort them.  Now, if this were later in the course, you could put them in a list and call a built-in function that will sort for you.  But it's not, so you can't.  Instead, figure out how to sort these values using the limited built-in functions and arithmetic available this week.  Then just return these 3 values and you're done.