Scala Recursively Count Elements Given Predicate - scala

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) }

Related

Scala Tail Recursion From a Flatmap

I have a recursive call as defined below:
def getElems[A](a: A)(f: A => List[A]): List[A] = {
f(a)
}
def parse[A](depth: Int, elems: List[A], f: A => List[A]): List[A] = {
elems.flatMap(elem => {
if (depth > 0) {
parse(depth - 1, getElems(elem)(f), f)
} else elems
})
}
As it can be seen that for every elem in the elems, I run a function that in turn gives me back another List. I do this until I reach the depth 0. So for example., I start with a certain elems and a certain depth like:
parse(depth = 2, elems = List("1", "2"), someFnThatGivesBackAListOfString)
What I'm doing with my code above is that for each element in elems, I check the depth value and if the depth is > 0, I run the function for that elem and go over the same process until I hit a depth of 0. This works as expected, but as it can be seen that it is not stack safe, I'm thiking of getting a tail recursive implementation. To my understanding tail recursion is about reduction, but here it is not the case. So how do I make it stack safe or how can I do a tail recursive logic here?
I started with something like this, but this is not quite right:
def firstAttempt[A](ls: List[A], depthOrig: Int)(f: (A => List[A])): List[A] = {
#annotation.tailrec
def helper(acc: List[A], ls: List[A], depth: Int): List[A] =
ls match {
case Nil => acc
case sublist # (head :: tail) =>
// Check if the entry is available in the bloom filter
if (depth > 0)
helper(acc ::: f(head), tail, depth - 1)
else
helper(acc.appended(head), tail, depthOrig)
}
helper(Nil, ls, depthOrig)
}
I got this to work by attaching the current depth to each element.
def parse[A](depth:Int, elems:List[A], f:A => List[A]): List[A] = {
#annotation.tailrec
def loop(todo:List[(A,Int)], acc:List[A]): List[A] = todo match {
case Nil => acc
case (_,dpth)::_ if dpth < 1 =>
val (zs, td) = todo.span(_._2 < 1)
loop(td, acc ++ zs.flatMap(_ => zs.map(_._1)))
case (elm,dpth)::tl =>
loop(f(elm).map(_ -> (dpth-1)) ++ tl, acc)
}
loop(elems.map(_ -> depth), Nil)
}

Filter from Seq less/greater elements and only one equal

I want to implement method in Scala which filters from Seq elements which are for example greater than provided value and additionally returns up to one equal element. For example:
greaterOrEqual(Seq(1,2,3,3,4), 3) shouldBe Seq(3,4)
I ended up with such method:
def greaterOrEqual(
seq: ArrayBuffer[Long],
value: Long
): ArrayBuffer[Long] = {
val greater = seq.filter(_ > value)
val equal = seq.filter(_ == value)
if (equal.isEmpty) {
greater
} else {
equal.tail ++ greater
}
}
but somehow it doesn't look nice to me :) Moreover, I'd like to have generic version of this method where I'd able to use not only Long type but custom case classes.
Do you have any suggestions?
Thanks in advance.
def foo[A : Ordering[A]](seq: Seq[A], value: A) = seq.find(_ == value).toList ++ seq.filter(implicitly[Ordering[A]].gt(_,value))
Or (different style)
def foo[A](seq: Seq[A], value: A)(implicit ord: Ordering[A]) = {
import ord._
seq.find(_ == value).toList ++ seq.filter(_ > value)
}
The code below is deprecated
scala> def foo[A <% Ordered[A]](seq: Seq[A], value: A) = seq.find(_ == value).toList ++ seq.filter(_ > value)
foo: [A](seq: Seq[A], value: A)(implicit evidence$1: A => Ordered[A])List[A]
scala> foo(Seq(1,2,3,3,4,4,5),3)
res8: List[Int] = List(3, 4, 4, 5)
Here's my take on it (preserving original order).
import scala.collection.mutable.ArrayBuffer
def greaterOrEqual[A]( seq :ArrayBuffer[A], value :A
)(implicit ord :Ordering[A]
) : ArrayBuffer[A] =
seq.foldLeft((ArrayBuffer.empty[A],true)){
case (acc, x) if ord.lt(x,value) => acc
case ((acc,bool), x) if ord.gt(x,value) => (acc :+ x, bool)
case ((acc,true), x) => (acc :+ x, false)
case (acc, _) => acc
}._1
testing:
greaterOrEqual(ArrayBuffer.from("xawbaxbt"), 'b')
//res0: ArrayBuffer[Char] = ArrayBuffer(x, w, b, x, t)
This is an excellent problem for a simple tail-recursive algorithm over lists.
def greaterOrEqual[T : Ordering](elements: List[T])(value: T): List[T] = {
import Ordering.Implicits._
#annotation.tailrec
def loop(remaining: List[T], alreadyIncludedEqual: Boolean, acc: List[T]): List[T] =
remaining match {
case x :: xs =>
if (!alreadyIncludedEqual && x == value)
loop(remaining = xs, alreadyIncludedEqual = true, x :: acc)
else if (x > value)
loop(remaining = xs, alreadyIncludedEqual, x :: acc)
else
loop(remaining = xs, alreadyIncludedEqual, acc)
case Nil =>
acc.reverse
}
loop(remaining = elements, alreadyIncludedEqual = false, acc = List.empty)
}
Which you can use like this:
greaterOrEqual(List(1, 3, 2, 3, 4, 0))(3)
// val res: List[Int] = List(3, 4)
You can use the below snippet:
val list = Seq(1,2,3,3,4)
val value = 3
list.partition(_>=3)._1.toSet.toSeq
Here partition method divide the list into two list. First list which satisfy the given condition, and second list contains the remaining elements.
For generic method you can using implicit Ordering. Any type who can compare elements can be handled by greaterOrEqual method.
import scala.math.Ordering._
def greaterOrEqual[T](seq: Seq[T], value: T)(implicit ordering: Ordering[T]): Seq[T] = {
#scala.annotation.tailrec
def go(xs: List[T], value: T, acc: List[T]): List[T] = {
xs match {
case Nil => acc
case head :: rest if ordering.compare(head, value) == 0 => rest.foldLeft(head :: acc){
case (result, x) if ordering.compare(x, value) > 0 => x :: result
case (result, _) => result
}
case head :: rest if ordering.compare(head, value) > 0 => go(rest, value, head :: acc)
case _ :: rest => go(rest, value, acc)
}
}
go(seq.toList, value, List.empty[T]).reverse
}

scala n-arity tree tail recursive evaluation

I have a Tree structure, which is more general than a binary tree structure
sealed trait Tree[+A]
case class Leaf[A](value: Terminal[A]) extends Tree[A]
case class Node[A](op: Function[A], branches: Tree[A]*) extends Tree[A]
As you see, it can have a arbitrary number of branches.
I'm trying to make an evaluation method to be tail recursive but i'm not being able to do it.
def evaluateTree[A](tree: Tree[A]): A = tree match {
case Leaf(terminal) => terminal.value
case Node(op: Function[A], args # _*) => op.operator((for (i <- args) yield evaluateTree(i)))
}
How can i save the stack manually?
If each Node can hold a different op then, no, I don't think tail recursion is possible.
If, on the other hand, you can feed all the Leaf.values to a single op then it might be possible.
def evaluateTree[A](tree: Tree[A]): A = {
#tailrec
def allValues(branches: Seq[Tree[A]], acc: Seq[A] = Seq()): Seq[A] =
if (branches.length < 1) acc
else branches.head match {
case Leaf(term) => allValues(branches.tail, term.value +: acc)
case Node(_, args: Seq[Tree[A]]) => allValues(branches.tail ++ args, acc)
}
tree match {
case Leaf(terminal) => terminal.value
case Node(op: Function[A], args: Seq[Tree[A]]) => op.operator(allValues(args))
}
}
I can't compile this as I don't have definitions for Terminal and Function, but it should be a reasonable outline of one approach to the problem.
Actually it was possible, using deep first search.
def evaluateTree[A](tree: Tree[A]): A = {
#tailrec
def evaluateWhile[C](l: List[Function[C]], arguments: List[List[C]], n_args: List[Int], f: Int => Boolean, acc: C): (List[Function[C]], List[List[C]], List[Int]) =
n_args match {
case h :: t if f(h) =>
evaluateWhile(l.tail, arguments.tail, n_args.tail, f, l.head.operator(arguments.head ::: List(acc)))
case h :: t =>
(l, (List(acc) ::: arguments.head) :: arguments.tail, List(n_args.head - 1) ::: n_args.tail)
case _ =>
(l, List(acc) :: arguments, n_args)
}
#tailrec
def DFS(toVisit: List[Tree[A]], visited: List[String] = Nil, operators: List[Function[A]] = Nil, arguments: List[List[A]] = Nil, n_args: List[Int] = Nil, debug: Int = 0): A = toVisit match {
case Leaf(id, terminal) :: tail if !visited.contains(id) => {
val (operators_to_pass, args_to_pass, n_args_to_pass) =
evaluateWhile[A](operators, arguments, n_args, x => x == 1, terminal.value)
DFS(toVisit.tail, visited ::: List(id), operators_to_pass, args_to_pass, n_args_to_pass, debug + 1)
}
case Node(id, op, args #_*) :: tail if !visited.contains(id) => {
DFS(args.toList ::: toVisit.tail, visited ::: List(id), op :: operators, List(Nil) ::: arguments, List(args.length ) ::: n_args, debug + 1)
}
case _ => arguments.flatten.head
}
DFS(List(tree))
}

Recursively iterate through a Scala list

I'm trying to recursively iterate through a list in Scala using pattern matching. I cannot use any list functions, or while/for loops. What I need to do is iterate through the list, and remove an element if it matches to be '4'. I'm new to Scala and I cannot find the answer in the textbook I have nor on google. Everyone else uses the filter method, or some other list method.
Here's what I tried to do (which is wrong)
def removeFours(lst: List[Int]): List[Int] = {
val newLst = lst
lst match {
case Nil => Nil
case a if a == 4 => newLst -= 0
case n => removeFours(newLst)
}
newLst
}
See if this works for you.
def removeFours(lst: List[Int], acc: List[Int] = List.empty): List[Int] = {
lst match {
case Nil => acc.reverse
case 4 :: t => removeFours( t, acc )
case h :: t => removeFours( t, h :: acc )
}
}
Usage:
scala> removeFours( List(3,7,4,9,2,4,1) )
res84: List[Int] = List(3, 7, 9, 2, 1)
Using an inner function and pattern matching to de-structure the list. If the head in the list is 4, then do not add it to the accumulator. If it is, append it to the accumulator.
def removeFours(lst: List[Int]): List[Int] = {
def loop(lst: List[Int], acc: List[Int]): List[Int] = lst match {
case Nil => acc
case h :: t =>
if (h == 4) {
loop(t, acc)
}else{
loop(t, acc :+ h)
}
}
loop(lst, List())
}
The preferred way to do this is with guards in the pattern match but the if else statement may look more familiar if you're just getting started with scala.
def removeFours(lst: List[Int]): List[Int] = {
def loop(lst: List[Int], acc: List[Int]): List[Int] = lst match {
case Nil => acc
case h :: t if (h == 4) => loop(t, acc)
case h :: t => loop(t, acc :+ h)
}
loop(lst, List())
}
I am not sure about the execution time. I am also new to scala but I am taking bollean approach to filter any list.
object Main extends App {
//fun that will remove 4
def rm_4(lst: List[Int]) : List[Int] = {
val a = lst.filter(kill_4)
a
}
// boolean fun for conditions
def kill_4(n: Int) : Boolean = {
if (n ==4) false
else true
}
println(rm_4(List(1,2,4,5,4))) // outpur List(1,2,5)
}

Difficulty understanding this type signature

merge sort type signature :
def msort[T](less: (T, T) => Boolean)(xs: List[T]): List[T] = {
The function is called using :
msort[Int]((a, b) => a < b) _
Does the type msort[Int] type the parameters a & b to Int ?
To better understand this type signature I've tried to extract the less function :
def lessFunc[Int]((a , b) : (Int , Int)) : Boolean = {
true
}
But this is not correct ?
Entire code :
def msort[T](less: (T, T) => Boolean)(xs: List[T]): List[T] = {
def merge(xs: List[T], ys: List[T], acc: List[T]): List[T] =
(xs, ys) match {
case (Nil, _) => ys.reverse ::: acc
case (_, Nil) => xs.reverse ::: acc
case (x :: xs1, y :: ys1) =>
if (less(x, y)) merge(xs1, ys, x :: acc)
else merge(xs, ys1, y :: acc)
}
val n = xs.length / 2
if (n == 0) xs
else {
val (ys, zs) = xs splitAt n
merge(msort(less)(ys), msort(less)(zs), Nil).reverse
}
}
This is a function which takes two lists of parameters. The first list contains a less function, which as you've guessed correctly when invoked with [Int] is typing the parameters to Int.
You have just expanded it wrong. What you should have done is
def less(a: Int, b: Int) = true
or to match your anonymous function
def less(a: Int, b: Int) = a < b
Now when you call your msort like msort[Int](less) _ (see currying) you'll get a new function which is able to sort Lits[Int].
val listSorter = msort[Int](less) _
listSorter(List(1, 2, 3))
def msort[T](less: (T, T) => Boolean)(xs: List[T]): List[T]
is a function with two parameter lists that returns List of type T. First parentheses let you pass a function that will be used for sorting the list.
(T,T) => Boolean - means that the function will take two parameters and yield boolean.
The second parentheses take a List of type T . This T after name of the function is like generics in Java. You use it to pass a type. It can be called like:
def msort[String]((a,b) => a.length < b.length)(some list) if you want to sort List of String's by their length. Or you can call it like in the example to sort List of Ints
def msort[Int]((a,b) => a < b)(some list)
Because function is defined with two sets of parameters we can take advantage of it by applying only part of them and build specialised functions based on that one. Like for example:
val stringSort = msort[String]((a,b) => a.length < b.length) _
val ascendingIntSort = msort[Int]((a,b) => a < b) _
These are curried functions because stringSort's signature is List[Strint] => List[String]. Now you can reuse these methods by passing only instances of Lists to them:
stringSort(List("cat", "elephant", "butterfly"))
ascendingIntSort(List(4,1,3,2))