This assignment asks you to write scala programs. Fill in the programs below. Use the test cases provided to test them. You are also encouraged to write your own test cases.
YOUR NAME HERE
// TEST HELPER
def passed(points: Int) {
require(points >=0)
if (points == 1) print(s"
*** Tests Passed (1 point) ***
")
else print(s"
*** Tests Passed ($points points) ***
")
}
def testWithMessage(cond: Boolean, testID: String) = {
assert(cond, s"Test $testID Failed");
println(s"Test $testID Passed!")
}
cell1.sc:108: procedure syntax is deprecated: instead, add `: Unit =` to explicitly declare `passed`'s return type [quickfixable] def passed(points: Int) { ^
defined [32mfunction[39m [36mpassed[39m defined [32mfunction[39m [36mtestWithMessage[39m
Problem 1 (5 points)
Write a scala function titled isPalindrome (s)
that tests whether a given input string s
is a palindrome.
The following string operations will be helpful.
s.size
gives you the size of the string.s(i)
gives you theith
character fori = 0, ... , s.size-1
- For loops in scala are described here: https://www.tutorialspoint.com/scala/scala_for_loop.htm Pay careful attention between the to and until forms of the for loop.
def isPalindrome(s: String): Boolean = {
??? // YOUR CODE HERE
}
defined [32mfunction[39m [36misPalindrome[39m
//BEGIN TEST
assert(isPalindrome("hellolleh"), "Test 1 Failed")
assert(!isPalindrome("bababablacksheep"), "Test 2 Failed")
assert(isPalindrome(""), "Test 3 Failed")
assert(isPalindrome("a"), "Test 4 Failed")
assert(isPalindrome("xxxxxxxx"), "Test 5 Failed")
assert(isPalindrome("ablewasiereisawelba"), "Test 6 Failed")
passed(5)
//END TEST
Problem 2 (10 points)
Implement a isPalindromeRec
function that checks if a given string is a palindrome, but without using mutable var
or without using for
/while
loops. Your recursive function should use the following high level algorithm:
- Strings of length 0 (empty string) or 1 (single char) are by default palindrones. (This is your base case).
- If the first and last characters of the string are the same, the string if a palindrome if the substring between second and last but one characters is itself a palindrome (use the recursive call to check).
- Or else, the string cannot be a palindrome.
Hint: You should consult Scala documentation on strings to figure out: https://www.tutorialspoint.com/scala/scala_strings.htm
- How do we get first and last characters of a string.
- How do we get substring between first and last character.
- How to find out if a string is empty or a single character.
def isPalindromeRec(s: String): Boolean = {
??? // YOUR CODE HERE
}
//BEGIN TEST
testWithMessage(isPalindromeRec("hellolleh") == true, "1")
testWithMessage(isPalindromeRec("bababablacksheep") == false, "2")
testWithMessage(isPalindromeRec("") == true, "3")
testWithMessage(isPalindromeRec("a") == true, "4")
testWithMessage(isPalindromeRec("xxxxxxxx") == true, "5")
testWithMessage(isPalindromeRec("ablewasiereisawelba") == true, "6")
passed(5)
//END TEST
Problem 3 (20 points)
We would like you to implement the methods in the class Rational that is supposed to represent fractions ndnd, where the numerator and denominator are integers n,dn,d. Note that it is important to ensure that d≠0d≠0.
Implement the missing methods below.
You should read this blog post about how to convert between numeric types.
https://alvinalexander.com/scala/how-to-convert-between-numeric-types-in-scala-int-long-float-double
class Rational(val n: Int, val d: Int) {
// Implement a pretty printer
override def toString(): String = {
s"$n/$d"
}
def isValid(): Boolean = {
// check if this is a valid fraction.
??? // YOUR CODE HERE
}
def toDouble(): Double = {
// Convert n/ d to double
// use toDouble method to convert an integer to double
??? // YOUR CODE HERE
}
def isInteger(): Boolean = {
// Is this fraction an integer.
// A fraction is an integer if n is divisible by d
??? // YOUR CODE HERE
}
def floor(): Double = {
// return the floor of n/d
// math.floor(f) takes the floor of a double precision number in scala
??? // YOUR CODE HERE
}
def rationalEquals(r: Rational): Boolean = {
// Check if this equals r
??? // YOUR CODE HERE
}
def + (r: Rational) : Rational = {
// Add two rationals and return a new Rational
??? // YOUR CODE HERE
}
def - (r: Rational): Rational = {
// compute this - r and return a new Rational
??? // YOUR CODE HERE
}
def * (r: Rational): Rational = {
// multiply two rationals and return a new Rational
??? // YOUR CODE HERE
}
def / (r: Rational): Rational = {
// compute this/r and return a new Rational
??? // YOUR CODE HERE
}
// We can use your rationalEquals method to overide the == operator as follows
// Ignore this method for now -- it will be clearer soon
override def equals(r: Any): Boolean = r match {
case rat: Rational => this.rationalEquals(rat)
case _ => false
}
// END Ignore
}
//BEGIN TEST
testWithMessage(new Rational(10, 0).isValid() == false, "1 - isValid")
testWithMessage(new Rational(10, 1).isValid() == true, "2 - isValid")
passed(2)
//END TEST
//BEGIN TEST
testWithMessage(new Rational(10, 3).toDouble() == 10.0/3.0, "1 - toDouble")
testWithMessage(new Rational(19, 5).toDouble() == 19.0/5.0, "2 - toDouble")
passed(2)
//END TEST
//BEGIN TEST
testWithMessage(new Rational(15, 3).isInteger() == true, "1 - isInteger")
testWithMessage(new Rational(15, 8).isInteger() == false, "2 - isInteger")
testWithMessage(new Rational(225, 15).isInteger() == true, "3 - isInteger")
testWithMessage(new Rational(181, 2).isInteger() == false, "4 - isInteger")
passed(2)
//END TEST
//BEGIN TEST
testWithMessage(new Rational(15, 4).floor() == 3.0, "1 - floor")
testWithMessage(new Rational(100, 45).floor() == 2.0, "2 - floor")
testWithMessage(new Rational(-25, 3).floor() == -9.0, "3 - floor")
testWithMessage(new Rational(-40, 7).floor() == -6.0, "4 - floor")
passed(2)
//END TEST
//BEGIN TEST
testWithMessage((new Rational(20, 5)) == (new Rational(16 , 4)), "1 - rationalEquals")
testWithMessage((new Rational(24, 5)) == (new Rational(120, 25)), "2 - rationalEquals")
testWithMessage((new Rational(19, 5)) != (new Rational(58, 15)), "3 - rationalEquals")
testWithMessage((new Rational(24, 1)) != (new Rational(120, 15)), "4 - rationalEquals")
passed(2)
//END TEST
//BEGIN TEST
val r1 = new Rational(10, 3)
val r2 = new Rational(14, 3)
val r3 = r1 + r2
testWithMessage(r3.n == r3.d * 8, "1 - addition of 10/3 + 14/3 - ")
val r4 = new Rational(9, 2)
val r5 = new Rational(18, 2)
val r6 = r4 + r5
testWithMessage(r6.n * 2 == r6.d * 27, "2 - addition of 9/2 + 18/2 - ")
val r7 = new Rational(15, 7)
val r8 = new Rational(19, 6)
val r9 = r7 + r8
testWithMessage(r9.n * 42 == r9.d * 223, "3 - addition of 15/7 + 19/6 - ")
val r10 = r1 - r2
testWithMessage(r10.n * 3 == r10.d * -4, "1 - subtraction of 10/3 - 14/3 - ")
val r11 = r6 - r7
passed(10)
//END TEST
Problem 4 (20 points)
Newton invented the Newton-Raphson method for solving an equation. We are going to ask you to write some code to solve equations.
To solve an equation of the form
we start from an initial guess at the solution: say x0=4.5x0=4.5 Each time we have the ithith guess xixi, we update it as
For our equation, f(x)=x2−3x+2f(x)=x2−3x+2 and f′(x)=2x−3f′(x)=2x−3. Thus, our update equation is
.
We stop whenever |f(xi)|≤10−8|f(xi)|≤10−8: i.e, we are very close to a root of the function. Gory details are here for the curious ones (curiosity = bad for cats, great for students). http://www.math.ubc.ca/~anstee/math104/newtonmethod.pdf
(A, 5 points) Write a scala function calculateRoot(x0: Double)
that takes in the initial guess x0x0 as input and calculates the root for the polynomial x2−3x+2x2−3x+2. Your code should use a var and While loop.
Caution: To calculate x2x2, you should use math.pow(x,2)
in Scala.
def calculateRoot(x0: Double): Double = {
/* Some helpful functions for f and its derivative */
def f(x: Double) = { math.pow(x,2) - 3 * x + 2.0 }
def df(x: Double) = { 2* x - 3}
// Your code here: use f(x) and df(x) provided already.
??? // YOUR CODE HERE
}
//BEGIN TEST
def isRootCorrect(x: Double): Boolean = {
def f(x: Double) = { math.pow(x,2) - 3 * x + 2.0 }
val y = calculateRoot(x)
math.abs(f(y)) <= 1e-08
}
testWithMessage(isRootCorrect(3.5), "1")
testWithMessage(isRootCorrect(4.6), "2")
testWithMessage(isRootCorrect(-3), "3")
testWithMessage(isRootCorrect(-3.5), "4")
testWithMessage(isRootCorrect(1.3), "5")
passed(5)
//END TEST
(B, 10 points) Implement the function calculateRootRec
that uses a recursion instead of a while loop to compute the root. You should not use a mutable var
in your code and no loops are allowed.
def calculateRootRec(x: Double): Double = {
/* Some helpful functions for f and its derivative */
def f(x: Double) = { math.pow(x,2) - 3 * x + 2.0 }
def df(x: Double) = { 2* x - 3}
??? // YOUR CODE HERE
}
//BEGIN TEST
def isRootCorrectRec(x: Double): Boolean = {
val y = calculateRootRec(x)
(math.abs(y - 2.0) <= 1e-06) || (math.abs(y - 1.0) <= 1e-06)
}
testWithMessage(isRootCorrectRec(3.5), "1")
testWithMessage(isRootCorrectRec(4.6), "2")
testWithMessage(isRootCorrectRec(-3), "3")
testWithMessage(isRootCorrectRec(-3.5), "4")
testWithMessage(isRootCorrectRec(1.3), "5")
passed(5)
//END TEST
(C, 10 points) Write a generalized Newton-Raphson function solveEquationNewtonRaphson
to solve any equation f(x)=0f(x)=0 wherein the functions ff and f′(x)f′(x) are given as inputs. Do not use while loops or mutable var
in your code.
def solveEquationNewtonRaphson(x: Double, f: Double => Double, df: Double => Double): Double = {
??? // YOUR CODE HERE
}
//BEGIN TEST
def f1(x: Double) = 2.0 * math.pow(x,3) - math.pow(x, 2) - 1.0
def df1(x: Double) = 6.0 * math.pow(x, 2) - 2 * x
val x1 = solveEquationNewtonRaphson(3.0, f1, df1)
testWithMessage(math.abs(f1(x1)) <= 1e-06, "1")
passed(2)
//END TEST
//BEGIN TEST
def f2(x: Double) = math.sin(x) - 0.5 * x
def df2(x: Double) = math.cos(x) - 0.5
val x2 = solveEquationNewtonRaphson(0.7, f2, df2)
testWithMessage(math.abs(f2(x2)) <= 1e-06, "2")
passed(2)
//END TEST
//BEGIN TEST
def f3(x: Double) = math.log(x) - 2
def df3(x: Double) = 1/x
val x3 = solveEquationNewtonRaphson(2.0, f3, df3)
testWithMessage(math.abs(f3(x3)) <= 1e-06, "3")
passed(2)
//END TEST
//BEGIN TEST
def f4(x: Double) = math.atan(x) - 1
def df4(x: Double) = 1.0/(1.0 + x*x)
val x4 = solveEquationNewtonRaphson(3.0, f4, df4)
testWithMessage(math.abs(f4(x4)) <= 1e-06, "4")
passed(2)
//END TEST
//BEGIN TEST
def f5(x: Double) = math.cos(x)* math.cos(x) - 1
def df5(x: Double) = -2.0 * math.sin(x) * math.cos(x)
val x5 = solveEquationNewtonRaphson(3.5, f5, df5)
testWithMessage(math.abs(f5(x5)) <= 1e-06, "5")
passed(2)
//END TEST
— That is all for now, folks! —
Reviews
There are no reviews yet.