Scala Do While Loop Not Ending - scala

I'm new to scala and i'm trying to implement a do while loop but I cannot seem to get it to stop. Im not sure what i'm doing wrong. If someone could help me out that would be great. Its not the best loop I know that but I am new to the language.
Here is my code below:
def mnuQuestionLast(f: (String) => (String, Int)) ={
var dataInput = true
do {
print("Enter 1 to Add Another 0 to Exit > ")
var dataInput1 = f(readLine)
if (dataInput1 == 0){
dataInput == false
} else {
println{"Do the work"}
}
} while(dataInput == true)
}

You're comparing a tuple type (Tuple2[String, Int] in this case) to 0, which works because == is defined on AnyRef, but doesn't make much sense when you think about it. You should be looking at the second element of the tuple:
if (dataInput1._2 == 0)
Or if you want to enhance readability a bit, you can deconstruct the tuple:
val (line, num) = f(readLine)
if (num == 0)
Also, you're comparing dataInput with false (dataInput == false) instead of assigning false:
dataInput = false

Your code did not pass the functional conventions.
The value that the f returns is a tuple and you should check it's second value of your tuple by dataInput1._2==0
so you should change your if to if(dataInput1._2==0)
You can reconstruct your code in a better way:
import util.control.Breaks._
def mnuQuestionLast(f: (String) => (String, Int)) = {
breakable {
while (true) {
print("Enter 1 to Add Another 0 to Exit > ")
f(readLine) match {
case (_, 0) => break()
case (_,1) => println( the work"
case _ => throw new IllegalArgumentException
}
}
}
}

Related

why does scala compile error on if else statement?

this is a scala code:
def otpu (start : Int, end : Int) : List[Int] = {
// TODO: Provide definition here.
if(start<end)
Nil
else if(start>end){
val list0:List[Int] = start::otpu(start-1,end)
list0
}
else if(start==end){
val list:List[Int] = List(end)
list
}
}
It works like otpu(5,1)=> List(5,4,3,2,1)
But when I compile,
I get a compiler error type mismatch, found: unit,require:List[Int]" at "if(start==end)".
When I delete if(start==end) and there is just else then it works.
Why does it not work with if(start==end)?
Consider the following.
val result = if (conditionA) List(9)
This is incomplete. What if conditionA is false? What is the value of result in that case? The compiler resolves this problem by silently competing the statement.
val result = if (conditionA) List(9) else ()
But now there's a new problem. () is of type Unit. (It's the only value of that type.) Your otpu method promises to return a List[Int] but the silent else clause doesn't do that. Thus the error.
The compilation error is due to the return type mismatch in if,elseif & else condition. As in above code else is missing, therefore the compiler fails to returns the value if & elseif condition are not satisfied.
def otpu(start: Int, end: Int): List[Int] = {
// TODO: Provide definition here.
if (start < end)
Nil
else if (start > end) {
val list0: List[Int] = start :: otpu(start - 1, end)
list0
}
else if (start == end) {
val list: List[Int] = List(end)
list
}
else Nil
}
As stated in the other answers you are missing the last else condition.
You can get that immediately if you convert the code to use pattern-matching, for instance:
def otpu (start : Int, end : Int) : List[Int] = {
start match {
case `end` => List(end)
case _ if start > end => start::otpu(start-1, end)
case _ => Nil
}
}
EDIT:
I noticed the tag recursion in the question and I thought you might want to end up with a recursive function for this. The way you implemented the recursive function is not really safe due to the fact that for a very (very) large list to be produced in output, you might incur in a stack overflow runtime error. To avoid that, Scala gives you the possibility of using tail-recursive functions. Here how it would look like:
def otpu(start: Int, end: Int) : List[Int] = {
import scala.annotation.tailrec
#tailrec
def f(e: Int, acc: List[Int]): List[Int] = {
start >= e match {
// base step
case false => acc
// recursive step
case true => f(e+1, e::acc)
}
}
// call the recursive function with the empty accumulator
f(end, Nil)
}

Scala: Make sure braces are balanced

I am running a code to balance brackets in statement. I think i have gotten it correct but it is failing on one particular statement, i need to understand why?
This is the test in particular it is failing "())("
More than the coding i think i need to fix the algo, any pointers?
def balance(chars: List[Char]): Boolean = {
def find(c: Char, l: List[Char], i: Int): Int={
if( l.isEmpty ) {
if(c=='(')
i+1
else if(c==')')
i-1
else
i
}
else if (c=='(')
find(l.head, l.tail, i+1)
else if(c==')')
find(l.head,l.tail, i-1)
else
find(l.head,l.tail, i)
}
if(find(chars.head, chars.tail,0) ==0 )
true
else
false
}
balance("())(".toList) //passes when it should fail
balance(":-)".toList)
balance("(if (zero? x) max (/ 1 x))".toList)
balance("I told him (that it's not (yet) done).\n(But he wasn't listening)".toList)
Here is a version:
def balance(chars: List[Char]): Boolean = {
def inner(c: List[Char], count: Int): Boolean = c match {
case Nil => count == 0 // Line 1
case ')' :: _ if count < 1 => false // Line 2
case ')' :: xs => inner(xs, count - 1) // Line 3
case '(' :: xs => inner(xs, count + 1) // Line 4
case _ :: xs => inner(xs, count) // Line 5
}
inner(chars, 0)
}
So in your code, I think you are missing the additional check for count < 1 when you encounter the right paranthesis! So you need an additional else if that checks for both the ')' and count < 1 (Line 2 in the example code above)
Using map:
def balance(chars: List[Char]): Boolean = {
chars.map(c =>
c match {
case '(' => 1
case ')' => -1
case _ => 0
}
).scanLeft(0)(_ + _).dropWhile(_ >= 0).isEmpty
}
You've made a very simple and completely understandable mistake. The parentheses in )( are balanced, by your current definition. It's just that they're not balanced in the way we would usually think. After the first character, you have -1 unclosed parentheses, and then after the second characte we're back to 0, so everything is fine. If the parenthesis count ever drops below zero, the parentheses cannot possibly be balanced.
Now there are two real ways to handle this. The quick and dirty solution is to throw an exception.
case object UnbalancedException extends Exception
if (i < 0)
throw UnbalancedException
then catch it and return false in balance.
try {
... // find() call goes in here
} catch {
case UnbalancedException => false
}
The more functional solution would be to have find return an Option[Int]. During the recursion, if you ever get a None result, then return None. Otherwise, behave as normally and return Some(n). If you ever encounter the case where i < 0 then return None to indicate failure. Then in balance, if the result is nonzero or the result is None, return false. This can be made prettier with for notation, but if you're just starting out then it can be very helpful to write it out by hand.
You can also use the property of Stack data structure to solve this problem. When you see open bracket, you push it into the stack. When you see close bracket, you pop from the stack (instead of Stack I'm using List, because immutable Stack is deprecated in Scala):
def isBalanced(chars: Seq[Char]): Boolean = {
import scala.annotation.tailrec
case class BracketInfo(c: Char, idx: Int)
def isOpen(c: Char): Boolean = c == '('
def isClose(c: Char): Boolean = c == ')'
def safePop[T](stack: List[T]): Option[T] = {
if (stack.length <= 1) stack.headOption
else stack.tail.headOption
}
#tailrec
def isBalanced(chars: Seq[Char], idx: Int, stack: List[BracketInfo]): Boolean = {
chars match {
case Seq(c, tail#_*) =>
val newStack = BracketInfo(c, idx) :: stack // Stack.push
if (isOpen(c)) isBalanced(tail, idx + 1, newStack)
else if (isClose(c)) {
safePop(stack) match {
case Some(b) => isBalanced(tail, idx + 1, stack.tail)
case None =>
println(s"Closed bracket '$c' at index $idx was not opened")
false
}
}
else isBalanced(tail, idx + 1, stack)
case Seq() =>
if (stack.nonEmpty) {
println("Stack is not empty => there are non-closed brackets at positions: ")
println(s"${stack.map(_.idx).mkString(" ")}")
}
stack.isEmpty
}
}
isBalanced(chars, 0, List.empty[BracketInfo])
}

is it possible to write functional version for below imperative code in scala

I wrote sum code in scala to find the majority element(the element which appears more than n/2 times where 'n' is the no.of elements in an array.I want to know where there is functional / scala native style of version(which includes match cases and transformations like "map/"flatmap" etc..) for the below imperative style of scala code which includes looping. The code which i used in:
object MajorityElement{
def printMajority(arr:Array[Int]) ={
var cand:Int=findCandidate(arr);
if(isMajority(arr,cand))
println(cand);
else
println("No Majority Element");
}
def isMajority(arr:Array[Int],Cand:Int):Boolean ={
var count=0;
for(i <- 0 until arr.length){
if(arr(i)== Cand)
count+=1;
}
if (count > arr.size/2)
return true;
else false
}
def findCandidate(arr:Array[Int]):Int ={
val s = arr.size
var majIndex:Int = 0;
var count = 1;
for(i <- 0 until arr.length){
if(arr(majIndex) == arr(i))
count+=1;
else
count-=1;
if(count==0)
{
majIndex = i;
count =1
}
}
return arr(majIndex);
}
}
please let me know, whether it is possible to write/ convert imperative style to functional version in scala(which uses match cases) for any scenario.
If you're only interested in the final result (and so you don't need isMajority etc), it's very simple
def findMajority(xs: List[Int]) = {
val mostFrequent = xs.groupBy(identity).values.maxBy(_.length)
if (mostFrequent.length >= xs.length / 2) Some(mostFrequent.head) else None
}
findMajority(List(1, 2, 2, 2, 3, 3, 3, 3, 3, 4))
//Option[Int] = Some(3)
Group equal elements into lists (the values of the Map returned by GroupBy). Pick the longest list. If its length is more than half the list, then it's a majority, return Some(the head) (any element will do, they're all the same value). Otherwise, return None
The transition from imperative thinking to functional thinking takes time and study. One approach is to find code examples here on SO and, with the help of the Standard Library, break it down until you understand what's going on.
Here's a little something to get you started.
def isMajority(arr:Array[Int],cand:Int):Boolean =
arr.count(_ == cand) > arr.size/2
Threr is no Native Scala Style, but code can be Functional Style(value oriented)
(No var, No Side-Effect, Pure Function)
object MajorityElement {
case class Candidate(idx: Int, count: Int)
def solve(arr: Array[Int]): Option[Int] = {
val candidate = findCandidate(arr)
if (isMajority(arr, candidate)) Option(arr(candidate.idx))
else None
}
def isMajority(arr: Array[Int], candidate: Candidate) =
arr.count(_ == arr(candidate.idx)) > arr.size / 2
def findCandidate(arr: Array[Int]): Candidate =
arr.indices.foldLeft(Candidate(0, 1)) { (acc, idx) =>
val newAcc =
if (arr(acc.idx) == arr(idx)) acc.copy(count = acc.count + 1)
else acc.copy(count = acc.count - 1)
if (newAcc.count == 0) Candidate(idx, 1)
else newAcc
}
}
val arr = Array(1, 1, 1, 2, 3, 4, 1)
val ret = MajorityElement.solve(arr)
ret match {
case Some(n) => println(s"Found Majority Element: $n")
case None => println("No Majority Element")
}

Count the occurrence of a specific character in a string by using substring in Scala

I am very new to programming. And I'm being asked to count the occurrence of a specific character in a string by using substring and recursion in scala. I am totally lost and I don't know how to check the equality of the second character in that string. I am not supposed to use tailrecursion and map. Many thanks!
My code so far looks like this:
def countChars(str:String, chr:Char):Int = {
if (str.length == 0) 0
else {
if (chr == str.substring(0,1)) 1
else 0} + countChars()
}
println(countChars())
First of all, this is a working version (Haven't used the shortest version to make it easier to read):
def countChars(str: String, chr: Char): Int = {
if (str.length == 0) {
0
} else {
(if (chr.toString() == str.substring(0, 1)) {
1
} else {
0
}) + countChars(str.substring(1), chr)
}
}
println(countChars("Hello World", 'l')) //> 3
You had two problems. First you didn't call countChars with the right parameters. And more important and maybe not very obvious: You compared a Char with a String. This will never be true:
chr == str.substring(0,1)
Because == or equals are both checking the type first, this is different. Just use a typecast or in this case a simple toString like I did.
Hope this helps you.
Edit Sorry just pressed the post button accidentily.
Here's a solution using a match on the existence/value of the first character at each iteration:
def countChars(str: String, chr: Char): Int = str.headOption match {
case None => 0
case Some(ch) if ch == chr => 1 + countChars(str.substring(1), chr)
case _ => countChars(str.substring(1), chr)
}
The idiomatic scala solution would be:
def countChars(str: String, chr: Char): Int = str.filter(_ == chr).length
I don't know why you would use map, but your question didn't say not to use filter
A variation from #cokeSchlumpf and #Shadowlands answers,
def countChars(s: String, c: Char): Int = {
if (s.isEmpty) 0
else if (s.substring(0,1).head == c) 1 + countChars(s.substring(1),c)
else countChars(s.substring(1),c)
}

What is Scala way of finding whether all the elements of an Array has same length?

I am new to Scala and but very old to Java and had some understanding working with FP languages like "Haskell".
Here I am wondering how to implement this using Scala. There is a list of elements in an array all of them are strings and I just want to know if there is a way I can do this in Scala in a FP way. Here is my current version which works...
def checkLength(vals: Array[String]): Boolean = {
var len = -1
for(x <- conts){
if(len < 0)
len = x.length()
else{
if (x.length() != len)
return false
else
len = x.length()
}
}
return true;
}
And I am pretty sure there is a better way of doing this in Scala/FP...
list.forall( str => str.size == list(0).size )
Edit: Here's a definition that's as general as possilbe and also allows to check whether a property other than length is the same for all elements:
def allElementsTheSame[T,U](f: T => U)(list: Seq[T]) = {
val first: Option[U] = list.headOption.map( f(_) )
list.forall( f(_) == first.get ) //safe to use get here!
}
type HasSize = { val size: Int }
val checkLength = allElementsTheSame((x: HasSize) => x.size)_
checkLength(Array( "123", "456") )
checkLength(List( List(1,2), List(3,4) ))
Since everyone seems to be so creative, I'll be creative too. :-)
def checkLength(vals: Array[String]): Boolean = vals.map(_.length).removeDuplicates.size <= 1
Mind you, removeDuplicates will likely be named distinct on Scala 2.8.
Tip: Use forall to determine whether all elements in the collection do satisfy a certain predicate (e.g. equality of length).
If you know that your lists are always non-empty, a straight forall works well. If you don't, it's easy to add that in:
list match {
case x :: rest => rest forall (_.size == x.size)
case _ => true
}
Now lists of length zero return true instead of throwing exceptions.
list.groupBy{_.length}.size == 1
You convert the list into a map of groups of equal length strings. If all the strings have the same length, then the map will hold only one such group.
The nice thing with this solution is that you don't need to know anything about the length of the strings, and don't need to comapre them to, say, the first string. It works well on an empty string, in which case it returns false (if that's what you want..)
Here's another approach:
def check(list:List[String]) = list.foldLeft(true)(_ && list.head.length == _.length)
Just my €0.02
def allElementsEval[T, U](f: T => U)(xs: Iterable[T]) =
if (xs.isEmpty) true
else {
val first = f(xs.head)
xs forall { f(_) == first }
}
This works with any Iterable, evaluates f the minimum number of times possible, and while the block can't be curried, the type inferencer can infer the block parameter type.
"allElementsEval" should "return true for an empty Iterable" in {
allElementsEval(List[String]()){ x => x.size } should be (true)
}
it should "eval the function at each item" in {
allElementsEval(List("aa", "bb", "cc")) { x => x.size } should be (true)
allElementsEval(List("aa", "bb", "ccc")) { x => x.size } should be (false)
}
it should "work on Vector and Array as well" in {
allElementsEval(Vector("aa", "bb", "cc")) { x => x.size } should be (true)
allElementsEval(Vector("aa", "bb", "ccc")) { x => x.size } should be (false)
allElementsEval(Array("aa", "bb", "cc")) { x => x.size } should be (true)
allElementsEval(Array("aa", "bb", "ccc")) { x => x.size } should be (false)
}
It's just a shame that head :: tail pattern matching fails so insidiously for Iterables.