Define if numbers in list are less than one in parameter - Scala - scala

Write a function which at the input takes two parameters: a list of integers and a number.
The output returns a logical value.
The function returns "true" if all numbers in the list are smaller than the number given in the second parameter. Otherwise, the function returns "false".
My code:
def less [A](list:List[A], number:Int):Boolean =
if (list == Nil) false
else ((List.head < number) && less[A](list:List.tail, number:Int))
less(List(1, 2, 3, 4), 5)
less(List(6,1,2,3),6)
Error message in IntelliJ:
On line 3: error: value head is not a member of object List
else (List.head < number) && less[A](list:List.tail, number:Int) //2
^
On line 3: error: type tail is not a member of object List
My question: What should I improve in this code to have it working?

Seems an awful lot like home work...
Scala has a forall function that can test a predicate against all values in the collection and returns a Boolean.
def less(xs: List[Int], number: Int) = xs.forall(x => ???)

I think you want something like this:
def less (list:List[Int], number:Int):Boolean =
if (list == Nil) true
else ((list.head < number) && less(list.tail, number))
less(List(1, 2, 3, 4), 5)//true
less(List(6,1,2,3),6)//false
But you should just use forall like #Brian said

Related

trying to solve palindrome integer in python 3 code is working but giving wrong output

enter code here''' class Solution:
def isPalindrome(self, x: int) -> bool:
x = str(x)
lst = list(x)
str_val = []
count = len(lst)
for i in range(len(lst)):
str_val.append(lst[count-1])
count -= 1
value = [str(i) for i in str_val]
res = int("".join(value))
if int(res) == x:
return True
else:
return False
'''
trying to solve palindrome integer in python 3 code is working but giving wrong output.
If you're just trying to check for integers only, you can try the below code. It's a two pointer approach.
class Solution:
def isPalindrome(self, x: int) -> bool:
x = str(x)
if len(x) < 2: return True
s, e = 0, len(x)-1
while s < e:
if x[s] != x[e]: return False
s += 1
e -= 1
return True
You can also do this in one line in python to check if a number (as a string) and it's reverse is same or not.
str(x) == str(x)[::-1]
The reason your results are not as expected is due to the type change that you make in the first line of your function.
x = str(x)
It is necessary to convert x into a string so that you can iterate over it and put it into a list for your second line of code:
lst = list(x)
but by re-assigning that back to x, you get an x at the end of the function call that is not equal to the int(res) when you make the final comparison to get your boolean:
if int(res) == x:
A simple solution is to just not assign the temporary string that is created from the parameter x back to itself, and rather to just merge the first and second lines of your function into one:
lst = list(str(x))

unable to understand the else if statement in scala code below

I am pretty new to Scala and was going through the docs when I came across this code in the below link
https://www.scala-lang.org/old/node/135.html
def filter(xs: List[Int], p: Int => Boolean): List[Int] =
if (xs.isEmpty) xs
else if (p(xs.head)) xs.head :: filter(xs.tail, p)
else filter(xs.tail, p)
Can anyone please tell me what the else if line does?
The second parameter to the filter function p is a function that takes Int as a parameter and returns Boolean.
So, in the else if, it is calling the function p with xs.head which is first element from xs which is Int. If it returns true, it adds an element at the beginning of a list and returns a list with the added element.
To test this -
You can try two variations of p one which returns true when number is even and one which returns true when the number is odd and see what it prints.
val output = filter(List(1,2,3,4), (p) => p % 2 != 0);
print(output) // prints `List(1, 3)`
val output = filter(List(1,2,3,4), (p) => p % 2 == 0);
print(output) // prints `List(2, 4)`
Hope this helps!

Type Mismatch Unit and String in Scala

I am trying to take from a list of tuples (e.g. List[(String, String)]) some words that have the difference between the number of syllables smaller than 2.
If that is ok, I return them - however, I have some issues: I get Unit found and String expected.
def ecrire():String = {
// Choose deux output: List[(Word, Word)]
// I take every tuple of the list and proceed as the element "b"
for (b <- choose_deux()){
val x = b._1
val y = b._2
val diff = Math.abs(x.syllabes - y.syllabes)
// Check if difference between syllables is smaller than 2
if(diff <= 2)
return x.toString() + "\n" + y.toString()
}
}
}
Now I know that probably I have to do a yield at the bottom, but yield what exactly? The idea is that if the condition shown in the "if" is respected, I write the string made of these two elements.
The error is shown at the for loop: type mismatch; found: Unit; required: String
Could you please help me a bit? I am still new and learning!
Type mismatch error is because your for loop doesn't have else statement and you can't return using if inside a for loop. So for loop is not returning anything so scala compiler assumes the return type to be () i.e. unit() and you have defined the return type as String.
Defining the functions in the following way should solve your issue
def diff(x) = Math.abs(x._1.syllabes - x._2.syllabes)
for (b <- choose_deux() if(diff(b) <= 2)) yield b._1.toString() + "\n" + b._2.toString()

Getting an error trying to map through a list in Scala

I'm trying to print out all the factors of every number in a list.
Here is my code:
def main(args: Array[String])
{
val list_of_numbers = List(1,4,6)
def get_factors(list_of_numbers:List[Int]) : Int =
{
return list_of_numbers.foreach{(1 to _).filter {divisor => _ % divisor == 0}}
}
println(get_factors(list_of_numbers));
}
I want the end result to contain a single list that will hold all the numbers which are factors of any of the numbers in the list. So the final result should be (1,2,3,4,6). Right now, I get the following error:
error: missing parameter type for expanded function ((x$1) => 1.to(x$1))
return list_of_numbers.foreach{(1 to _).filter {divisor => _ % divisor == 0}}
How can I fix this?
You can only use _ shorthand once in a function (except for some special cases), and even then not always.
Try spelling it out instead:
list_of_numbers.foreach { n =>
(1 to n).filter { divisor => n % divisor == 0 }
}
This will compile.
There are other problems with your code though.
foreach returns a Unit, but you are requiring an Int for example.
Perhaps, you wanted a .map rather than .foreach, but that would still be a List, not an Int.
A few things are wrong here.
First, foreach takes a function A => Unit as an argument, meaning that it's really just for causing side effects.
Second your use of _, you can use _ when the function uses each argument once.
Lastly your expected output seems to be getting rid of duplicates (1 is a factor for all 3 inputs, but it only appears once).
list_of_numbers flatMap { i => (1 to i) filter {i % _ == 0 }} distinct
will do what you are looking for.
flatMap takes a function from A => List[B] and produces a simple List[B] as output, list.distinct gets rid of the duplicates.
Actually, there are several problems with your code.
First, foreach is a method which yields Unit (like void in Java). You want to yield something so you should use a for comprehension.
Second, in your divisor-test function, you've specified both the unnamed parameter ("_") and the named parameter (divisor).
The third problem is that you expect the result to be Int (in the code) but List[Int] in your description.
The following code will do what you want (although it will repeat factors, so you might want to pass it through distinct before using the result):
def main(args: Array[String]) {
val list_of_numbers = List(1, 4, 6)
def get_factors(list_of_numbers: List[Int]) = for (n <- list_of_numbers; r = 1 to n; f <- r.filter(n%_ == 0)) yield f
println(get_factors(list_of_numbers))
}
Note that you need two generators ("<-") in the for comprehension in order that you end up with simply a List. If you instead implemented the filter part in the yield expression, you would get a List[List[Int]].

Scala comparison error

I am trying to compare an item from a List of type Strings to an integer. I tried doing this but I get an error saying that:
'value < is not a member of List[Int]'
The line of code that compares is something similar to this:
if(csvList.map(x => x(0).toInt) < someInteger)
Besides the point of why this happens, I wondered why I didn't get an error
when I used a different type of comparison, such as ' == '.
So if I run the line:
if( csvList.map(x => x(0).toInt) == someInteger)
I don't get an error. Why is that?
Let's start with some introductions before answering the questions
Using the REPL you can understand a bit more what you are doing
scala> List("1", "2", "3", "33").map(x => x(0).toInt)
res1: List[Int] = List(49, 50, 51, 51)
The map function is used to transform every element, so x inside the map will be "1" the first time, "2" the second, and so on.
When you are using x(0) you are accessing the first character in the String.
scala> "Hello"(0)
res2: Char = H
As you see the type after you have mapped your strings is a List of Int. And you can compare that with an Int, but it will never be equals.
scala> List(1, 2, 3) == 5
res0: Boolean = false
This is very much like in Java when you try
"Hello".equals(new Integer(1));
If you want to know more about the reasons behind the equality problem you can check out Why has Scala no type-safe equals method?
Last but not least, you get an error when using less than because there is no less than in the List class.
Extra:
If you want to know if the second element in the list is smaller than 2 you can do
scala> val data = List("1", "10", "20")
data: List[String] = List(1, 10, 20)
scala> 5 < data(1).toInt
res2: Boolean = true
Although it is a bit strange, maybe you should transform the list of string is something a bit more typed like a case class and then do your business logic with a more clear data model.
You can refer to
Why == operator and equals() behave differently for values of AnyVal in Scala
Every class support operator ==, but may not support <,> these operators.
in your code
csvList.map(x => x(0).toInt)
it returns a List<int>, and application use it to compare with a int,
so it may process a implicit type conversion. Even the compiler doesn't report it as a error. Generally, it's not good to compare value with different types.
csvList.map(x => x(0).toInt) converts the entire csvList to a List[Int] and then tries to apply the operator < to List[Int] and someInteger which does not exist. This is essentially what the error message is saying.
There is no error for == since this operator exists for List though List[T] == Int will always return false.
Perhaps what you are trying to do is compare each item of the List to an Int. If that is the case, something like this would do:
scala> List("1","2","3").map(x => x.toInt < 2)
res18: List[Boolean] = List(true, false, false)
The piece of code csvList.map(x => x(0).toInt) actually returns a List[Int], that is not comparable with a integer (not sure what it would mean to say that List(1,2) < 3).
If you want to compare each element of the list to your number, making sure they are all inferior to it, you would actually write if(csvList.map(x => x.toInt).forall { _ < someInteger })