Scala Error: identifier expected but '}' found - scala

I'm trying to figure out this compile error:
Error:(51, 4) identifier expected but '}' found.
} else if (n < 0) {
^
For this code:
def nthPowerOfX(n: Int, x:Double) : Double = {
if (n == 0) {
1.0
} else if (n < 0) {
1.0 / nthPowerOfX(n,x)
} else if (n % 2 == 0 && n > 0) {
nthPowerOfX(2, nthPowerOfX(n/2,x))
} else {
x*nthPowerOfX(n-1, x)
}
}
I tried return statements too but that didn't help nor should it matter to my understanding.

Jozef is right! There is no error. Please consider using this:
def nthPowerOfX(n: Int, x:Double) : Double = {
n match{
case 0 => 1.0
case x if x < 0 => 1.0 / nthPowerOfX(n,x)
case x if x % 2 == 0 && x > 0 => nthPowerOfX(2, nthPowerOfX(n/2,x))
case x => x*nthPowerOfX(n-1, x)
}
}
But keep in mind that recursion is dangerous thing, it's better to use tail recursion, if we are talking about Scala.

Related

Facing Issues in Recursion of Perfect Number Problem

I've been working on the scala recursion problem. I used to develop the program using loops and then use the concept of recursion to convert the existing loop problem in a recursive solution.
So I have written the following code to find the perfect number using loops.
def isPerfect(n: Int): Boolean = {
var sum = 1
// Find all divisors and add them
var i = 2
while ( {
i * i <= n
}) {
if (n % i == 0) if (i * i != n) sum = sum + i + n / i
else sum = sum + i
i += 1
}
// If sum of divisors is equal to
// n, then n is a perfect number
if (sum == n && n != 1) return true
false
}
Here is my attempt to convert it into a recursive solution. But I'm getting the incorrect result.
def isPerfect(n: Int): Boolean = {
var sum = 1
// Find all divisors and add them
var i = 2
def loop(i:Int, n:Int): Any ={
if(n%i == 0) if (i * i != n) return sum + i + n / i
else
return loop(i+1, sum+i)
}
val sum_ = loop(2, n)
// If sum of divisors is equal to
// n, then n is a perfect number
if (sum_ == n && n != 1) return true
false
}
Thank you in advance.
Here is a tail-recursive solution
def isPerfectNumber(n: Int): Boolean = {
#tailrec def loop(d: Int, acc: List[Int]): List[Int] = {
if (d == 1) 1 :: acc
else if (n % d == 0) loop(d - 1, d :: acc)
else loop(d - 1, acc)
}
loop(n-1, Nil).sum == n
}
As a side-note, functions that have side-effects such as state mutation scoped locally are still considered pure functions as long as the mutation is not visible externally, hence having while loops in such functions might be acceptable.

fast power function in scala

I tried to write a function for fast power in scala, but I keep getting java.lang.StackOverflowError. I think it has something to do with two slashes that use in the third line when I recursively called this function for n/2.
Can someone explain why is this happening
def fast_power(x:Double, n:Int):Double = {
if(n % 2 == 0 && n > 1)
fast_power(x, n/2) * fast_power(x, n /2)
else if(n % 2 == 1 && n > 1)
x * fast_power(x, n - 1)
else if(n == 0) 1
else 1 / fast_power(x, n)
}
Your code doesn't terminate, because there was no case for n = 1.
Moreover, your fast_power has linear runtime.
If you write it down like this instead:
def fast_power(x:Double, n:Int):Double = {
if(n < 0) {
1 / fast_power(x, -n)
} else if (n == 0) {
1.0
} else if (n == 1) {
x
} else if (n % 2 == 0) {
val s = fast_power(x, n / 2)
s * s
} else {
val s = fast_power(x, n / 2)
x * s * s
}
}
then it is immediately obvious that the runtime is logarithmic, because
n is at least halved in every recursive invocation.
I don't have any strong opinions on if-vs-match, so I just sorted all the cases in ascending order.
Prefer the match construct instead of multiple if/else blocks. This will help you isolate the problem you have (wrong recursive call), and write more understandable recursive functions. Always put the termination conditions first.
def fastPower(x:Double, m:Int):Double = m match {
case 0 => 1
case 1 => x
case n if n%2 == 0 => fastPower(x, n/2) * fastPower(x, n/2)
case n => x * fastPower(x, n - 1)
}

Check if number is prime in O(sqrt(n)) in Scala

When checking if n is a prime number in Scala, the most common solutions is concise one-liner which can be seen in almost all similar questions on SO
def isPrime1(n: Int) = (n > 1) && ((2 until n) forall (n % _ != 0))
Moving on, it's simple to rewrite it to check only odd numbers
def isPrime2(n: Int): Boolean = {
if (n < 2) return false
if (n == 2) return true
if (n % 2 == 0) false
else (3 until n by 2) forall (n % _ != 0)
}
However, to be more efficient I would like to combine checking only odds with counting up to sqrt(n), but without using Math.sqrt. So, as i < sqrt(n) <==> i * i < n, I would write C-like loop:
def isPrime3(n: Int): Boolean = {
if (n < 2) return false
if (n == 2) return true
if (n % 2 == 0) return false
var i = 3
while (i * i <= n) {
if (n % i == 0) return false
i += 2
}
true
}
The questions are:
1) How to achieve the last version in the first version nice Scala functional style?
2) How can I use Scala for to this? I thought of something similar to below, but don't know how.
for {
i <- 3 until n by 2
if i * i <= n
} { ??? }
Here is a method to verify if n is prime until sqrt(n) without using sqrt:
def isPrime3(n: Int): Boolean = {
if (n == 2) {
true
} else if (n < 2 || n % 2 == 0) {
false
} else {
Stream.from(3, 2).takeWhile(i => i * i < n + 1).forall(i => n % i != 0)
}
}
If you want to do it until n/2, which is also a possible optimization (worse than sqrt(n)), you can replace the last line with:
(3 to n/2 + 1 by 2).forall(i => n % i != 0)
If you prefer, you could also make a tail recursive version, something along these lines:
import scala.annotation.tailrec
def isPrime3(n: Int): Boolean = {
if (n == 2 || n == 3) {
true
} else if (n < 2 || n % 2 == 0) {
false
} else {
isPrime3Rec(n, 3)
}
}
#tailrec
def isPrime3Rec(n:Int, i: Int): Boolean = {
(n % i != 0) && ((i * i > n) || isPrime3Rec(n, i + 2))
}

Do if else statements in Scala always require an else?

I have the following function which works fine:
def power(x: Double, n: Int) : Double = {
if (n > 0 && n % 2 == 0) power(x, n/2) * power(x, n/2)
else if (n > 0 && n % 2 == 1) x * power(x, n-1)
else if (n < 0) 1 / power(x, -n)
else 1
}
If I change it to be:
def power(x: Double, n: Int) : Double = {
if (n > 0 && n % 2 == 0) power(x, n/2) * power(x, n/2)
else if (n > 0 && n % 2 == 1) x * power(x, n-1)
else if (n < 0) 1 / power(x, -n)
else if (n==0 ) 1
}
I.e. change the final else statement to be an else if, then I get the following error trying to call the function:
> <console>:8: error: not found: value power
power(2, 1)
^
I'm guessing this is because there is a possible return type of Unit because the value of n could meet none of the conditions?
In Java "if-else" is a statement. In Scala it is an expression (think of Java's ternary ?:), meaning that it always produces some value. As mentioned by som-snytt in comments, in case of a missing else block the compiler supplies else (), which is of type Unit, which obviously conflicts with the expected type Double in your example.
Some valid examples of missing else are provided in Chris's answer.
No - In general, an if expression does not require an else clause.
Examples:
if (true) println("a")
// prints "a"
if (false) println("a") else if (true) println("b")
// prints "b"
As Nikita Volkov's answer says, though, it is necessary if you need the expression to have some type other than Unit.
Your guess is correct. The method must return a Double, yours would return Unit if non of the "if.." cases match. Actually, when you paste the second definition into the repl, you should get
<console>:11: error: type mismatch;
found : Unit
required: Double

How to get unique elements from two lists of strings in scala?

I have two list to compare:
List one:
List("one","two","three","four")
List two:
List("one","two")
how can I get the unique values from these two lists?
If your two lists are r1 and r2, and assuming you want the values in each list that are not present in the other:
r1.filterNot(r2.contains) ::: r2.filterNot(r1.contains)
or
r1.diff(r2) ::: r2.diff(r1)
Turn them into sets, and get the intersection. You may then turn it back to Seq if you want, but first ask yourself if they had to be Seq in first place, instead of Set.
scala> List("one","two","three","four").toSet & List("one","two").toSet
res0: scala.collection.immutable.Set[String] = Set(one, two)
Use The difference operator for Set &~
http://www.scala-lang.org/api/current/scala/collection/immutable/Set.html
I use List(1, 2, 3, 4) ::: List(1, 2, 5) distinct for this issue. It returns List(1, 2, 3, 4, 5).
I would suggest using the following for O(m+n) running time (assumes input arrays are sorted).
def mergeUniqueSortedArrays( A: Array[String], B: Array[String] ): Array[String]= {
val n = A.length
val m = B.length
var C = Array[String]()
var i = 0
var j = 0
while (i < n && j < m) {
if (i == n) {
if ( B(j) != A(i-1) ) {
C :+= B(j)
}
j+=1
}
else if (j == m) {
if ( A(i) != B(j-1) ) {
C :+= A(j)
}
i+=1
}
else {
if ( A(i) < B(j) ) {
if (C.length == 0 || A(i) != C(C.length-1)) {
C :+= A(i)
}
i+=1
}
else if ( B(j) < A(i) ) {
if (C.length == 0 || B(j) != C(C.length-1)) {
C :+= B(j)
}
j+=1
}
else {
if (C.length == 0 || A(i) != C(C.length-1)) {
C :+= A(i)
}
i+=1
j+=1
}
}
}
return C
}
--
NOTE: If the input arrays are not sorted, then you can easily sort the input arrays and it will run in in O( max{(n + m), (n log n)}) time, assuming n>m.
NOTE: O(n + m) time technically assumes that string length is bounded by constant k, but you aren't going to get around that anyway.