Last active
May 11, 2019 16:26
-
-
Save JohnReedLOL/8efaed267bfcc1706c2d2ea51cf7d765 to your computer and use it in GitHub Desktop.
Johns Wedding Problem Solution in Scala
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| // For problem, see: https://imgur.com/gallery/ahW6XFq | |
| // For video, see: https://youtu.be/x2kcgWwv8Mo | |
| def calculateSlope(first: (Int, Float), second: (Int, Float)): Double = { | |
| val x1 = first._1.toDouble | |
| val y1 = first._2.toDouble | |
| val x2 = second._1.toDouble | |
| val y2 = second._2.toDouble | |
| val slope = (y2 - y1) / (x2 - x1) | |
| slope | |
| } | |
| def calculateYintercept(first: (Int, Float), slope: Double): Double = { | |
| val x1 = first._1.toDouble | |
| val y1 = first._2.toDouble | |
| val yIntercept = y1 - (slope * x1) | |
| yIntercept | |
| } | |
| def calculatePrice(quantity: Double, slope: Double, yIntercept: Double): Double = { | |
| // price = slope * quantity + yIntercept | |
| val price = slope * quantity + yIntercept | |
| price | |
| } | |
| // Complete the interpolate function below. | |
| def interpolate(n: Int, quantity: Array[Int], price: Array[Float]): Float = { | |
| // Wait a second. What if two different wedding favors exist in the same quantity and have the same price? | |
| // Are they the same wedding favor? In real life they won't be, but this is a contrived example. | |
| // Let's assume that if the quantity is the same, then they are the same wedding favor and the price is the same. | |
| // Based on this assumption, let's construct a sorted collection. | |
| val quantityToPrice: Array[(Int, Float)] = quantity.zip(price).sortBy(_._1) // Sort by quantity (1) | |
| val smallest: (Int, Float) = quantityToPrice.head // Smallest quantity first. | |
| val biggest: (Int, Float) = quantityToPrice.last // Biggest quantity last. | |
| // This map lets us look up price based on quantity. | |
| val quantityToPriceMap = quantityToPrice.toMap | |
| // In Scala, if/else is an expression that returns a value. | |
| val toReturn: Float = if(quantityToPriceMap.contains(n)) { | |
| // if n already exists in quantityPriceMap, just return n. | |
| quantityToPriceMap(n) | |
| } else { | |
| assert(!quantityToPriceMap.contains(n), "At this point, the value of n is not in our quantityToPriceMap.") | |
| val smallestQuantity: Int = smallest._1 | |
| val biggestQuantity: Int = biggest._1 | |
| if(n < smallestQuantity) { | |
| // If n is smaller than smallest, we extrapolate down. | |
| val secondSmallest: (Int, Float) = quantityToPrice(1) // Smallest is at index 0, second smallest at index 1. | |
| // Now we must calculate a slope and y-intercept with smallest and secondSmallest. | |
| val slope = calculateSlope(smallest, secondSmallest) | |
| val yIntercept = calculateYintercept(smallest, slope) | |
| calculatePrice(n, slope, yIntercept).toFloat | |
| } else if(n > biggestQuantity) { | |
| // If n is bigger than biggest, we extrapolate up. | |
| assert(biggest == quantityToPrice(quantityToPrice.length - 1)) // If an Array goes from 0 to length - 1, then the last element is at length - 1. | |
| val secondBiggest: (Int, Float) = quantityToPrice(quantityToPrice.length - 2) | |
| // Now we must calculate a slope and y-intercept with biggest and secondBiggest. | |
| val slope = calculateSlope(biggest, secondBiggest) | |
| val yIntercept = calculateYintercept(biggest, slope) | |
| calculatePrice(n, slope, yIntercept).toFloat | |
| } else { | |
| // If n is in between smallest and biggest, then we interpolate by making a line in between the nearest quantities. | |
| // Find the quantity that is below n | |
| val partitions: (Array[(Int, Float)], Array[(Int, Float)]) = quantityToPrice.partition((element: Tuple2[Int, Float]) => element._1 < n ) | |
| val quantityPriceLessThanN: Array[(Int, Float)] = partitions._1 | |
| val quantityPriceGreaterThanN: Array[(Int, Float)] = partitions._2 | |
| assert(quantityPriceLessThanN.length + quantityPriceGreaterThanN.length == quantityToPrice.length, "The size of the two partitions must add up.") | |
| // Now let's get the value that is just below n and the value that is just above n so that we can interpolate. | |
| val belowN: (Int, Float) = quantityPriceLessThanN.last | |
| val aboveN: (Int, Float) = quantityPriceGreaterThanN.head | |
| // Now we must calculate a slope and y-intercept with belowN and aboveN. | |
| val slope = calculateSlope(belowN, aboveN) | |
| val yIntercept = calculateYintercept(belowN, slope) | |
| calculatePrice(n, slope, yIntercept).toFloat | |
| } | |
| } | |
| toReturn | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment