Repeat String in braces n times - java

I have an input String in the form "(x5(y8)2)4"
Let's say x and y are separate functions, I either want to call them 'n' times, or expand the brackets to create a new String that I can use to call the functions.
Example 1:
Input: (x5(y8)2)4
Output: x5y8y8x5y8y8x5y8y8x5y8y8
Example 2 (more complex):
Input: (((x1)3x2)4y5)2z5
Output: x1x1x1x2x1x1x1x2x1x1x1x2x1x1x1x2y5x1x1x1x2x1x1x1x2x1x1x1x2x1x1x1x2y5z5
Thanks

You could parse the tree to a tree-data-structure. Each node in the tree in the has a number of children nodes. A node could either be a leaf (which is a node without children) - so for example a variable x5 - or it could be a node (with children nodes) which represents a "mathematical" function.
The tree from your first example could look like this.
Root [NODE]:
child_of_root * 4
Child_of_Root [NODE]:
1_child_of_child_of_root + 2_child_of_child_of_root
1_Child_of_Child_of_Root [LEAF]:
x5
2_Child_of_Child_of_Root [NODE]:
child_of_2_child_of_child_of_root * 2
Child_of_2_Child_of_Child_of_Root [LEAF]:
y8
To parse your input-string to the tree-structure you have to analyse how the ( and ) are set and if you "multiply" those by a factor and if you add other stuff - (x5 "+" (y8) "*" 2). This could get quite complicated. (Maybe you could use stacks? However, I'm sure there are tutorials out there).
After you created your tree-representation of your input, it is relatively simple to calculate your output string. Create a recursive algorithm similar to this:
String getReult() {
if(this == NODE) {
return calculate(MY_NODE_CHILDREN.getResult());
}else if(this == LEAF) {
return VARIABLE;
}
}
This is pseudo-code!
The calculate function should add the children string results, multiply them by a factor or do nothing, depending on a context.
If you call your recursive function at the root, the correct result should pop out.

Related

Is it possible to run a recursive function in parallel?

I have a findAllPaths() function to find all possible paths in a graph (stored in matrix):
public void findAllPaths(final Matrix matrix, final Index s, final Index d, HashMap <Index , Boolean> isVisited, Collection localPathList)
{
// Mark the current node
isVisited.put(s, true);
if (s.equals(d)) {
this.pathsList.add(new ArrayList<>(localPathList));
// if match found no need to traverse more till depth
isVisited.put(s, false);
return;
}
// Recur for all the vertices neighbors to current index
for (Index i : matrix.getNeighbors(s)) {
if (!isVisited.get(i)) {
// store current node in path[]
localPathList.add(i);
findAllPaths(matrix, i, d, isVisited, localPathList);
// remove current node in path[]
localPathList.remove(i);
}
}
// Mark the current node
isVisited.put(s, false);
}
I'm trying to make it run in parallel as much as possible.
Does anybody have an idea of how I can accomplish that?
You might want to use RecursiveTask or RecursiveAction of the java.util.concurrent package and run it in a ForkjoinPool. The general idea of these classes is that you decide in your code what portion of the work should be done in one thread. If the work is bigger than that portion, fork a part of the work to a new thread. To get the results of all threads, use join(). These classes use a work stealing algorithm: when a thread is done, it can steal work of another thread, so this is highly efficient for heavy number crunching like this.
One prerequisite of RecursiveTask or RecursiveAction, is that you should be able to split the work in parts, and that you know how to combine the finished parts to the final result. The factorial of a big number is one example that can be calculated using RecursiveTask: 10! can be split in (1 * 2 * 3 * 4 * 5) and (6 * 7 * 8 * 9 * 10). Both sub-results can be multiplied for the final result.

Breadth-First Search Algorithm JAVA 8-puzzle

Im trying to implement the Breadth-First algorithm for 8 puzzle game. I know that it is not a new case and theres a bunch of solutions on web, but I want to make it on my way of thinking.
This code already finds the node result, which is
123
456
780
But it takes 350,000 steps to do it!
Any thoughts would be appreciated!
=)
//This method receives a Collection of `Nodo` objects, each one will be checked and compare with the finalGoal
public void percorreNodos(Collection<Nodo> nodosBase)
{
//In this class a have an array that has all the IDs os nodes that already has been checked
//The ID of a Node, is the representation: 123456780, 354126870 , etc..
System.out.println("idsPercorrido.size() = " + idsPercorridos.size());
//Check if the collection nodosBase contains the finalGoal
Iterator<Nodo> iterator = nodosBase.iterator();
while( iterator.hasNext() )
{
Nodo nodoBase = (Nodo) iterator.next();
//If this current node has already been checked, we dont have to check it again
idsPercorridos.add( nodoBase.getId() );
//Just print the node (sysout)
nodoBase.print();
contPassos++;
System.out.println( "\n" + contPassos + " STEPS(number of nodes checked)..." );
//Check if this node is the final goal
if( nodoBase.isObjetivoFinal() )
{
//set the variable indicating that the result has been found
encontrouObjetivo = true;
System.out.println( "Resultado alcancado EM " + contPassos + " PASSOS..." );
nodoBase.print();
break;
}
}
// Now that we know that no one Node of nosoBase collection is the final goal, we are going to generate the next children to be checked, and call this function recursively
//Just confirm that we didnt find the goal
if(encontrouObjetivo == false)
{
//Creates the next frontier
Collection<Nodo> novaFronteira = new HashSet<Nodo>();
for(Nodo nodoPai : nodosBase)
{
//Generate each Node its childrens and add to a collection called "novaFronteira"
Collection<Nodo> filhos = nodoPai.gerarFilhos();
for(Nodo filho : filhos)
{
//idsPercorridos is a collection<String> which contains all the nodes ids that we checked, we dont want to check a node more than one time !
if( idsPercorridos.contains( filho.getId() ) == false )
{
novaFronteira.add( filho );
}
}
}
this.percorreNodos( novaFronteira );
}
}
You could make sure you don't add duplicate elements to novaFronteira.
There's nothing preventing this code:
for(Nodo nodoPai : nodosBase)
{
Collection<Nodo> filhos = nodoPai.gerarFilhos();
for(Nodo filho : filhos)
{
if( idsPercorridos.contains( filho.getId() ) == false )
{
novaFronteira.add( filho );
}
}
}
From adding many duplicate nodes to novaFronteira.
If you were to add to idsPercorridos inside the if-statement, that would prevent this from happening, and result in less steps, although, depending on exactly what your data and data structures looks like, the added running time of this call may actually make it take longer than it did originally.
If the problem is running time, you should make sure that idsPercorridos is a TreeSet or HashSet, as these allow for efficient contains calls, as opposed to ArrayList or LinkedList, which don't.
If this doesn't help, you could try using the A* algorithm instead, which involves adding a heuristic function to each node, which is the distance to the target - this allows us to explore the nodes closer to the target first, often resulting in less steps to get there.
A good heuristic function might be the sum of Manhattan distances between each tile and its target location.
Note that this would involve quite a few changes to your current code.
According to Wikipedia there are 9!/2 = 181440 possible solvable combinations to this puzzle. If you check each node for each of these combinations (which you don't, but it makes the calculation easier), it makes about (9!/2) * 9 = 1,632,960 steps. Therefore, there I don't see an issue if it takes your algorithm 350,000 steps because a computer can do those steps really fast.

issues with iterative code in java

I want to convert the recursive function given below:
LinkedList i=a; //a contains the nodes which are adjacent to the last element of g
for(String i1: i )
{
if(g.contains(i1) || i1.equals("o"))
{ continue; }
g.addLast(i1);
func(g);
g.removeLast();
}
I want to convert the above program to an iterative one. Can someone help
LinkedList i=a; //a contains the nodes which are adjacent to the last element of g
for(String i1: i )
{
if(g.contains(i1) || i1.equals("o"))
{ continue; }
g.addLast(i1);
func(g);
g.removeLast();
}
So walking through this it appears as though the steps are as follows:
1) Check for existence of current String or if it equals "o"
2a) If yes continue
2b) else put current string at end of list.
3) repeat steps 1->2
4) remove the last element of the list
If I were to make the code as simple as possible given those steps it would look like so:
func(LinkedList ll)
{
Set set = new HashSet(ll); //removes all duplicates
if(set.contains("o") { set.remove("o") ;} //these are strings so that works
LinkedList newLL = new LinkedList(set); //order still retained
newLL.poll(); //remove last element
}
If I understand correctly your code, it finds all the available paths, right ?
The main 2 issues I see in your 2nd code are :
In the recursive version, you handle the path with currentNode by calling func, then remove currentNode. In the iterative version, you put visitedNodes in the stack "to be handled", and then alter visitedNodes before it was handled !
Related issue : you're always stacking over and over the same visitedNodes
So some solutions would be to put in the stack a copy of visitedNodes + the element currentNode.
visitedNodes will not be altered this way
I can do a bit of code if needed

Efficient algorithm to find all the paths from A to Z?

With a set of random inputs like this (20k lines):
A B
U Z
B A
A C
Z A
K Z
A Q
D A
U K
P U
U P
B Y
Y R
Y U
C R
R Q
A D
Q Z
Find all the paths from A to Z.
A - B - Y - R - Q - Z
A - B - Y - U - Z
A - C - R - Q - Z
A - Q - Z
A - B - Y - U - K - Z
A location cannot appear more than once in the path, hence A - B - Y - U - P - U - Z is not valid.
Locations are named AAA to ZZZ (presented here as A - Z for simplicity) and the input is random in such a way that there may or may not be a location ABC, all locations may be XXX (unlikely), or there may not be a possible path at all locations are "isolated".
Initially I'd thought that this is a variation of the unweighted shortest path problem, but I find it rather different and I'm not sure how does the algorithm there apply here.
My current solution goes like this:
Pre-process the list such that we have a hashmap which points a location (left), to a list of locations (right)
Create a hashmap to keep track of "visited locations". Create a list to store "found paths".
Store X (starting-location) to the "visited locations" hashmap.
Search for X in the first hashmap, (Location A will give us (B, C, Q) in O(1) time).
For-each found location (B, C, Q), check if it is the final destination (Z). If so store it in the "found paths" list. Else if it doesn't already exist in "visited locations" hashmap, Recurl to step 3 now with that location as "X". (actual code below)
With this current solution, it takes forever to map all (not shortest) possible routes from "BKI" to "SIN" for this provided data.
I was wondering if there's a more effective (time-wise) way of doing it. Does anyone know of a better algorithm to find all the paths from an arbitrary position A to an arbitrary position Z ?
Actual Code for current solution:
import java.util.*;
import java.io.*;
public class Test {
private static HashMap<String, List<String>> left_map_rights;
public static void main(String args[]) throws Exception {
left_map_rights = new HashMap<>();
BufferedReader r = new BufferedReader(new FileReader("routes.text"));
String line;
HashMap<String, Void> lines = new HashMap<>();
while ((line = r.readLine()) != null) {
if (lines.containsKey(line)) { // ensure no duplicate lines
continue;
}
lines.put(line, null);
int space_location = line.indexOf(' ');
String left = line.substring(0, space_location);
String right = line.substring(space_location + 1);
if(left.equals(right)){ // rejects entries whereby left = right
continue;
}
List<String> rights = left_map_rights.get(left);
if (rights == null) {
rights = new ArrayList<String>();
left_map_rights.put(left, rights);
}
rights.add(right);
}
r.close();
System.out.println("start");
List<List<String>> routes = GetAllRoutes("BKI", "SIN");
System.out.println("end");
for (List<String> route : routes) {
System.out.println(route);
}
}
public static List<List<String>> GetAllRoutes(String start, String end) {
List<List<String>> routes = new ArrayList<>();
List<String> rights = left_map_rights.get(start);
if (rights != null) {
for (String right : rights) {
List<String> route = new ArrayList<>();
route.add(start);
route.add(right);
Chain(routes, route, right, end);
}
}
return routes;
}
public static void Chain(List<List<String>> routes, List<String> route, String right_most_currently, String end) {
if (right_most_currently.equals(end)) {
routes.add(route);
return;
}
List<String> rights = left_map_rights.get(right_most_currently);
if (rights != null) {
for (String right : rights) {
if (!route.contains(right)) {
List<String> new_route = new ArrayList<String>(route);
new_route.add(right);
Chain(routes, new_route, right, end);
}
}
}
}
}
As I understand your question, Dijkstras algorithm cannot be applied as is, since shortest path problem per definition finds a single path in a set of all possible paths. Your task is to find all paths per-se.
Many optimizations on Dijkstras algorithm involve cutting off search trees with higher costs. You won't be able to cut off those parts in your search, as you need all findings.
And I assume you mean all paths excluding circles.
Algorithm:
Pump network into a 2dim array 26x26 of boolean/integer. fromTo[i,j].
Set a 1/true for an existing link.
Starting from the first node trace all following nodes (search links for 1/true).
Keep visited nodes in a some structure (array/list). Since maximal
depth seems to be 26, this should be possible via recursion.
And as #soulcheck has written below, you may think about cutting of paths you have aleady visted. You may keep a list of paths towards the destination in each element of the array. Adjust the breaking condition accordingly.
Break when
visiting the end node (store the result)
when visiting a node that has been visted before (circle)
visiting a node for which you have already found all paths to the destination and merge your current path with all the existing ones from that node.
Performance wise I'd vote against using hashmaps and lists and prefer static structures.
Hmm, while re-reading the question, I realized that the name of the nodes cannot be limited to A-Z. You are writing something about 20k lines, with 26 letters, a fully connected A-Z network would require far less links. Maybe you skip recursion and static structures :)
Ok, with valid names from AAA to ZZZ an array would become far too large. So you better create a dynamic structure for the network as well. Counter question: regarding performance, what is the best data structure for a less popuplate array as my algorithm would require? I' vote for an 2 dim ArrayList. Anyone?
What you're proposing is a scheme for DFS, only with backtracking.It's correct, unless you want to permit cyclic paths (you didn't specify if you do).
There are two gotchas, though.
You have to keep an eye on nodes you already visited on current path (to eliminate cycles)
You have to know how to select next node when backtracking, so that you don't descend on the same subtree in the graph when you already visited it on the current path.
The pseudocode is more or less as follows:
getPaths(A, current_path) :
if (A is destination node): return [current_path]
for B = next-not-visited-neighbor(A) :
if (not B already on current path)
result = result + getPaths(B, current_path + B)
return result
list_of_paths = getPaths(A, [A])
which is almost what you said.
Be careful though, as finding all paths in complete graph is pretty time and memory consuming.
edit
For clarification, the algorithm has Ω(n!) time complexity in worst case, as it has to list all paths from one vertex to another in complete graph of size n, and there are at least (n-2)! paths of form <A, permutations of all nodes except A and Z, Z>. No way to make it better if only listing the result would take as much.
Your data is essentially an adjacency list which allows you to construct a tree rooted at the node corresponding to A. In order to obtain all the paths between A & Z, you can run any tree traversal algorithm.
Of course, when you're building the tree you have to ensure that you don't introduce cycles.
I would proceed recursively where I would build a list of all possible paths between all pairs of nodes.
I would start by building, for all pairs (X, Y), the list L_2(X, Y) which is the list of paths of length 2 that go from X to Y; that's trivial to build since that's the input list you are given.
Then I would build the lists L_3(X, Y), recursively, using the known lists L_2(X, Z) and L_2(Z, Y), looping over Z. For example, for (C, Q), you have to try all Z in L_2(C, Z) and L_2(Z, Q) and in this case Z can only be R and you get L_3(C, Q) = {C -> R -> Q}. For other pairs, you might have an empty L_3(X, Y), or there could be many paths of length 3 from X to Y.
However you have to be careful here when building the paths here since some of them must be rejected because they have cycles. If a path has twice the same node, it is rejected.
Then you build L_4(X, Y) for all pairs by combining all paths L_2(X, Z) and L_3(Z, Y) while looping over all possible values for Z. You still remove paths with cycles.
And so on... until you get to L_17576(X, Y).
One worry with this method is that you might run out of memory to store those lists. Note however that after having computed the L_4's, you can get rid of the L_3's, etc. Of course you don't want to delete L_3(A, Z) since those paths are valid paths from A to Z.
Implementation detail: you could put L_3(X, Y) in a 17576 x 17576 array, where the element at (X, Y) is is some structure that stores all paths between (X, Y). However if most elements are empty (no paths), you could use instead a HashMap<Pair, Set<Path>>, where Pair is just some object that stores (X, Y). It's not clear to me if most elements of L_3(X, Y) are empty, and if so, if it is also the case for L_4334(X, Y).
Thanks to #Lie Ryan for pointing out this identical question on mathoverflow. My solution is basically the one by MRA; Huang claims it's not valid, but by removing the paths with duplicate nodes, I think my solution is fine.
I guess my solution needs less computations than the brute force approach, however it requires more memory. So much so that I'm not even sure it is possible on a computer with a reasonable amount of memory.

different for loops java

I'm having some difficulties with the following problem:
I'm making a little game where you're at a specific spot and each spot has each some possible directions.
The available directions are N(ord),E(ast),S,W . I use the function getPosDirections to get the possible directions of that spot. The function returns the directions into an ArrayList<String> e.g. for spot J3: [E,W]
Now the game goes like this: 2 dice will be rolled so you get a number between 2 and 12, this number represents the number of steps you can make.
What I want is an ArrayList of all the possible routes
clarification of all the possible routes:
When I'm at the current position I check what the possibilities are from there. Let's say that's go East and go West. So we get 2 new positions and from there on we need to check for the next possibilities again for both positions (until we took x directions)
(x equals the number thrown by the dice).
e.g.: I throw 3 and I'm currently at spot J3:
[[E,N,E],[E,N,S],[E,S,E],[E,S,S],[W,N,E],[W,N,S],[W,S,E],[W,S,S]]
How would obtain the last mentioned Array(list)?
First, you might wish to think about your approach some more. In the worst case (a 12 is rolled, and all 4 directions are possible at every location), there will be 4^12 ~= 160 million routes. Is it really necessary to iterate over them all? And is it necessary to fill about 1 GB of memory to store that list?
Next, it is probably a good idea to represent directions in a type-safe manner, for instance using an enum.
That being said, recursion is your friend:
private void iteratePaths(Location currentLoc, List<Direction> currentPath, List<List<Direction>> allPaths, int pathLength) {
if (currentPath.size() >= pathLength) {
allPaths.add(new ArrayList<Direction>(currentPath));
return;
}
for (Direction d : currentLoc.getPosDirections()) {
currentPath.add(d);
Location newLoc = currentLoc.walk(d);
iteratePaths(newLoc, currentPath, allPaths, pathLength);
currentPath.remove(currentPath.size() - 1);
}
}
public void List<List<Direction>> getAllPaths(Location loc, int length) {
List<List<Direction>> allPaths = new ArrayList<List<Direction>>();
List<Direction> currentPath = new ArrayList<Direction>();
iteratePaths(loc, currentPath, allPaths, length);
return allPaths;
}
You can assume that your field of spots is a complete graph. Then you need to implement BFS or DFS with saving pathes.
You can implement all logic in any of these algorithms (like getting a list of possible directions from a certain node).

Categories