I have to write a function to find if the parenthesises are balanced in a string.
The problem is that in line 1, the if condition is always skipped.
def balance(chars: List[Char]): Boolean = {
def butil(chars: List[Char], l: Int, r: Int): Boolean ={
if (chars.isEmpty) l==r
val c = chars.head
val ret = c match {
case '(' => butil(chars.tail, l+1, r)
case ')' => if(l<=r) false else butil(chars.tail, l, r+1)
case _ => butil(chars.tail, l, r)
}
ret
}
butil(chars, 0, 0)
}
Even the IntelliJ idea shows it in a faded text(meaning that it is never evaluated).
The faded code is evaluated, it is just ignored because the if does nothing with it. You need to move the rest of the code into the else part of the first if and remove the spurious recursive call at the end:
def balance(chars: List[Char]): Boolean = {
def butil(chars: List[Char], l: Int, r: Int): Boolean = {
if (chars.isEmpty) {
l==r
} else {
println(chars.toString())
val c = chars.head
c match {
case '(' => butil(chars.tail, l+1, r)
case ')' => if(l<=r) false else butil(chars.tail, l, r+1)
case _ => butil(chars.tail, l, r)
}
}
}
butil(chars, 0, 0)
}
A cleaner way to do with is to use match to test and extract head/tail at the same time:
def balance(chars: String): Boolean = {
def butil(chars: List[Char], l: Int, r: Int): Boolean =
chars match {
case Nil => l == r
case '(' :: tail => butil(tail, l + 1, r)
case ')' :: tail => if (l <= r) false else butil(tail, l, r + 1)
case _ :: tail => butil(tail, l, r)
}
butil(chars.toList, 0, 0)
}
I've also changed the input type to String as that seems more natural.
Related
I am new to scala and was trying to implement a BST using Pattern Matching Concept in scala.
Edit: I have modified the insert function and now it is behaving in the expected manner, can someone help me to make it tail recursive?
Also, any other code improvements would be appreciated.
trait IntTree {
def contains(v: Int): Boolean
def insert(x: Int): IntTree
}
case object EmptyTree extends IntTree {
override def insert(x: Int): IntTree = Node(x, EmptyTree, EmptyTree)
override def contains(v: Int): Boolean = false
}
case class Node(elem: Int, left: IntTree, right: IntTree) extends IntTree {
override def contains(v: Int): Boolean = {
#scala.annotation.tailrec
def contains(t: IntTree, v: Int): Boolean = t match {
case Node(data, _, _) if (data == v) => true
case Node(data, l, r) => if (data > v) contains(l, v) else contains(r, v)
case _ => false
}
contains(this, v)
}
override def insert(x: Int): IntTree = {
def insert(t: IntTree, x: Int): IntTree = t match {
case Node(data, l, r) if (data > x) => Node(data, insert(l, x), r)
case Node(data, l, r) if (data < x) => Node(data, l, insert(r, x))
case EmptyTree => t insert x
case _ => t
}
insert(this, x)
}
}
It would require a revisit and update of the parent nodes after you go down the leaf:
sealed trait IntTree {
def contains(v: Int): Boolean
def insert(x: Int): Node // better to return Node here
}
def insert(x: Int): Node = {
#annotation.tailrec
def insert(t: IntTree, x: Int, parents: List[Node]): Node = t match {
case EmptyTree =>
parents.foldLeft(t insert x) { case (n, p) =>
if (p.elem >= n.elem) p.copy(left = n)
else p.copy(right = n)
}
case Node(data, l, r) =>
insert(if(data >= x) l else r, x, t :: parents)
}
insert(this, x, List.empty)
}
I have this iterative function which counts the number of Boolean values in a list.
def countBoolIter[A](test: A=>Boolean, a: List[A]) = {
var count = 0
for(elem <- a){
if(test(elem)) count += 1
}
count
}
The first parameter passed in is an isBool function:
def isBool(i: Any) = i match {
case _: Boolean => true
case _ => false
}
Calling the function looks like this:
countBoolIter(isBool, List(1, true, 3, true, false, "hi"))
// Output: 3
Now, I tried converting it into a tail recursive function like this:
def countBoolRec[A](test: A=>Boolean, a: List[A], acc: Int = 0): Int = a match {
case Nil => acc
case h :: t if(test(h)) => countBoolRec(test, a, acc+1)
case h :: t => countBoolRec(test, a, acc)
}
However, I'm getting a runtime error because the function doesn't return anything; no errors are thrown. I presume that it is stuck in an infinite loop that's why nothing is being returned.
Question: How should I fix my attempted recursive implementation?
There is an error in the function countBoolRec:
#tailrec
def countBoolRec[A](test: A=>Boolean, a: List[A], acc: Int = 0): Int = a match {
case Nil => acc
case h :: t if(test(h)) => countBoolRec(test, t, acc+1)
case h :: t => countBoolRec(test, t, acc)
}
In the recursive call, use t as the parameter and no again a. If not, basically, you are in an infinite loop.
Also, better to use the #tailrec annotation to be sure that the implementation is "tail recursive".
You're repeatedly recursing with the same list as input.
Consider the case where a.head passes the test:
countBoolRec(test, a, 0)
countBoolRec(test, a, 1)
countBoolRec(test, a, 2)
... and so on
#scala.annotation.tailrec // Not that your original code wasn't tail-recursive, but it's a generally good practice to mark code that isn't tail recursive with this annotation
def countBoolRec[A](test: A=>Boolean, a: List[A], acc: Int = 0): Int = a match {
case Nil => acc
case h :: t if (test(h)) => countBoolRec(test, t, acc + 1)
case h :: t => countBoolRec(test, t, acc)
}
Though you could also just as well write:
(0 /: a) { (acc, v) => acc + (if (test(v)) 1 else 0) }
This is an exercise in Functional Programming in Scala.
Implement hasSubsequence for
checking whether a List contains another List as a subsequence. For instance,
List(1,2,3,4) would have List(1,2), List(2,3), and List(4) as
subsequences, among others.
My first try is as below:
def go[A](l: List[A], sub:List[A]): Boolean =
(l, sub) match {
case (_,Nil) => true
case (Nil,_) => false
case (a :: as, x :: xs) if a == x => go(as, xs)
case (a :: as, _) => go(as, sub)
} //> go: [A](l: List[A], sub: List[A])Boolean
go(List(1,2,0), List(1,0)) //> res6: Boolean = true
This is wrong as in recursion the initial sub input was not stored (or not recognized) but replaced at each call.
However, if I used the function as a helper function
def hasSubsequence[A](l: List[A], sub: List[A]): Boolean ={
def go[A](l: List[A], a:List[A]): Boolean =
(l, a) match {
case (_,Nil) => true
case (Nil,_) => false
case (a :: as, x :: xs) if a == x => go(as, xs)
case (a :: as, _) => go(as, sub)
}
go(l,sub)
} //> hasSubsequence: [A](l: List[A], sub: List[A])Boolean
hasSubsequence(List(1,2,0), List(1,0)) //> res5: Boolean = false
Then it is stored as a value and works fine. Question is, are there ways of doing this if I don't want any helper functions?
Update: per #jwvh the second one need to be corrected as below.
def hasSubsequence[A](l: List[A], sub: List[A]): Boolean ={
def go[A](l: List[A], a:List[A]): Boolean =
(l, a) match {
case (_,Nil) => true
case (Nil,_) => false
case (a :: as, x :: xs) if a == x => go(as, xs)
case (a :: as, _) if a == sub.head => go(a::as, sub)
case (a :: as, _) => go(as,sub)
}
go(l,sub)
} //> hasSubsequence: [A](l: List[A], sub: List[A])Boolean
hasSubsequence(List(1,2,0), List(1,0)) //> res0: Boolean = false
hasSubsequence(List(1,1,2,0), List(1,2)) //> res1: Boolean = true
Your 2nd solution isn't correct either.
hasSubsequence(List(1,1,2,0), List(1,2)) // res0: Boolean = false
As #Dima has commented, a 3rd parameter would help keep track of whether we have started a match sequence or not. Also, we need to continue the search if the match sequence starts but fails.
def hasSubsequence[A]( l : List[A]
, sub : List[A]
, inMatch: Boolean = false ): Boolean =
(l, sub) match {
case (_,Nil) => true
case (Nil,_) => false
case (a :: as, x :: xs) if a == x =>
hasSubsequence(as, xs, true) || hasSubsequence(as, sub)
case _ =>
!inMatch && hasSubsequence(l.tail, sub)
}
This is not tail recursive but it is recursive without a helper function.
hasSubsequence(List(1,2,0), List(1,0)) // res0: Boolean = false
hasSubsequence(List(1,2,0), List(1,2)) // res1: Boolean = true
hasSubsequence(List(1,2,0), List(2,0)) // res2: Boolean = true
hasSubsequence(List(1,1,2,0), List(2,1)) // res3: Boolean = false
hasSubsequence(List(1,1,2,0), List(1,2)) // res4: Boolean = true
def hasSubsequence[A](sup: List[A], sub: List[A]): Boolean = {
def isPrefix(pref: List[A], xs: List[A]): Boolean = (pref,xs) match {
case (Cons(h1,t1),Cons(h2,t2)) => h1 == h2 && isPrefix(t1,t2)
case (Nil,_) => true
case _ => false
}
sup match {
case Cons(h, t) => isPrefix(sub,sup) || hasSubsequence(t,sub)
case _ => false
}
}
Here's what I've tried so far:
implicit val doubleEq = TolerantNumerics.tolerantDoubleEquality(0.1)
implicit val listEq = new Equivalence[List[Double]] {
override def areEquivalent(a: List[Double], b: List[Double]): Boolean = {
(a, b) match {
case (Nil, Nil) => true
case (x :: xs, y :: ys) => x === y && areEquivalent(xs, ys)
case _ => false
}
}
}
The first assert succeeds but the second one fails:
assert(1.0 === 1.01)
assert(List(1.0) === List(1.01))
Is there a way to have collections use the implicits I've defined for their elements as well?
In my case, I redefined are areEqual method by providing a new Equality[List[Double]] which is a subclass of Equivalence[List[Double]] considering that areEqual takes Any as the second type parameter.
implicit val listEq = new Equality[List[Double]] {
def areEqual(a: List[Double], b: Any): Boolean = {
def areEqualRec(a: List[Double], b: List[Double]): Boolean = {
(a, b) match {
case (Nil, Nil) => true
case (x :: xs, y :: ys) => x === y && areEquivalent(xs, ys)
case _ => false
}
}
b match {
case daList: List[Double] => areEqualRec(a, daList)
case _ => false
}
}
}
Equality classes are only used when importing TypeCheckedTripleEquals:
Provides === and !== operators that return Boolean, delegate the equality determination to an Equality type class, and require the types of the two values compared to be in a subtype/supertype relationship.
Here's the base test class I'm using to solve this:
import org.scalactic.{Equivalence, TolerantNumerics, TypeCheckedTripleEquals}
import org.scalatest.FunSuite
abstract class UnitSpec extends FunSuite with TypeCheckedTripleEquals {
implicit val doubleEq = TolerantNumerics.tolerantDoubleEquality(0.001)
implicit val listEq = new Equivalence[List[Double]] {
override def areEquivalent(a: List[Double], b: List[Double]): Boolean = {
(a, b) match {
case (Nil, Nil) => true
case (x :: xs, y :: ys) => x === y && areEquivalent(xs, ys)
case _ => false
}
}
}
}
I'm trying to port this haskell max function implementation to scala
maximum' :: (Ord a) => [a] -> a
maximum' [] = error "maximum of empty list"
maximum' [x] = x
maximum' (x:xs) = max x (maximum' xs)
This is my first attempt:
def max[T <: Ordered[T]](list: List[T]): T = list match {
case Nil => throw new Error("maximum of empty list")
case head :: Nil => head
case list => {
val maxTail = max(list.tail)
if (list.head > maxTail) list.head else maxTail
}
}
max(List[Int](3,4))
But I get the following error:
inferred type arguments [Int] do not conform to method max's type parameter bounds [T <: Ordered[T]]
I tried with ordering, comprable, etc with similar results...
Any idea about what's missing?
Went through a similar exercise as the OP sans pattern matching and generic types, and came up with the following:
def max(xs: List[Int]): Int = {
if (xs.isEmpty) throw new NoSuchElementException
if (xs.length == 1)
return xs.head
else
return max(xs.head, max(xs.tail))
}
def max(x: Int, y: Int): Int = if (x > y) x else y
Maybe you want the Ordering type class?
def max[T: Ordering](list: List[T]): T = list match {
case Nil => throw new RuntimeException("maximum of empty list")
case head :: Nil => head
case list =>
val maxTail = max(list.tail)
if (implicitly[Ordering[T]].gt(list.head, maxTail)) list.head else maxTail
}
This is, after all, how the built-in max method works:
// From GenTraversableOnce
def max[A1 >: A](implicit ord: Ordering[A1]): A
You can clean things up a lot if you do this:
def max[T](list: List[T])(implicit ord: Ordering[T]): T = list match {
case Nil => throw new RuntimeException("maximum of empty list")
case head :: Nil => head
case head :: tail => ord.max(head, max(tail))
}
Or, you can make it tail-recursive for increased efficiency (because the compiler will optimize it):
def max[T](list: List[T])(implicit ord: Ordering[T]): T = {
if (list.isEmpty)
throw new RuntimeException("maximum of empty list")
#tailrec
def inner(list: List[T], currMax: T): T =
list match {
case Nil => currMax
case head :: tail => inner(tail, ord.max(head, currMax))
}
inner(list.tail, list.head)
}
Also, you should throw RuntimeException or a subclass of it, not Error.
I have just come up with this solution.
def max(xs: List[Int]): Int = {
if (xs.isEmpty) 0
else {
if( xs.head >= max(xs.tail) ) xs.head
else max(xs.tail)
}
}
I came up with quite a simple solution which is easy to understand. It caters for an empty list, a list with only one element, and negative numbers.
def max(xs: List[Int]): Int = {
if (xs.isEmpty) throw new NoSuchElementException
else {
def inner(max: Int, list: List[Int]): Int = {
def compare(x: Int, y: Int): Int =
if (x > y) x
else y
if (list.isEmpty) max
else inner(compare(max, list.head), list.tail)
}
inner(xs.head, xs.tail)
}
}
Oops, shoulda look better before asking
I found the answer in this thread: https://stackoverflow.com/a/691674/47633
It seems like Haskell's type classes are implemented using implicits in scala (like in dhg's example)
so it ends up like this:
def max[T](list: List[T])(implicit f: T => Ordered[T]): T = {
def maxElement(value1: T, value2: T): T = if (value1 > value2) value1 else value2
list match {
case Nil => throw new Error("empty list found")
case head :: Nil => head
case list => maxElement(list.head, max(list.tail))
}
}
or with some syntactic sugar, just
def max[T <% Ordered[T]](list: List[T]): T = list match {
Still, I think the compiler has enough information to do it by himself...
ps: I prettied up a little bit the function...
def genFunc[A](a1: A, a2: A)(f:(A, A) => Boolean):A = if (f(a1, a2)) a1 else a2
def min[A : Ordering] = (a1: A, a2: A) => implicitly[Ordering[A]].lt(a1, a2)
def max[A : Ordering] = (a1: A, a2: A) => implicitly[Ordering[A]].gt(a1, a2)
List(1,2,8,3,4,6,0).reduce(genFunc(_,_)(min))
List(1,2,8,3,4,6,0).reduce(genFunc(_,_)(max))
or if need only function max with tail recursion and the type Option[_] does not break the referential transparency
def max[A: Ordering](list: List[A]): Option[A] = list match {
case Nil => None
case h :: Nil => Some(h)
case h :: t => if(implicitly[Ordering[A]].gt(h, t.head)) max(h :: t.tail) else max(t)
}
max(List(1,2,8,3,4,6,0)).getOrElse("List is empty") // 8: Any
max(List()).getOrElse("List is empty") // List is empty: Any
this is the simplest way I could come up with:
def max(xs: List[Int]): Int = { if (xs.length == 1) xs.head
else if(xs.isEmpty) throw new NoSuchElementException
else if(xs.head > max(xs.tail)) xs.head
else max(xs.tail)} }
this works
def max(xs: List[Int]): Int = xs match{
case Nil => 0
case head :: Nil => head
case head :: tail => max(List(head, max(tail)))
}
My solve:
def max(xs: List[Int]): Int = {
if (xs.isEmpty) 0
else xs.max
}