Scala - recursive compare function - scala

I'm working on a function to recursively run through a list of Ints and return a Boolean stating whether each item in the list is the same number. I've taken a stab at it below but it's not passing the tests I'm running. Here's what I've got, any suggestions are much appreciated. Thanks!
def equalList (xs : List[Int]) : Boolean = {
def equalAux (xs:List[Int], value:Int) : Boolean = {
xs match {
case Nil => true
case x :: xs if (x == value) => equalAux(xs, x)
case x :: xs if (x != value) => false
}
}
equalAux(xs, x)
}

As you said in your comment, you just need to make sure the list is not empty so you can give an initial value to your recursive function:
def equalList(xs: List[Int]): Boolean = {
def equalAux (xs: List[Int], value: Int): Boolean = {
xs match {
case Nil => true
case x :: xs if x == value => equalAux(xs, x)
case x :: _ if x != value => false
}
}
// Check to make sure the list has at least one item initially
xs match {
case Nil => true
case head :: tail => equalAux(tail, head)
}
}
println(equalList(List.empty)) // true
println(equalList(List(1))) // true
println(equalList(List(1, 1, 1, 1))) // true
println(equalList(List(1, 1, 1, 1, 2))) // false
println(equalList(List(1, 2, 1))) // false

Do you need a recursive function? If not, I would use Set as a trick:
myList.toSet.size <= 1 // because empty list returns true. Else make it == 1
If you do need recursion, then #Tyler answer is the answer I would also give.

Related

How to compare elements of an array in scala (using tail recursive)

I'm trying to solve the following problem and cannot find any solutions, could you please help with this:
Implement a higher order function that checks if an Array[A] is sorted given a comparison function as an argument:
def isSorted[A](as: Array[A], comparison: (A, A) => Boolean): Boolean
Ensure that your implementation is tail recursive, and use an appropriate annotation.
Example1:
isSorted[Int](Array(1, 2, 3), (x, y) => x <= y)
should be true
Example2:
isSorted[Int](Array(2, 2, 2), (x, y) => x == y)
should be true
Example3:
isSorted[Int](Array(2, 2, 2), (x, y) => x < y)
should be false
def isSorted[A](as: Array[A], comparison: (A, A) => Boolean): Boolean = {
#scala.annotation.tailrec
def iterator(as: Array[A], a: Int, b: Int): Boolean =
if (as.size == 0 || as.size == 1)
true
else if (b + 1 < as.size)
if (comparison(as(a), as(b)))
iterator(as, b, b + 1)
else
false
else
true
iterator(as, 0, 1)
}
How would you solve it without the extra constraints? You would have to check that
For all indices i in the range 0 until arr.size - 1
the condition comparison(arr(i), arr(i + 1)) holds.
That is:
def isSorted[A](arr: Array[A])(cmp: (A, A) => Boolean) =
(0 until (arr.size - 1)).forall(i => cmp(arr(i), arr(i + 1)))
Now, where's the iteration/recursion hidden? It's inside of the forall
method for the range. So, reimplement the forall on your own,
obeying the constraints of the task:
def rangeForall(r: Range, p: Int => Boolean): Boolean = {
#annotation.tailrec
def rec(idx: Int): Boolean =
if (idx >= r.end) {
true
} else if (p(idx)) {
rec(idx + 1)
} else {
false
}
rec(r.start)
}
Note how it can be tested separately, and that it requires neither nested functions nor generics or anything like that.
Use that instead of the built-in forall:
def isSorted[A](as: Array[A])(cmp: (A, A) => Boolean) =
rangeForall(0 until (as.size - 1), i => cmp(as(i), as(i + 1)))
Sanity check:
println(isSorted(Array(1, 2, 3))(_ <= _)) // true
println(isSorted(Array(2, 2, 2))(_ == _)) // true
println(isSorted(Array(2, 2, 2))(_ < _)) // false
Note that the function signature has two argument lists: this is necessary so that the type parameter is inferred from the array only, before the type checker gets to the second argument list. In this way, you don't have to write out the [Int] every time.
Short and sweet.
#annotation.tailrec
def isSorted[A](as: Seq[A], comparison: (A,A)=>Boolean): Boolean = as match {
case Seq() => true
case Seq(_) => true
case a+:b+:z => if (comparison(a,b)) isSorted(b+:z, comparison)
else false
}

how can I write a function in scala called Order that takes one arguement: a list of Ints. And returns the same List of Ints from least to greatest

I've got a base case and a recursive call but I don't know where to go from there.I do also need to use pattern matching
def order(ls:List[Int]):List[Int] = ls match {
case Nil => Nil
case h::t => order(t)
I'm pretty sure you are looking for a recursive sort algorithm.
You can take a look at merge sort for example. This is a simplified Non generic version
def mergeSort(ls: List[Int]): List[Int] = {
def merge(l: List[Int], r: List[Int]): List[Int] = (l, r) match {
case (Nil, _) => r
case (_, Nil) => l
case (lHead :: lTail, rHead :: rTail) =>
if (lHead < rHead) {
lHead :: merge(lTail, r)
} else {
rHead :: merge(l, rTail)
}
}
val n = ls.length / 2
if (n == 0)
ls
else {
val (a, b) = ls splitAt n
merge(mergeSort(a), mergeSort(b))
}
}
Try This
def order(ls:List[Int]):List[Int] = ls match {
case Nil => Nil
case h => h.sorted
}
OR
def order(ls:List[Int]):List[Int] = ls match {
case Nil => Nil
case h => h.sortWith(_ < _)
}

Find an element in a list in Scala

I'm trying to write a function myfoo which, taken an Int and a list of ints, verifies if the int element is in the list or not. It should return "true" if the int is in the list, false otherwise.
I've written this function, but when I compile it it returns this error:
error: type mismatch;
found : Unit
required: Boolean
breakable { for (i <-l) {
^
one error found*
This is my program:
import scala.util.control.Breaks._
object findEl extends App{
def myfoo (x:Int,l:List[Int]):Boolean={
breakable { for (i <-l) {
i match {
case a if (a==x) => true
case _ => false
break
}
}
}
}
println(myfoo(1,List(1,2,3,4))) //should print "true"
}
How can I solve it? :)
This is how breakable is implemented
def breakable(op: => Unit) {
try {
op
} catch {
case ex: BreakControl =>
if (ex ne breakException) throw ex
}
}
Breakable returns Unit finally. So thats why compiler is complaining.
Here is one way to fix this. Notice I am using var
import scala.util.control.Breaks._
object findEl extends App {
def myfoo(x: Int, l: List[Int]): Boolean = {
var res: Boolean = false
breakable {
for (i <- l) {
i match {
case a if a == x => res = true
break
case _ => ()
}
}
}
res
}
println(myfoo(1, List(1, 2, 3, 4))) //should print "true"
}
Functional way (better way) of implementing the same
def myFoo(num: Int, list: List[Int]): Boolean = list match {
case Nil => false
case `num` :: xs => true
case _ => myFoo(num, list.tail)
}
Below code is same but does not use back ticks
def myFoo(num: Int, list: List[Int]): Boolean = list match {
case Nil => false
case x :: xs if x == num => true
case _ => myFoo(num, list.tail)
}
Scala REPL
scala> def myFoo(num: Int, list: List[Int]): Boolean = list match {
| case Nil => false
| case `num` :: xs => true
| case _ => myFoo(num, list.tail)
| }
myFoo: (num: Int, list: List[Int])Boolean
scala> myFoo(1, List(2, 1, 2))
res0: Boolean = true
Using breakable is not functional practice
Halting the execution of the program using an exception is not functional. Functional programming advocates communicating through interpretation of types. Internally breakable halts the control flow by throwing exception.
Above second way is the way to solve the problem functionally.
you can use this trick instead
def function myFoo(x:Int, xList:List[Int]) = xList.contains(x)
println(myFoo(1, List(1,2,3,4,5,6)))

how to check whether given List[Int] is sorted in scala?

I would like to know whether is there any isSorted() function exist or not in scala.
Question: check whether List[Int] is sorted or not, If not remove smallest number and do again till List[Int] become sorted?
I want only 1 or 2 line program.
You can compare each pair in the input sequence for lists containing more than 1 item:
def isSorted[T](s: Seq[T])(implicit ord: Ordering[T]): Boolean = s match {
case Seq() => true
case Seq(_) => true
case _ => s.sliding(2).forall { case Seq(x, y) => ord.lteq(x, y) }
}
It's not the best solution but you can use sorted method on list and then compare it with original one;
def sorted(l: List[Int]): Boolean = l == l.sorted
With some lazyness:
def isSorted(l:List[Int]):Boolean = {
val list = l.view
!list.zip(list.tail).exists {case (x,y) => x>y}
}
Performing a sort just to check if the list is already sorted is a bit of an overkill. The optimal solution here seems to be the most obvious one, which is just describing the problem in human language and transferring it into code:
def isSorted[T](list: List[T])(implicit ord: Ordering[T]): Boolean = list match {
case Nil => true // an empty list is sorted
case x :: Nil => true // a single-element list is sorted
case x :: xs => ord.lteq(x, xs.head) && isSorted(xs) // if the first two elements are ordered and the rest are sorted, the full list is sorted too
}
If you want it shorter, you could trade the 2nd case for a bit of readability:
def isSorted[T](list: List[T])(implicit ord: Ordering[T]): Boolean = list match {
case Nil => true
case x :: xs => xs.headOption.fold(true)(ord.lteq(x, _)) && isSorted(xs)
}
If you want a one-liner, that would be not readable at all:
def isSorted[T](list: List[T])(implicit ord: Ordering[T]): Boolean = list.headOption.fold(true)(a => list.tail.headOption.fold(true)(ord.lteq(a, _) && isSorted(list.tail.tail)))
def isSorted(xs: List[Int]): Boolean = (xs.tail zip xs).forall(pair => pair._1 - pair._2 > 0)
Using `zip`
Lets do it without actually sorting the list.
Drop the head element in the intermediate list and then compare in pairs with original list. This way, ith element compares with i+1th element of the original list.
scala> val originalList = List(10, 20, 30, 40)
val originalList: List[Int] = List(10, 20, 30, 40)
scala> val intermediate = originalList.drop(1)
val intermediate: List[Int] = List(20, 30, 40)
scala> originalList.zip(intermediate)
val res5: List[(Int, Int)] = List((10,20), (20,30), (30,40))
scala> originalList.zip(intermediate).forall { case (orig, in) => orig <= in }
val res17: Boolean = true
A inefficient but easy to understand answer:
def specialSort(a: List[Int]): List[Int] =
if (a == a.sorted) a
else specialSort(a.filterNot(_ == a.min))
l == l.sorted didn't work for me, managed to do it with l sameElements l.sorted
Here your one-line homework solution
def removeMinWhileNotSorted[A: Ordering](xs: List[A]): List[A] = if (xs == xs.sorted) xs else xs.splitAt(xs.indexOf(xs.min)) match {case (prefix, m :: postfix) => removeMinWhileNotSorted(prefix ++ postfix)}
It does not exists. But it is easy to do: create a list with the joined version of the list and the same list sorted as you want and verify both elements of the joined list are the same.
Something like this:
import org.junit.Assert._
val sortedList = List(1, 3, 5, 7)
val unsortedList = List(10, 1, 8, 3, 5, 5, 2, 9)
// detailed test. It passes.
sortedList
.zip(sortedList.sortWith((a,b) => a.compareTo(b) < 0)) // this is the required sorting criteria.
.foreach(x => assertEquals("collection is not sorted", x._1, x._2))
// easier to read but similar test. It fails.
unsortedList
.zip(unsortedList.sorted) // this is the required sorting criteria.
.foreach(x => assertEquals("collection is not sorted", x._1, x._2))
a function could be:
def isSorted(list: List[Int]): Boolean = !list.zip(list.sortWith((a, b) => a.compareTo(b) < 0)).exists(p => !p._1.equals(p._2))
def isSorted[T <% Ordered[T]](list: List[T]): Boolean =
list.sliding(2).forall(p => (p.size==1) || p(0) < p(1))
I assumed that if two neighbor elements are equal it is legal too.
def isSorted[T <% Ordered[T]](l: List[T]):Boolean ={
val a = l.toArray
(1 until a.length).forall(i => a(i-1) <= a(i))
}
Another possibility (not necessarily any better than some of the other suggestions)
def isSorted[T <% Ordered[T]](a: List[T]): Boolean =
if (a == Nil) true // an empty list is sorted
else a.foldLeft((true, a.head))(
(prev, v1) => {
val (p, v0) = prev
(p && v0 <= v1, v1)
})._1
Results for a few test cases:
isSorted(Nil) -> true
isSorted(1 :: Nil) -> true
isSorted(2 :: 3 :: Nil) -> true
isSorted(1 :: 2 :: 5 :: 8 :: Nil) -> true
isSorted(1 :: 1 :: 2 :: 2 :: Nil) -> true
isSorted(3 :: 2 :: Nil) -> false
isSorted(1 :: 2 :: 3 :: 1 :: Nil) -> false
You can use tail recursion to less create objects and to avoid stack overflow for long lists. This version is lazy, function return value instantly after a first unordered pair.
#scala.annotation.tailrec
def isSorted[T : Ordering](values: List[T]): Boolean = {
import scala.math.Ordering.Implicits._
values match {
case fst :: snd :: _ if fst <= snd => isSorted(values.tail)
case _ :: _ :: _ => false
case _ => true
}
}
This works.
def check(list: List[Int]) = {
#tailrec
def isSorted(list: List[Int], no: Int, acc: Boolean): Boolean = {
if (list.tail == Nil) acc
else if (list.head > no) {
isSorted(list.tail, list.head, acc = true)
}
else isSorted(list.tail, list.head, acc=false)
}
isSorted(list, Integer.MIN_VALUE, acc = false)
}

Implementing `elem` with foldLeft

I'm working on Learn You a Haskell. On the "fold" section, I need to implement elem (given an element, find out if it's in the list - True or False).
def myElem(a: Char, as: List[Char]): Boolean = as match {
case Nil => false
case x::Nil => println(x); if(x == a) true else false
case x::_ => println(x); as.foldLeft(false){ (_, elem) =>
if(a == elem) true
else myElem(a, as.tail)
}
}
However, it's failing on a simple example:
scala> myElem('a', "ab".toList)
a
b
res8: Boolean = false
What am I doing wrong here? Also, as extra, I'd appreciate any suggestion on improvement of this code.
As an aside, I would think a find would be more appropriate here.
This is a pretty simple implementation:
def elem[A](a: A, as: List[A]): Boolean = as match {
case Nil => false
case h :: t => (h == a) || elem(a, t)
}
Also, instead of find you could use exists:
def elem[A](a: A, as: List[A]) = as.exists(_ == a)
If you want to foldLeft you can, but you'll still traverse the whole list instead of stopping early:
def elem[A](a: A, as: List[A]) =
as.foldLeft(false)((bool, value) => bool || value == a)