How to compare two decimals of different length Groovy [duplicate] - groovy

Let's say I have a following list of library's versions:
List myList = ["4.11", "4.12", "4.13", "5.1"]
I need to check if the first element of the list is equal to or greater than "4.11".
I do it this way:
#compateTo() returns 0 if the caller string equals to the argument string
#compateTo() returns > 0 if the caller string is greater than the argument string
if (myList[0].compareTo("4.11") >= 0) {
println("equal or greater than 4.11")
} else {
println("less than 4.11")
}
However, let's consider this case:
List myList = ["4.9"]
Comparing two strings character by character it gets to 9 compared to 1 and since 9 is greater than 1 it returns equal or greater than 4.11, which is incorrect.
What would be the best way to fix it? I considered this:
def strToDecimal = Double.parseDouble(myList[0])
to get a decimal number and compare two decimal numbers 4.9 and 4.11 but the problem is the same.
I cannot use anything that would require an import statement.

If you're using Java >= 9, I'd go with the Version class:
// List myList = ["4.11", "4.12", "4.13", "5.1"]
List myList = ["4.9"]
if (java.lang.module.ModuleDescriptor.Version.parse(myList[0]).compareTo(java.lang.module.ModuleDescriptor.Version.parse("4.11")) >= 0) {
println("equal or greater than 4.11")
} else {
println("less than 4.11")
}
If your Java version is <= 9, then you may checkout this question. There are some ideas on how to solve your problem.

Related

Comparing library version strings in Groovy

Let's say I have a following list of library's versions:
List myList = ["4.11", "4.12", "4.13", "5.1"]
I need to check if the first element of the list is equal to or greater than "4.11".
I do it this way:
#compateTo() returns 0 if the caller string equals to the argument string
#compateTo() returns > 0 if the caller string is greater than the argument string
if (myList[0].compareTo("4.11") >= 0) {
println("equal or greater than 4.11")
} else {
println("less than 4.11")
}
However, let's consider this case:
List myList = ["4.9"]
Comparing two strings character by character it gets to 9 compared to 1 and since 9 is greater than 1 it returns equal or greater than 4.11, which is incorrect.
What would be the best way to fix it? I considered this:
def strToDecimal = Double.parseDouble(myList[0])
to get a decimal number and compare two decimal numbers 4.9 and 4.11 but the problem is the same.
I cannot use anything that would require an import statement.
If you're using Java >= 9, I'd go with the Version class:
// List myList = ["4.11", "4.12", "4.13", "5.1"]
List myList = ["4.9"]
if (java.lang.module.ModuleDescriptor.Version.parse(myList[0]).compareTo(java.lang.module.ModuleDescriptor.Version.parse("4.11")) >= 0) {
println("equal or greater than 4.11")
} else {
println("less than 4.11")
}
If your Java version is <= 9, then you may checkout this question. There are some ideas on how to solve your problem.

Checking if the integer only contains odd number

I can't figure out what I'm doing wrong, but my solution seems to be not working.
Check that the given positive integer n contains only odd digits (1, 3, 5, 7 and 9) when it is written out. Return True if this is the case, and False otherwise. Note that this question is not asking whether the number n itself is odd or even. You therefore will have to look at every digit of the given number before you can proclaim that the number contains no odd digits.
My solution (for Python)
def only_odd_digits(n):
b = list(str(n))
onlyodd = [1,3,5,7,9]
for index, value in enumerate(b):
if value in onlyodd:
return True
else:
return False
Can someone help? Thanks
You can also use all to avoid the loops, and then use modulo as already suggested by alparslan mimaroğlu to avoid the lookup:
def only_odd_digits(n):
digits = map(int, str(n))
return all(dig % 2 for dig in digits)
I liked the set-based answer which got deleted now. It works when using it like this:
def only_odd_digits(n):
return set(str(n)).issubset(set("13579"))
You already created the list of integers you want to check.
You just have to check every digit if it is divisible by 2.
If any of them are you can just return False. If none of them are you can return True
def only_odd_digits(n):
digits = [int(digit) for digit in str(n)]
for digit in digits:
if digit % 2 == 0:
return False
return True
Use the following codes:
def odd(n):
return set(str(n))-set('13579')==set()

I don't know why the correct answer isn't coming up

I'm novice programmer.
I want the smallest of the input values ​​to be output, but I don't know what's wrong.
Input example :
10
10 4 2 3 6 6 7 9 8 5
Output example :
2
n = int(input())
a = input().split()
min=a[0]
for i in range(n) :
if a[i] < min :
min = a[i]
print(min)
what is the problem? please help me
Your code should work (and it does for me).
Nevertheless, min is a reserved Python word. Taking that into consideration, I also recommend the following changes for it to be more idiomatic:
a = input().split()
min_num = a[0]
for element in a:
if element < min :
min = element
print(min)
Variables can be either number or strings. For example "2" is different from 2.
The function split returns an array of strings. You would need to convert each to a number if you want to do number comparison, like:
n = int(input())
a = input().split()
min=int(a[0])
for i in range(n) :
if int(a[i]) < min :
min = int(a[i])
print(min)
Note: you already did that for n (first line in original code), but you did not do the same when you access a.
So, min is actually a python built-in, which would be very useful in this scenario. Also, you are not making the input values in a into integers, so we can do that too:
n = int(input())
a = list(map(int, input().split()))
print(min(a))
We use map to turn all the values from the split list into integers, then turn the map object back into a list. Then, using min, we can find the smallest number very easily, without a for loop.
I think you should convert each element to integers before comparing them.
a = [int(i) for i in input().split()]
Your code should work, but it will compare strings against strings instead of integers against integers.

Finding the median of an array of floating point numbers

I've looked through all the examples in here already of this and nothing quite answers my question. I'm very new to Groovy.
I want to create something like a list or an array of floating point numbers, prices such as 239.99.
I then want to pass that array or list to a method that will determine the median price in that array or list of numbers. The total size will vary.
Is there any quick and easy code to do this? How do I add each number to the array or list and must I use doubles?
Any help is appreciated, this one has me stuck and frustrated.
Thanks!
The following function determines the median for non-empty lists.
def median(data) {
def copy = data.toSorted()
def middle = data.size().intdiv(2)
// you can omit the return in groovy for the last statement
data.size() % 2 ? copy[middle] : (copy[middle - 1] + copy[middle]) / 2
}
It works with all types that support addition and division.
For example:
assert median([1, 7, 4, 3]) == 3.5
assert median([1, 7, 4]) == 4
assert median([1, 7]) == 4
assert median([1]) == 1
assert median([1.7, 3.4, 10.9, 4.2]) == 3.8
In terms of what you can do with lists check the Lists overview and then the List API.

groovy: how to simplify/rewrite this method in groovy

protected int xMethod (Integer a, Integer b) {
if (a<b)
return 1
else if (a>b)
return 2
else
return 3
}
I wonder if there is some way of rewriting above method differently in groovy? as now is very Java style.
It seems that the function just needs to return 3 different values depending on whether a is less than, equal to, or greater than b. There is already an operator in Groovy that does this:
a <=> b
The return values are -1, 0 and 1. Perhaps the best thing to do is refactor the code to use this operator instead of xMethod, if that is possible.
Of course, if the precise values 1, 2 and 3 are important and not just 3 distinct values then you can't do this.
Just to expand on Mark's answer:
protected int xMethod (Integer a, Integer b) {
switch ( a <=> b ) {
case -1: 1; break
case 1: 2; break
case 0: 3; break
}
}
However, you have to question whether this method has any value. If the caller can be changed to accept -1, 0, 1 then the method has no reason to exist.
How about:
return (a <=> b) + 2
If you remove the two occurrences of Integer from the signature, you can call the method with any parameters for which < is defined.
E.g.
assert x.xMethod(1, 2)==1
assert x.xMethod("2", "1")==2
assert x.xMethod(2.0, 2.0)==3

Resources