Guidance: converting parallelly increamental nested loop to streams - groovy

I am trying to convert the following loop to Java stream.
def a = [12,34,5,64,24,56], b = [1,23,45]
for(int i=0;i<a.size();)
for(int j=0;j<b.size() && a[i];j++)
println a[i++]+","+b[j]
Output:
12,1
34,23
5,45
64,1
24,23
56,45
I tried few ways but I am not sure how to increment outer loop from inner loop. Any guidance is appreciated. The following code is the furthest I have done.
a.stream().forEach({x ->
b.stream().filter({y-> y%2 != 0}).forEach({ y->
println x+","+y
});
});
Output:
12,1
12,23
12,45
34,1
34,23
34,45
5,1
5,23
5,45
64,1
64,23
64,45
24,1
24,23
24,45
56,1
56,23
56,45

IntStream.range(0, left.length)
.mapToObj(x -> left[x] + " " + right[x % right.length])
.forEachOrdered(System.out::println);
where left is a and right is b

Related

Function doesn't execute inside loop

I'm making a simple terminal calculator but for some reason a function isn't executing inside a while loop but executes outside the loop.
Given this input: ((1 + 2) + (3 + 4))
It should output:10
But gets stuck in an infinite loop because it doesn't replace the innermost expressions with their result.
The function that doesn't execute is s.replace(basicOp, answer);
Here is a snippet of the problem:
public static function processInput(s:String):String
{
var result:Null<Float> = parseNumber(s);
if (result != null)
{
return Std.string(result);
}
var closeParPos:Int = 0;
var openParPos:Int = 0;
var basicOp:String;
var answer:String = "";
// ERROR HERE
while (Std.string(answer) != s)
{
closeParPos = s.indexOf(")");
openParPos = s.lastIndexOf("(", closeParPos);
basicOp = s.substring(openParPos, closeParPos + 1);
answer = processBasicOp(basicOp);
// This isn't executed
s.replace(basicOp, answer);
trace("Input: " + s + " basicOp: " + basicOp + " Answer: " + answer);
}
return (result == null)? "": Std.string(result);
}
All the code is here just run make test
The input syntax is: ([number] [operator] [number]) or ([operator] [number])
There must be a single space between number and operators.
There shouldn't be any space between numbers and parenthesis
Supported operations:
+ - / *
% (remainder),
div (quotient),
sqr (square),
sqroot (square root),
sin cos tan (in degrees, bugged)
fact (factorial)
It isn't completed yet, there may be other problems, but this problem prevents me from advancing.
Can someone help me find the solution?
Thank you.
I can't actually get this to run, but StringTools.replace() doesn't modify the string in-place.
Try changing s.replace(basicOp, answer); to s = s.replace(basicOp, answer);

Return to menu language GO

I have a menu option with two options: add and substract. When I choose one it runs ok but the program closes. I would like to know how to make it go back to the menu after an operation ends to select another one
package main
import (
"fmt"
)
func main() {
var n1, n2, s, r float64
var op, ns int
fmt.Println("\n\tWelcome")
fmt.Println("Chose an option")
fmt.Println("1.-Add")
fmt.Println("2.-Substract")
fmt.Scan(&op)
if op == 1 {
fmt.Printf("\n\tAdd")
fmt.Printf("\nHow many numbers you add? ")
fmt.Scan(&ns)
if ns <= 1 {
fmt.Print("You can not add just a number")
} else {
for i := 0; i < ns; i++ {
fmt.Printf("\nType the number %d: ", i+1)
fmt.Scan(&n1)
s += n1
}
fmt.Println("\nThe sum is: ", s)
//How to return to the menu?
}
} else if op == 2 {
fmt.Printf("\n\tSubtraction")
fmt.Printf("\nType the first number: ")
fmt.Scan(&n1)
fmt.Printf("\nType the second number: ")
fmt.Scan(&n2)
r = n1 - n2
fmt.Println("\nSubstraction is: ", r)
}
}
Just wrap the whole thing in
for {
}
Use break to exit the loop or continue to go back to the top.
It's hard to tell exactly without seeing your code, but I may assume you should use operator for ;; {} and put inside your menu with the appropriate if/else statements.

Finding minimum moves required for making 2 strings equal

This is a question from one of the online coding challenge (which has completed).
I just need some logic for this as to how to approach.
Problem Statement:
We have two strings A and B with the same super set of characters. We need to change these strings to obtain two equal strings. In each move we can perform one of the following operations:
1. swap two consecutive characters of a string
2. swap the first and the last characters of a string
A move can be performed on either string.
What is the minimum number of moves that we need in order to obtain two equal strings?
Input Format and Constraints:
The first and the second line of the input contains two strings A and B. It is guaranteed that the superset their characters are equal.
1 <= length(A) = length(B) <= 2000
All the input characters are between 'a' and 'z'
Output Format:
Print the minimum number of moves to the only line of the output
Sample input:
aab
baa
Sample output:
1
Explanation:
Swap the first and last character of the string aab to convert it to baa. The two strings are now equal.
EDIT : Here is my first try, but I'm getting wrong output. Can someone guide me what is wrong in my approach.
int minStringMoves(char* a, char* b) {
int length, pos, i, j, moves=0;
char *ptr;
length = strlen(a);
for(i=0;i<length;i++) {
// Find the first occurrence of b[i] in a
ptr = strchr(a,b[i]);
pos = ptr - a;
// If its the last element, swap with the first
if(i==0 && pos == length-1) {
swap(&a[0], &a[length-1]);
moves++;
}
// Else swap from current index till pos
else {
for(j=pos;j>i;j--) {
swap(&a[j],&a[j-1]);
moves++;
}
}
// If equal, break
if(strcmp(a,b) == 0)
break;
}
return moves;
}
Take a look at this example:
aaaaaaaaab
abaaaaaaaa
Your solution: 8
aaaaaaaaab -> aaaaaaaaba -> aaaaaaabaa -> aaaaaabaaa -> aaaaabaaaa ->
aaaabaaaaa -> aaabaaaaaa -> aabaaaaaaa -> abaaaaaaaa
Proper solution: 2
aaaaaaaaab -> baaaaaaaaa -> abaaaaaaaa
You should check if swapping in the other direction would give you better result.
But sometimes you will also ruin the previous part of the string. eg:
caaaaaaaab
cbaaaaaaaa
caaaaaaaab -> baaaaaaaac -> abaaaaaaac
You need another swap here to put back the 'c' to the first place.
The proper algorithm is probably even more complex, but you can see now what's wrong in your solution.
The A* algorithm might work for this problem.
The initial node will be the original string.
The goal node will be the target string.
Each child of a node will be all possible transformations of that string.
The current cost g(x) is simply the number of transformations thus far.
The heuristic h(x) is half the number of characters in the wrong position.
Since h(x) is admissible (because a single transformation can't put more than 2 characters in their correct positions), the path to the target string will give the least number of transformations possible.
However, an elementary implementation will likely be too slow. Calculating all possible transformations of a string would be rather expensive.
Note that there's a lot of similarity between a node's siblings (its parent's children) and its children. So you may be able to just calculate all transformations of the original string and, from there, simply copy and recalculate data involving changed characters.
You can use dynamic programming. Go over all swap possibilities while storing all the intermediate results along with the minimal number of steps that took you to get there. Actually, you are going to calculate the minimum number of steps for every possible target string that can be obtained by applying given rules for a number times. Once you calculate it all, you can print the minimum number of steps, which is needed to take you to the target string. Here's the sample code in JavaScript, and its usage for "aab" and "baa" examples:
function swap(str, i, j) {
var s = str.split("");
s[i] = str[j];
s[j] = str[i];
return s.join("");
}
function calcMinimumSteps(current, stepsCount)
{
if (typeof(memory[current]) !== "undefined") {
if (memory[current] > stepsCount) {
memory[current] = stepsCount;
} else if (memory[current] < stepsCount) {
stepsCount = memory[current];
}
} else {
memory[current] = stepsCount;
calcMinimumSteps(swap(current, 0, current.length-1), stepsCount+1);
for (var i = 0; i < current.length - 1; ++i) {
calcMinimumSteps(swap(current, i, i + 1), stepsCount+1);
}
}
}
var memory = {};
calcMinimumSteps("aab", 0);
alert("Minimum steps count: " + memory["baa"]);
Here is the ruby logic for this problem, copy this code in to rb file and execute.
str1 = "education" #Sample first string
str2 = "cnatdeiou" #Sample second string
moves_count = 0
no_swap = 0
count = str1.length - 1
def ends_swap(str1,str2)
str2 = swap_strings(str2,str2.length-1,0)
return str2
end
def swap_strings(str2,cp,np)
current_string = str2[cp]
new_string = str2[np]
str2[cp] = new_string
str2[np] = current_string
return str2
end
def consecutive_swap(str,current_position, target_position)
counter=0
diff = current_position > target_position ? -1 : 1
while current_position!=target_position
new_position = current_position + diff
str = swap_strings(str,current_position,new_position)
# p "-------"
# p "CP: #{current_position} NP: #{new_position} TP: #{target_position} String: #{str}"
current_position+=diff
counter+=1
end
return counter,str
end
while(str1 != str2 && count!=0)
counter = 1
if str1[-1]==str2[0]
# p "cross match"
str2 = ends_swap(str1,str2)
else
# p "No match for #{str2}-- Count: #{count}, TC: #{str1[count]}, CP: #{str2.index(str1[count])}"
str = str2[0..count]
cp = str.rindex(str1[count])
tp = count
counter, str2 = consecutive_swap(str2,cp,tp)
count-=1
end
moves_count+=counter
# p "Step: #{moves_count}"
# p str2
end
p "Total moves: #{moves_count}"
Please feel free to suggest any improvements in this code.
Try this code. Hope this will help you.
public class TwoStringIdentical {
static int lcs(String str1, String str2, int m, int n) {
int L[][] = new int[m + 1][n + 1];
int i, j;
for (i = 0; i <= m; i++) {
for (j = 0; j <= n; j++) {
if (i == 0 || j == 0)
L[i][j] = 0;
else if (str1.charAt(i - 1) == str2.charAt(j - 1))
L[i][j] = L[i - 1][j - 1] + 1;
else
L[i][j] = Math.max(L[i - 1][j], L[i][j - 1]);
}
}
return L[m][n];
}
static void printMinTransformation(String str1, String str2) {
int m = str1.length();
int n = str2.length();
int len = lcs(str1, str2, m, n);
System.out.println((m - len)+(n - len));
}
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
String str1 = scan.nextLine();
String str2 = scan.nextLine();
printMinTransformation("asdfg", "sdfg");
}
}

Node.js variables being changed without any operations performed on them

I am using a node.js server for a multiplayer synchronized dice, but i am having some strange problems with variables changing that are not referenced or used...
var origonalRolls = rolls;
//identify epic fails
var epicFails = [];
for(var r = 0; r < rolls.length; r++)
if(rolls[r] === 1)
epicFails.push(r);
console.log("TEST 1 :: " + JSON.stringify(rolls));
console.log("TEST 2 :: " + JSON.stringify(origonalRolls));
//remove epic fails and the corresponding heighest
if(epicFails.length > 0){
for(var i = epicFails.length-1; i >= 0; i--){
rolls.splice(epicFails[i], 1);
if(rolls[rolls.length-1] >= success)
rolls.splice(rolls.length-1, 1);
}
}
console.log("TEST 3 :: " + JSON.stringify(rolls));
console.log("TEST 4 :: " + JSON.stringify(origonalRolls));
the above should find any element in the rolls array which is 1 and then add it to epicFails. it should then remove it from rolls as well as the heighest remaining roll. (note, rolls is sorted numerically)
for some reason the output of this segment of code is as follows:
TEST 1 :: [1,1,2,3,3,6,7,7,9,9]
TEST 2 :: [1,1,2,3,3,6,7,7,9,9]
TEST 3 :: [2,3,3,6,7,7]
TEST 4 :: [2,3,3,6,7,7]
I am unsure why rolls and origonalRolls start the same and end the same. I am only using rolls.
Any help and/or explanation to this problem is welcome, it's been troubling me for a long time now...
In Javascript Arrays and Objects are only shallow copied - which means that an array (rolls) copied from another array (originalRolls) is only a reference to originalRolls - it is not an entirely new array, and modifying values in one will affect values in the other.
You will need to implement a deep copy function to create an entirely new array based off another. There are numerous imlementations of deep copying arrays/objects both here and elsewhere on the net - here is one of them from a quick Google.
Replace var origonalRolls = rolls; with:
var origonalRolls = [];
for (var i = 0, len = rolls.length; i < len; i++) {
origonalRolls[i] = rolls[i];
}

Groovy for loop with multiple counters?

Following works in groovy -
for(def i=0;i<10;i++)
print i
But this which is valid in Java, C++ does not work in groovy -
for(def i=0,j=0;i<10;i++,j++)
print i + ' ' + j
Why? How to make this work?
It will not working as Groovy does not accept multiple expressions in a for loop.
Try this:
[0..10,0..10].transpose().each{ i, j ->
println i + ' ' + j
}
to achieve the same result.
Update to make it more generalized. This update is equivalent to increment with i++, j+=3.
(0..<10).collect{[it, it+3]}.each{ i, j ->
println i + ' ' + j
}
Have you tried this:
for( def ( int i, int j ) = [ 0, 0 ]; i < 10; i++, j++ )
If that doesn't work, it might be failing because of the last part.
C++ has a explicit comma operator, which is how it allows constructs like this.
Java does not have a comma operator, but presumably allows constructs such as this as a hack to the for loop.
If Groovy wont allow this, it's most probably because it doesn't allow this hack.

Resources