Groovy: Compare float values and find out greater value - groovy

I have a float value and a list of float values where I want to compare the float value with list and find out the greater value than the float value and greater than the whole number of the float value with the list.
Eg:
cv = 1.5
av = [1.1,1.5,1.7,1.9,1.11,2.1,2.5]
Current code :
versions = av.findAll {
def isVersionGreater
it.indexed().any { i, v ->
if (cv[i] == v) return false
isVersionGreater = v > (cv[i] ?: 0)
return true
}
return isVersionGreater
}
versions.removeAll { it[0] > cv[0] }
versions.collect { it.join('.') }
which prints [1.7,1.9,1.11], but I don't want the value with 1, I want to compare and find out only [2.1,2.5] not the other values.
Note: I am collecting the variables av and cv as below
av = output2.tokenize().collect { it.tokenize('.').collect { it as int } }
cv = output.tokenize().collect { it.tokenize('.').collect { it as int } }.first()
Could someone help me to achieve this using groovy?

Use <= instead of >:
versions.removeAll { it[0] <= cv[0] }
print versions.collect { it.join('.') }
It means remove all from it where its first value is less or equal to first value of cv.
Output:
[2.1, 2.5]

Related

Return two numbers in Q Sharp (Q#) (Quantum Development Kit)

So, basically, I did the tutorial to create a random number on the website of Microsoft Azure and now I am trying to add some functionalities, including their suggestion add a minimum number.
The initial code to generate just one number, max, is:
operation SampleRandomNumberInRange(max : Int) : Int {
// mutable means variables that can change during computation
mutable output = 0;
// repeat loop to generate random numbers until it generates one that is less or equal to max
repeat {
mutable bits = new Result[0];
for idxBit in 1..BitSizeI(max) {
set bits += [GenerateRandomBit()];
}
// ResultArrayAsInt is from Microsoft.Quantum.Convert library, converts string to positive integer
set output = ResultArrayAsInt(bits);
} until (output <= max);
return output;
}
#EntryPoint()
operation SampleRandomNumber() : Int {
// let declares var which don't change during computation
let max = 50;
Message($"Sampling a random number between 0 and {max}: ");
return SampleRandomNumberInRange(max);
}
Everything works well. Now, I want to generate two numbers so I would like to create a function TwoSampleRandomNumbersInRange but I can't figure out how to make the function return a result such as "Int, Int", I tried a few things including the follow:
operation TwoSampleRandomNumbersInRange(min: Int, max : Int) : Int {
// mutable means variables that can change during computation
mutable output = 0;
// repeat loop to generate random numbers until it generates one that is less or equal to max
repeat {
mutable bits = new Result[0];
for idxBit in 1..BitSizeI(max) {
set bits += [GenerateRandomBit()];
}
for idxBit in 1..BitSizeI(min) {
set bits += [GenerateRandomBit()];
}
// ResultArrayAsInt is from Microsoft.Quantum.Convert library, converts string to positive integer
set output = ResultArrayAsInt(bits);
} until (output >= min and output <= max);
return output;
}
To generate two numbers, I tried this:
operation TwoSampleRandomNumbersInRange(min: Int, max : Int) : Int, Int {
//code here
}
...but the syntax for the output isn't right.
I also need the output:
set output = ResultArrayAsInt(bits);
to have two numbers but ResultArrayAsInt, as the name says, just returns an Int. I need to return two integers.
Any help appreciated, thanks!
The return of an operation has to be a data type, in this case to represent a pair of integers you need a tuple of integers: (Int, Int).
So the signature of your operation and the return statement will be
operation TwoSampleRandomNumbersInRange(min: Int, max : Int) : (Int, Int) {
// code here
return (integer1, integer2);
}
I found the answer to my own question, all I had to do was:
operation SampleRandomNumberInRange(min: Int, max : Int) : Int {
// mutable means variables that can change during computation
mutable output = 0;
// repeat loop to generate random numbers until it generates one that is less or equal to max
repeat {
mutable bits = new Result[0];
for idxBit in 1..BitSizeI(max) {
set bits += [GenerateRandomBit()];
}
// ResultArrayAsInt is from Microsoft.Quantum.Convert library, converts string to positive integer
set output = ResultArrayAsInt(bits);
} until (output >= min and output <= max);
return output;
}
#EntryPoint()
operation SampleRandomNumber() : Int {
// let declares var which don't change during computation
let max = 50;
let min = 10;
Message($"Sampling a random number between {min} and {max}: ");
return SampleRandomNumberInRange(min, max);
}
}

Breakdown of Drug's Dosage weight (mg) to tablets

I am writing a piece of code in c# to retreive number of tablets for a given dosage. For example, if a Dosage is 20 mg of DrugA (if DrugA comes in 10mg, 5mg and 2mg tablets) then the code would return (2). If Dosage is 15 then the code would return (1 & 1). If a dosage is 3 then Invalid Dosage message is returned. The code must use the highest denominations first i.e. 10mg tablets and then 5mg tablets for the remainder and so on. I am using recursive function (GetDispenseBreakdownForSingleDosage) to acheive the above functionality. My code is working fine for most of the scenarios that I tested. The one scenario that it is incorrectly returning Invalid Dosage is for 8mg dosage. The code should return (4) since 2mg tablets is a valid option. I have given my code below. My questions are:
1) Is there a better way of acheiving my objective than using my code.
2) What changes should I make to avoid the trap of 8mg as invalid dosage. It is returning it invalid because code divides 8 with 5 during second recursive call and remainder becomes 3, on third recursive call 3 is not divisible by 2 so code returns invalid dosage.
My code is given below:
public string GetDispenseBreakdown(PrescriptionsBLL Prescription, double[] IndexAndNonIndexDosageForBreakdown)
{
int[] NoOfTablets = new int[Prescription.SelectedDrug.PrescriptionsDrugWeights.Count];
for (int Index = 1; Index <= IndexAndNonIndexDosageForBreakdown.Length; Index++)
{
GetDispenseBreakdownForSingleDosage(Prescription, ref NoOfTablets, IndexAndNonIndexDosageForBreakdown[(Index - 1)], Prescription.SelectedDrug.PrescriptionsDrugWeights[0].Weight, 1);//assuming that index 0 will always contain the highest weight i.e. if a drug has 2, 5, 10 as drug weights then index 0 should always contain 10 as we are sorting by Desc
}
return ConvertNumberOfTabletsIntoString(NoOfTablets);
}
public void GetDispenseBreakdownForSingleDosage(PrescriptionsBLL Prescription, ref int[] NoOfTablets, double Dosage, double Weight, int WeightCount)
{
int LoopIteration;
string TempLoopIteration = (Dosage / Weight).ToString();
if (TempLoopIteration.Contains("."))
LoopIteration = (int)Math.Floor(Dosage / Weight);
else
LoopIteration = int.Parse(TempLoopIteration);
double TempDosage = Weight * LoopIteration;
int WeightTablets = LoopIteration;
double RemainingDosage = Math.Round((Dosage - TempDosage), 2);
NoOfTablets[(WeightCount - 1)] = NoOfTablets[(WeightCount - 1)] + WeightTablets;
if (WeightCount == Prescription.SelectedDrug.PrescriptionsDrugWeights.Count && RemainingDosage > 0.0)
{
NoOfTablets[0] = -99999;//Invalid Dosage
return;
}
if (LoopIteration == 0 && Dosage > 0.0 && WeightCount == Prescription.SelectedDrug.PrescriptionsDrugWeights.Count)
{
NoOfTablets[0] = -99999;//Invalid Dosage
return;
}
if (WeightCount == Prescription.SelectedDrug.PrescriptionsDrugWeights.Count)
return;
GetDispenseBreakdownForSingleDosage(Prescription, ref NoOfTablets, RemainingDosage, Prescription.SelectedDrug.PrescriptionsDrugWeights[WeightCount].Weight, ++WeightCount);
}
public bool IsDosageValid(int[] NoOfTablets)
{
if (NoOfTablets[0] == -99999)
return false;
else
return true;
}
public string ConvertNumberOfTabletsIntoString(int[] NoOfTablets)
{
if (!IsDosageValid(NoOfTablets))
return "Dosage is Invalid";
string DispenseBreakDown = "(";
int ItemsAdded = 0;
for (int Count = 0; Count < NoOfTablets.Length; Count++)
{
if (NoOfTablets[Count] != 0)
{
if (ItemsAdded > 0)
DispenseBreakDown += " & " + NoOfTablets[Count];
else
DispenseBreakDown += NoOfTablets[Count];
ItemsAdded = ItemsAdded + 1;
}
}
DispenseBreakDown += ")";
return DispenseBreakDown;
}
This sounds like a version of the same logic required for coin change.
This site goes through that logic:
http://www.geeksforgeeks.org/dynamic-programming-set-7-coin-change/
You will also need to make a few adjustments:
You'll need to get back the possible results and accept the one that has highest number of larger pills.
You'll need to handle the possibility of no "correct change".
Here is a simple recursive method. Pass it the desired dosage and an empty list:
// Test if 2 floats are "equal", the difference between them
// is less than some predefined value (epsilon)
bool floatIsEqual(float f1, float f2)
{
float epsilon = 0.001f;
return Math.Abs(f1 - f2) <= epsilon;
}
static bool CalcDose(float desired, List<float> list)
{
// Order of array is important. Larger values will be attempted first
float[] sizes = new float[] { 8, 2, .4f, .2f };
// This path isn't working, return
if (desired < sizes[sizes.Length - 1])
{
return false;
}
// Try all combos
for (int i = 0; i < sizes.Length; i++)
{
if (floatIsEqual(desired, sizes[i]))
{
// Final step: perfect match
list.Add(sizes[i]);
return true;
}
if (sizes[i] <= desired)
{
// Attempt recursive call
if (true == CalcDose( desired - sizes[i], list))
{
// Success
list.Add(sizes[i]);
return true;
}
else break;
}
}
return false;
}

Method to convert binary number to decimal

I tried to write a program that converts a binary number to a decimal but am getting a number of errors and I cannot figure out where I am going wrong.
// Takes exponent from the user and calculates 2 ** exponent
int power2(int exponent) {
result = 2 ** exponent
return result
}
// Converts binary number to decimal
int binary2decimal(String binary) {
result = 0
count = 0
for (i = binary.length(); i-- > 0;) {
int d = Integer.parseInt(binary.charAt(i))
if (d == 1) {
result = result + power2(count)
}
count ++
}
return result
}
binary2decimal("101110")
Change
int d = Integer.parseInt(binary.charAt(i))
to
int d = Integer.parseInt("${binary[i]}")
and it will work.
An alternative implementation to yours is:
int binary2decimal2(String binary) {
binary.reverse()
.toList()
.indexed()
.collect { Integer idx, String val -> Integer.parseInt(val) * (2 ** idx)}.sum()
}
Assuming you want the shortest route to a clean solution, use:
Integer.parseInt(String base2num, int radix), where radix = 2.
See http://docs.oracle.com/javase/7/docs/api/java/lang/Integer.html#parseInt(java.lang.String,%20int)

Check if a string is a shuffle of two other given strings

This is a question from The Algorithm Design Manual:
Suppose you are given three strings of characters: X, Y, and Z, where |X| = n,
|Y| = m, and |Z| = n+m. Z is said to be a shuffle of X and Y if and only if Z can be formed by interleaving the characters from X and Y in a way that maintains the left-to ­right ordering of the characters from each string.
Give an efficient dynamic ­programming algorithm that determines whether Z is a shuffle of X and Y.
Hint: the values of the dynamic programming matrix you construct should be Boolean, not numeric
This is what I tried:
Initially, I made a 1-D char array and pointers to the starting characters of X,Y,Z respectively. If Z-pointer with matches X-pointer store X in the char array else check the same with Y-pointer.If each entry in the char array is not different from its last entry, Z is not interleaved.
Can someone help me with this problem?
First, let's start with some definitions. I write X[i] for the ith element of X and X[i) for the substring of X starting at index i.
For example, if X = abcde, then X[2] = c and X[2) = cde.
Similar definitions hold for Y and Z.
To solve the problem by dynamic programming, you should keep a 2D boolean array A of size (n+1) x (m+1). In this array, A[i, j] = true if and only if X[i) and Y[j) can be interleaved to form Z[i+j).
For an arbitrary (i, j), somewhere in the middle of the 2D array, the recurrence relation is very simple:
A[i, j] := X[i] = Z[i+j] and A[i+1, j]
or Y[j] = Z[i+j] and A[i, j+1]
On the edges of the 2D array you have the case that either X or Y is already at its end, which means the suffix of the other should be equal to the suffix of Z:
A[m, j] := Y[j) = Z[m+j)
A[i, n] := X[i) = Z[i+n)
A[m, n] := true
If you first fill the border of the array (A[m, j] and A[i, n], for all i, j), you can then simply loop back towards A[0, 0] and set the entries appropriately. In the end A[0, 0] is your answer.
Following approach should give you an idea.
Define the condition d(s1,s2,s3) = (s1 + s2 == s3) { s3 is a shuffle of s1 and s2 }
We have to find d( X, Y, Z ).
if lengths of s1 and s2 are 1 each and length of s3 = 2,
d( s1,s2,s3 ) = { (s1[0] == s3[0] && s2[0] == s3[1]) || (s1[0] == s3[1] && s2[0] == s3[0])
Similarly d can be obtained for empty strings.
For strings of arbitrary length, following relation holds.
d( s1,s2,s3 ) = { ( d( s1-s1[last],s2,s3 - s3[last]) && s1[last] == s3[last] )
|| ( d( s1,s2 - s2[last],s3 - s3[last]) && s2[last] == s3[last] )
}
You can compute the d() entries starting from zero length strings and keep checking.
It is defined by following recurrence relation:-
S(i,j,k) = false
if(Z(i)==Y(k))
S(i,j,k) = S(i,j,k)||S(i+1,j,k+1)
if(Z(i)==X(j))
S(i,j,k) = S(i,j,k)||S(i+1,j+1,k)
Where S(i,j,k) corresponds to Z[i to end] formed by shuffle of X[j to end] and Y[K to end]
You should try to code this into DP on your own.
I think this is quite easy if you are solving this problem by using this approach with java
Java Based Solution
public class ValidShuffle {
public static void main(String[] args) {
String s1 = "XY";
String s2 = "12";
String results = "Y21XX";
validShuffle(s1, s2, results);
}
private static void validShuffle(String s1, String s2, String result) {
String s3 = s1 + s2;
StringBuffer s = new StringBuffer(s3);
boolean flag = false;
char[] ch = result.toCharArray();
if (s.length() != result.length()) {
flag = false;
} else {
for (int i = 0; i < ch.length; i++) {
String temp = Character.toString(ch[i]);
if (s3.contains(temp)) {
s = s.deleteCharAt(s.indexOf(temp));
s3 = new String(s);
flag = true;
} else {
flag = false;
break;
}
}
}
if (flag) {
System.out.println("Yes");
} else {
System.out.println("No");
}
}
}
If any problem in my code then comment me please. thank you
function checkShuffle(str1, str2, str3) {
var merge=str1+str2;
var charArr1= merge.split("").sort();
var charArr2= str3.split("").sort();
for(i=0;i<str3.length;i++){
if(charArr1[i] == charArr2[i]){
return true;
}
}
return false;
}
checkShuffle("abc", "def", "dfabce"); //output is true
JAVASCRIPT BASED SOLUTION
const first = "bac";
const second = "def"
const third = "dabecf";
function createDict(seq,str){
let strObj = {};
str = str.split("");
str.forEach((letter,index)=>{
strObj[letter] = {
wordSeq: seq,
index : index
} ;
})
return strObj;
}
function checkShuffleValidity(thirdWord,firstWord,secondWord){
let firstWordDict = createDict('first',firstWord);
let secondWordDict = createDict('second',secondWord);
let wordDict = {...firstWordDict,...secondWordDict};
let firstCount=0,secondCount = 0;
thirdWord = thirdWord.split("");
for(let i=0; i<thirdWord.length; i++){
let letter = thirdWord[i];
if(wordDict[letter].wordSeq == "first"){
if(wordDict[letter].index === firstCount){
firstCount++;
}else{
return false
}
}else{
if(wordDict[letter].index === secondCount){
secondCount++;
}else{
return false;
}
}
}
return true;
}
console.log(checkShuffleValidity(third,first,second));
Key points:
All strings shouldn't be null or empty.
The sum of the 2 strings length should be equal to the third string.
The third string should not contain the substrings of the 2 strings.
Else create arrays of characters , sort and compare.
Code:
public static boolean validShuffle(String first, String second, String third){
boolean status=false;
if((first==null || second==null || third==null) || (first.isEmpty()|| second.isEmpty() || third.isEmpty())){
status = false;
} else if((first.length()+second.length()) !=third.length()){
//check if the sum of 2 lengths equals to the third string length
status = false;
} else if(third.indexOf(first,0)!=-1 || third.indexOf(second,0)!=-1){
//check if the third string contains substrings
status = false;
} else {
char [] c1_2=(first+second).toCharArray();
char [] c3 =third.toCharArray();
Arrays.sort(c1_2);
Arrays.sort(c3);
status=Arrays.equals(c1_2, c3);
}
return status;
}

C# IsBetween String Logic

Looking for either a solution, some ideas or being point in the right direction on how to resolve a problem.
Basically, I have to figure out if a string value is in between a Low and High string value. However, the values are in a format which String.Compare will not work. But, a human can easily figure out.
For example, one of my ranges is Low: A7, High A12. A8 fits in between those values but String.Compare says it does not. A13 would not fit between the values.
Other examples of Low and High values are:
Low Value - High Value
1A1 - 1A12
25W00 - 25W050
42W1 - 42W296
W232N0002 - W232N000598
In the above examples 1A2 would fit between the Low High Value of 1A1 and 1A12, but 1A100 would not.
Any ideas on how to resolve this? I know this had to have been encountered before.
This could use some optimization, but it's a proof of concept.
Just convert the letters to numerical values and compare the results:
private bool ValueIsBetween(string value, string lowValue, string highValue)
{
long low = long.Parse(ConvertToNumber(lowValue));
long high = long.Parse(ConvertToNumber(highValue));
long val = long.Parse(ConvertToNumber(value));
return val > low && val < high;
}
private string ConvertToNumber(string value)
{
value = value.ToUpper();
value = value.Replace("A", "0");
value = value.Replace("B", "1");
value = value.Replace("C", "2");
value = value.Replace("D", "3");
value = value.Replace("E", "4");
value = value.Replace("F", "5");
value = value.Replace("G", "6");
value = value.Replace("H", "7");
value = value.Replace("I", "8");
value = value.Replace("J", "9");
value = value.Replace("K", "10");
value = value.Replace("L", "11");
value = value.Replace("M", "12");
value = value.Replace("N", "13");
value = value.Replace("O", "14");
value = value.Replace("P", "15");
value = value.Replace("Q", "16");
value = value.Replace("R", "17");
value = value.Replace("S", "18");
value = value.Replace("T", "19");
value = value.Replace("U", "20");
value = value.Replace("V", "21");
value = value.Replace("W", "22");
value = value.Replace("X", "23");
value = value.Replace("Y", "24");
value = value.Replace("Z", "25");
return value;
}
Results:
ValueIsBetween("1A2", "1A1", "1A12");
true
ValueIsBetween("1A100", "1A1", "1A12");
false
ValueIsBetween("43W4", "42W1", "44W3");
true
Edit:
Try this improved algorithm instead:
private bool ValueIsBetween(string value, string lowValue, string highValue)
{
return !ValueIsLessThan(value, lowValue) && ValueIsLessThan(value, highValue);
}
private bool ValueIsLessThan(string value, string compareTo)
{
var matches = Regex.Matches(value, "[0-9]+|[a-zA-Z]+");
var matchesB = Regex.Matches(compareTo, "[0-9]+|[a-zA-Z]+");
var count = matches.Count < matchesB.Count ? matches.Count : matchesB.Count;
for (int i = 0; i < count; i++)
{
long val;
long val2;
if (long.TryParse(matches[i].Value, out val))
{
if (long.TryParse(matchesB[i].Value, out val2))
{
if (val > val2) return false;
if (val < val2) return true;
}
else
{
return false;
}
}
else
{
if (matches[i].Value.CompareTo(matchesB[i].Value) > 0 ) return false;
if (matches[i].Value.CompareTo(matchesB[i].Value) < 0 ) return true;
}
}
return true;
}
Results:
ValueIsBetween("B431Z543", "A0", "Z9");
true
ValueIsBetween("4B31Z543", "A0", "Z9");
false
ValueIsBetween("1A2", "1A1", "1A12");
true
ValueIsBetween("1A100", "1A1", "1A12");
false
ValueIsBetween("43W4", "42W1", "44W3");
true
ValueIsBetween("W5", "CC4", "CC6");
false
ValueIsBetween("W8B4", "W5C3", "W7C3");
false
ValueIsBetween("W5C4", "W5C3", "C7W3");
false
Build a class, probably abstract, with sub classes for each pattern.
The pattern for "25W00" could be ^(?<LEFTTHING>.{2})(?<MIDDLETHING>.{1})(?<RIGHTTHING>.{2})$
In your class, capture each Regex group as a string or numeric as appropriate.
I suppose you could come up with some conventions so you might even be able to have a single Type - and pass in that pattern to the constructor.
You may even have some kind of really smart class where you pass in two strings and a common pattern. This super class builds appropriate "comparable" classes (as per above) and returns a boolean result of the comparison. Your client code would be very clean in this case.
Assuming the non-numeric parts are fixed (i.e. you aren't searching for 1B1 being between 1A1 and 1C1), you could use a regex to expand the numerical values to a certain fixed width, so you could then compare the strings.
For example, using
static Regex digits = new Regex(#"\d+");
static string ExpandDigits(string s)
{
return digits.Replace(s, m => string.Format("{0:D10}", int.Parse(m.ToString())));
}
then calling ExpandDigits("W232N0002") yields W0000000232N0000000002.
You could have a comparison method like this:
static bool IsInRange(string lower, string upper, string test)
{
test = ExpandDigits(test);
lower = ExpandDigits(lower);
if (lower.CompareTo(test) <= 0)
{
upper = ExpandDigits(upper);
if (test.CompareTo(upper) <= 0)
{
return true;
}
}
return false;
}

Resources