Stopping condition for simple DFS traversing - java

I'm trying to solve this problem on topcoder as a practice , I tried implementing DFS solution for it , it works well except for a bug : it keeps traversing every unvisited cell even if it reached a dead end , the initial code was :
public void func(int[][] x, StringBuilder s, int i, int j, int n) {
if (i < 0 || j < 0 || i > n || j > n || x[i][j] == 1) {
return;
}
s.append((char) (97 + j));
s.append(n - i + 1 + "-");
x[i][j] = 1;
func(x, s, i, j + 1, n);
func(x, s, i - 1, j, n);
func(x, s, i + 1, j, n);
func(x, s, i, j - 1, n);
return;
}
public String dukePath(int n, String initPosition) {
String p = initPosition;
int x[][] = new int[n][n];
StringBuilder s = new StringBuilder("");
func(x, s, n - Integer.parseInt(p.charAt(1) + ""), (int) p.charAt(0) - 97, n - 1);
s.replace(s.length() - 1, s.length(), "");
if (s.length() > 40) {
s.replace(20, s.length() - 20, "...");
}
return s.toString();
}
so I tried to modify the signature of the function "func()" by adding a boolean flag , and initial position (z,y) to compare the current cell with ; if the code tries to revisit the initial position then it should return , but it also didn't work..
How could I stop traversing when reaching a dead-end or the initial position again ?

You are approaching this problem incorrectly, all you need to do is to move to the lexicographically greatest neighbour at every step until you reach a point where you have visited all neighbouring cells. This is simple iteration and doesn't require DFS:
public static String dukePath(int n, String initPosition) {
int x = initPosition.charAt(0) - 'a';
int y = n - (initPosition.charAt(1) - '0');
boolean grid[][] = new boolean[n][n];
StringBuilder s = new StringBuilder(initPosition);
while (true) {
grid[x][y] = true;
if (x < (n - 1) && !grid[x + 1][y])
x++; // Right
else if (y > 0 && !grid[x][y - 1])
y--; // Up
else if (y < (n - 1) && !grid[x][y + 1])
y++; // Down
else if (x > 0 && !grid[x - 1][y])
x--; // Left
else
break; // Nowhere left to go!
s.append("-" + (char)('a' + x) + (char)('0' + n - y));
}
if (s.length() > 40) {
s.replace(20, s.length() - 20, "...");
}
return s.toString();
}
public static void main(String args[])
{
System.out.println(dukePath(3, "b2"));
System.out.println(dukePath(4, "d4"));
System.out.println(dukePath(3, "a2"));
System.out.println(dukePath(4, "d3"));
System.out.println(dukePath(8, "a8"));
}
Gives the expected results:
b2-c2-c3-b3-a3-a2-a1-b1-c1
d4-d3-d2-d1-c1-c2-c3...b3-b2-b1-a1-a2-a3-a4
a2-b2-c2-c3-b3-a3
d3-d4-c4-c3-c2-d2-d1...b2-b3-b4-a4-a3-a2-a1
a8-b8-c8-d8-e8-f8-g8...a1-a2-a3-a4-a5-a6-a7

I think the simplest solution is to create a set of objects containing i and j. In every call of func if this set contains the target object with i and j, it should not call the func function. This method both covers step backs and loops.

Related

Method returns wrong value when there is no way to reach the goal

Method prince.This should be recursive method without any loops.Prince can move only one cell to the west or east or south or north(not diagonally). Prince is jumping by the roofs, searching for the villain.The cell with a villain values -1, and this is the only negative value in the array. Method takes three parameters: drm - Digital Rood Map(as 2d array), i - rows, j - columns (This is the index where he starts his path).
Cells value represents the roof height. Prince can jump from one roof to another under these circumstances:
If the roof that he jumps on is the same value,as the roof that he jumps from.
If the difference between roof that he jumps down from to the roof that lays above is not more than 2.
(from 5 to 3, or from 2 to 0).
Prince can climb up to another roof if its not more than 1 cell above.
(from 3 to 4, or from 0 to 1).
Method must return the shortest way to the villain(to the index that values -1). If prince deadlocks, then method should return -1.
public class Test {
public static int prince(int[][] drm, int i, int j) {
final int BEEN_HERE = Integer.MAX_VALUE;
if (drm[i][j] == -1) {
return 1;
}
int temp = drm[i][j];
drm[i][j] = BEEN_HERE;
int north = Integer.MAX_VALUE, south = Integer.MAX_VALUE, east = Integer.MAX_VALUE, west = Integer.MAX_VALUE;
if (i - 1 >= 0) {
if(drm[i - 1][j]==temp||temp - drm[i-1][j]==2||Math.abs(temp - drm[i-1][j])==1 || drm[i-1][j]==-1)
north = prince(drm, i - 1, j) + 1;
}
if (i + 1 < drm[0].length) {
if(drm[i + 1][j]==temp||temp - drm[i + 1][j]==2||Math.abs(temp - drm[i + 1][j])==1 || drm[i + 1][j]==-1)
south = prince(drm, i + 1, j) + 1;
}
if (j - 1 >= 0 ) {
if(temp==drm[i][j-1] || temp - drm[i][j-1]==2||Math.abs(temp - drm[i][j-1])==1 || drm[i][j-1]==-1)
west = prince(drm, i, j - 1) + 1;
}
if (j + 1 < drm.length) {
if(temp==drm[i][j+1] || temp - drm[i][j+1]==2||Math.abs(temp - drm[i][j+1])==1 || drm[i][j+1]==-1)
east = prince(drm, i, j + 1) + 1;
}
if(north==Integer.MAX_VALUE&&south==Integer.MAX_VALUE&&east==Integer.MAX_VALUE&&west==Integer.MAX_VALUE){
return -1;
}
return Math.min(Math.min(north, south), Math.min(east, west));
}
public static void main(String[] args) {
int[][] a =
{{2,0,1,2,3}
,{2,3,5,5,4},
{8,-1,6,8,7},
{3,4,7,2,4}
,{2,4,3,1,2}};
System.out.println(prince(a, 4, 4));
}
}
From the index a[4][4] when the prince deadlocks method returns 1 instead of -1. Can you please help me with any idea how can i prevent this.
int[][] a =
{{2,0,1,2,3}
,{2,3,5,5,4},
{8,-1,6,8,7},
{3,4,7,2,4}
,{2,4,3,1,2}};
System.out.println(prince(a, 4, 4));
I have added another parameter steps to the function signature, the problem was that you returned the path length even to invalid paths. But the function should return the path length only when path is valid, else return MAX_VALUE
public static int prince(int[][] drm, int i, int j,int steps) {
final int BEEN_HERE = Integer.MAX_VALUE;
if (drm[i][j] == -1) {
return steps;
}
int temp = drm[i][j];
drm[i][j] = BEEN_HERE;
int north = Integer.MAX_VALUE, south = Integer.MAX_VALUE, east = Integer.MAX_VALUE, west = Integer.MAX_VALUE;
if (i - 1 >= 0) {
if(drm[i - 1][j]==temp||temp - drm[i-1][j]==2||Math.abs(temp - drm[i-1][j])==1 || drm[i-1][j]==-1)
north = prince(drm, i - 1, j,steps+1);
}
if (i + 1 < drm[0].length) {
if(drm[i + 1][j]==temp||temp - drm[i + 1][j]==2||Math.abs(temp - drm[i + 1][j])==1 || drm[i + 1][j]==-1)
south = prince(drm, i + 1, j,steps+1);
}
if (j - 1 >= 0 ) {
if(temp==drm[i][j-1] || temp - drm[i][j-1]==2||Math.abs(temp - drm[i][j-1])==1 || drm[i][j-1]==-1)
west = prince(drm, i, j - 1,steps+1);
}
if (j + 1 < drm.length) {
if(temp==drm[i][j+1] || temp - drm[i][j+1]==2||Math.abs(temp - drm[i][j+1])==1 || drm[i][j+1]==-1)
east = prince(drm, i, j + 1,steps+1) ;
}
drm[i][j]=temp;
return Math.min(Math.min(north, south), Math.min(east, west));
}
public static int prince(int[][] drm, int i, int j) {
int res= prince(drm,i,j,1);
if(res==Integer.MAX_VALUE)
return -1;
else return res;
}
public static void main(String[] args) {
int[][] a =
{{2,0,1,2,3}
,{2,3,5,5,4},
{8,-1,6,8,7},
{3,4,7,2,4}
,{2,4,3,1,2}};
System.out.println(prince(a, 0, 0));
}

Adding return statement in DFS on grid causes abnormality

So the question asked to print all the paths to reach from (1,1) to (M,N) in an M X N grid and total numbers of ways for the same.
Problem Statement
Take as input M and N, both numbers. M and N is the number of rows and columns on a rectangular board. Our player starts in top-left corner of the board and must reach bottom-right corner. In one move the player can move 1 step horizontally (right) or 1 step vertically (down) or 1 step diagonally (south-east).
Write a recursive function which returns the count of different ways the player can travel across the board. Print the value returned.
Write a recursive function which prints moves for all valid paths across the board (void is the return type for function).
Expected Input/Output:
Input:
3 3
Output:
VVHH VHVH VHHV VHD VDH HVVH HVHV HVD HHVV HDV DVH DHV DD
13
My JAVA Solution
import java.util.*;
public class Main {
static int count = 0;
public static void main(String args[]) {
Scanner sc = new Scanner(System.in);
int m = sc.nextInt();
int n = sc.nextInt();
dfs(m, n, 0, 0, new int[m][n], "");
System.out.print("\n" + count);
sc.close();
}
static void dfs(int m, int n, int i, int j, int[][] board, String path) {
if (i < 0 || i >= m || j < 0 || j >= n || board[i][j] == 1) {
return;
}
board[i][j] = 1;
if (i == m - 1 && j == n - 1) {
count++;
System.out.print(path + " ");
return; // this line when included does cause problem
}
dfs(m, n, i + 1, j, board, path + "V");
dfs(m, n, i, j + 1, board, path + "H");
dfs(m, n, i + 1, j + 1, board, path + "D");
board[i][j] = 0;
}
}
But When I include the return statement then the ouput is:
Input:
3 3
Output:
VVHH
1
I am not able to understand why does it make difference to have the return statement when we are already at the right-most bottom of the board.
Any explanations are always welcome.
The problem is this line here:
board[i][j] = 0;
If you return without resetting the board, your result will be incorrect. This will happen if your return in your if statement, since this line board[i][j] = 0; line wont be reached.
A solution would be to add that line to the if statement:
if (i == m - 1 && j == n - 1) {
count++;
System.out.print(path + " ");
board[i][j] = 0;
return;
}
You do not have to mark the cell once it has been reached. Because as long as you go to right, down or right down, you will never reach the same cell. Therefore, board[][] is unnecessary.
static int count = 0;
static void dfs(int m, int n, int i, int j, String path) {
if (i < 0 || i >= m || j < 0 || j >= n) {
return;
}
if (i == m - 1 && j == n - 1) {
count++;
System.out.print(path + " ");
return;
}
dfs(m, n, i + 1, j, path + "V");
dfs(m, n, i, j + 1, path + "H");
dfs(m, n, i + 1, j + 1, path + "D");
}
public static void main(String[] args) {
dfs(3, 3, 0, 0, "");
System.out.println();
System.out.println(count);
}
output:
VVHH VHVH VHHV VHD VDH HVVH HVHV HVD HHVV HDV DVH DHV DD
13

StackOverflowError during recursive calls to find closest empty index in 2D array

I am trying to use a recursive approach to figure out the closest empty element in my 2D array if the input index already has an element. For example, I call my method tryPlant(int X, int Y) to put a symbol in my 2D (32x32) array:
ecoArray[X][Y] == "." (empty) then fill it with "~"
If there is an element besides ".", then recursively find the next empty spot in the same row first, then column.
The code for the method is:
public void tryPlant(int X, int Y){
if (this.ecoArray[X][Y] == ".") {
this.ecoArray[X][Y] = "~";
}else{
if((Y - 1) >= 0) {
tryPlant(X, Y - 1);
}
else if((Y + 1) <= 32){
tryPlant(X, Y + 1);
}else if((X - 1) >= 0 ) {
tryPlant(X - 1, Y);
}else if((X + 1) <= 32){
tryPlant(X + 1, Y);
}
}
}
I am calling the method in another class like this:
Plant p1;
private void initPlants(){
int size = p1.initPop;
for (int i = 0; i < size; i++) {
int randX = randGen();
int randY = randGen();
Plant plant = new Plant(randX, randY, this.ecoArray);
}
}
The randGen() method returns a random integer between 0-31.
Sometimes the random generator gives me indexes such that they do not collide with other objects. An example of this (the | are obstacles):
I want to know why I get a stackoverflow error and what I can do to fix it. If you need any other portions of my code, please ask. I am pretty new to Java.
Edit
public static int left = 0;
public static int right = 0;
public void tryPlant(int X, int Y){
if (this.ecoArray[X][Y] == ".") {
this.ecoArray[X][Y] = "~";
}else{
if((Y - 1) >= 0) {
this.left++;
tryPlant(X, Y - 1);
}
else if((Y + this.left + 1) <= 32){
tryPlant(X, Y + this.left + 1);
this.left = 0;
}else if((X - 1) >= 0 ) {
this.right++;
tryPlant(X - 1, Y);
}else if((X + this.right + 1) <= 32){
tryPlant(X + + this.right + 1, Y);
this.right = 0;
}
}
}
Approximately what happens is: Each time a function is called it is stored in a memory stack. When the function return, what was stored is cleared. But, if you call too many functions, you fullfil the memory and a stackoverflow error is sent.
You get a stackoverflow error because somewhere you have a loop in your algorithm. That cause too many call to tryPlant().
First, when you find a way where you already pass, return. (where char == '~')
Second, where there is an obstacle, return. (where char == '|')
Third, you don't try all directions:
if ((Y - 1) >= 0) {
this.left++;
tryPlant(X, Y - 1);
} else if ((Y + this.left + 1) <= 32){
tryPlant(X, Y + this.left + 1);
this.left = 0;
} else if ((X - 1) >= 0 ) {
this.right++;
tryPlant(X - 1, Y);
} else if ((X + this.right + 1) <= 32){
tryPlant(X + + this.right + 1, Y);
this.right = 0;
}
I tried this and it seems to work:
public class Test {
private char[][] ecoArray;
public Test() {
String[] stringArray = new String[] {
"||.|.||..|..||.|.||||||||..||.||",
"||||....||..|||..||....|.||..|||",
"||||||...|.|||...||.|..||..||||.",
"||...||.|.|||.||||.|||||.|...||.",
"|.|....|.|||||||||..||.|.|.||...",
"..|||.||||...|..||.||..|..||||.|",
"..|.||||||..||.||||..|||.|.|...|",
"|||||.||.|||...||...||..||.|||..",
"||||.|..||||||..|.|||...||.||.|.",
"|||.|||||.|||||.||||.|....||||||",
"||...||||||.|.|||||||||||.|.|.||",
"|.|.||||||||.||||....|.||||.||||",
"||..||.||||.|..||.|||..||.|.||||",
"..||..|..||.|.|||..|||..|||||.|.",
"||||.|.||.||||.|||||..|||.|.....",
"..|.|.|||..|||..||.||||.|||.|..|",
"||||.|..|||||||.|||||.||.|.|....",
"..|...||...|||||.|...|..|...|||.",
"..|||||||..||...||||||..|..|||||",
"||||..||.|.|||||.||||.|||||.||..",
"|||||.||||.|....||||....||.||...",
"||..||.|||||.||||||..||..|....||",
"|.||||.||..|...|.|..|||.|.|||.||",
"...||||.|..|||.|||..|.||...|.|||",
".||||.|..|.|..||..||..||..||||||",
"|||.|||..|||..||||.||||.|.||.|||",
"|||||.||...|.|.|.||...|||..|.|||",
".||||.|.|.|||...|||.|||.....||||",
"|||.|||.|.|...||.|....||||.|.|||",
".||||||.|||||||...||..|||.||||.|",
"||||.|||||.|.||.||||..|.|||.||||",
"|.|.||||....|.||||||||.|||||.|.|"
};
this.ecoArray = new char[32][32];
int index = 0;
for (String s : stringArray) {
this.ecoArray[index] = s.toCharArray();
++index;
}
}
public void tryPlant(int X, int Y){
if (this.ecoArray[X][Y] == '~' || this.ecoArray[X][Y] == '|') {
return;
}
if (this.ecoArray[X][Y] == '.') {
this.ecoArray[X][Y] = '~';
if ((Y - 1) >= 0) {
tryPlant(X, Y - 1);
}
if((Y + 1) < 32){
tryPlant(X, Y + 1);
}
if((X - 1) >= 0 ) {
tryPlant(X - 1, Y);
}
if((X + 1) < 32){
tryPlant(X + 1, Y);
}
}
}
private void displayInConsole() {
for (char[] cl : this.ecoArray) {
System.out.println(cl);
}
}
public static void main(String[] args) {
for (int x = 0; x < 32; x++) {
for (int y = 0; y < 32; y++) {
Test t = new Test();
t.tryPlant(x, y);
System.out.println("After tryPlant('" + x + "','" + y + "'): ");
t.displayInConsole();
}
}
}
}
Is it doing what you need ? I don't really understand where you want to start and where you want to stop...
The result is too big sorry...

How can i fin the index using exponential, binary or interpolatin search recursively? [duplicate]

This question already has an answer here:
How can I locate an index given the following constraints? [closed]
(1 answer)
Closed 9 years ago.
Given an array of n integers A[0…n−1], such that ∀i,0≤i≤n, we have that |A[i]−A[i+1]|≤1, and if A[0]=x, A[n−1]=y, we have that x<y. Locate the index j such that A[j]=z, for a given value of z, x≤ z ≤y
I dont understand the problem. I've been stuck on it for 4 days. Any idea of how to approach it with binary search, exponential search or interpolation search recursively? We are given an element z find the index j such that a [j] = z (a j) am i right?.
static int binarySearch(int[] searchArray, int x) {
int start, end, midPt;
start = 0;
end = searchArray.length - 1;
while (start <= end) {
midPt = (start + end) / 2;
if (searchArray[midPt] == x) {
return midPt;
} else if (searchArray[midPt] < x) {
start = midPt + 1;
} else {
end = midPt - 1;
}
}
return -1;
}
You can use the basic binary search algorithm. The fact that A[i] and A[i+1] differ by at most 1 guarantees you will find a match.
Pseudocode:
search(A, z):
start := 0
end := A.length - 1
while start < end:
x = A[start]
y = A[end]
mid := (start+end)/2
if x <= z <= A[mid]:
end := mid
else if A[mid] < z <= y
start := mid + 1
return start
Note that this doesn't necessarily return the first match, but that wasn't required.
to apply your algorithms your need a sorted array.
the condition of you problem says that you have an array which has elements that differ with max 1, not necessarily sorted!!!
so, here are the steps to write the code :
check if problem data respects given conditions
sort input array + saving old indexes values, so later can can initial positions of elements
implement you search methods in recursive way
Binary search source
Interpolation search source
Here's full example source :
public class Test {
// given start ======================================================
public int[] A = new int[] { 1, 1, 2, 3, 4, 4, 3, 2, 1, 1, 2, 3, 4, 5, 6,
7, 8 };
public int z = 4;
// given end =======================================================
public int[] indexes = new int[A.length];
public static void main(String[] args) throws Exception {
Test test = new Test();
if (test.z < test.A[0] || test.z > test.A[test.A.length - 1]){
System.out.println("Value z="+test.z+" can't be within given array");
return;
}
sort(test.A, test.indexes);
int index = binSearch(test.A, 0, test.A.length, test.z);
if (index > -1) {
System.out.println("Binary search result index =\t"
+ test.indexes[index]);
}
index = interpolationSearch(test.A, test.z, 0, test.A.length-1);
if (index > -1) {
System.out.println("Binary search result index =\t"
+ test.indexes[index]);
}
}
public static void sort(int[] a, int[] b) {
for (int i = 0; i < a.length; i++)
b[i] = i;
boolean notSorted = true;
while (notSorted) {
notSorted = false;
for (int i = 0; i < a.length - 1; i++) {
if (a[i] > a[i + 1]) {
int aux = a[i];
a[i] = a[i + 1];
a[i + 1] = aux;
aux = b[i];
b[i] = b[i + 1];
b[i + 1] = aux;
notSorted = true;
}
}
}
}
public static int binSearch(int[] a, int imin, int imax, int key) {
// test if array is empty
if (imax < imin)
// set is empty, so return value showing not found
return -1;
else {
// calculate midpoint to cut set in half
int imid = (imin + imax) / 2;
// three-way comparison
if (a[imid] > key)
// key is in lower subset
return binSearch(a, imin, imid - 1, key);
else if (a[imid] < key)
// key is in upper subset
return binSearch(a, imid + 1, imax, key);
else
// key has been found
return imid;
}
}
public static int interpolationSearch(int[] sortedArray, int toFind, int low,
int high) {
if (sortedArray[low] == toFind)
return low;
// Returns index of toFind in sortedArray, or -1 if not found
int mid;
if (sortedArray[low] <= toFind && sortedArray[high] >= toFind) {
mid = low + ((toFind - sortedArray[low]) * (high - low))
/ (sortedArray[high] - sortedArray[low]); // out of range is
// possible here
if (sortedArray[mid] < toFind)
low = mid + 1;
else if (sortedArray[mid] > toFind)
// Repetition of the comparison code is forced by syntax
// limitations.
high = mid - 1;
else
return mid;
return interpolationSearch(sortedArray, toFind, low, high);
} else {
return -1;
}
}
}

Algorithm for finding all paths in a NxN grid

Imagine a robot sitting on the upper left hand corner of an NxN grid. The robot can only move in two directions: right and down. How many possible paths are there for the robot?
I could find solution to this problem on Google, but I am not very clear with the explanations. I am trying to clearly understand the logic on how to solve this and implement in Java. Any help is appreciated.
Update: This is an interview question. For now, I am trying to reach the bottom-right end and print the possible paths.
public static int computePaths(int n){
return recursive(n, 1, 1);
}
public static int recursive(int n, int i, int j){
if( i == n || j == n){
//reach either border, only one path
return 1;
}
return recursive(n, i + 1, j) + recursive(n, i, j + 1);
}
To find all possible paths:
still using a recursive method. A path variable is assigned "" in the beginning, then add each point visited to 'path'. A possible path is formed when reaching the (n,n) point, then add it to the list.
Each path is denoted as a string, such as " (1,1) (2,1) (3,1) (4,1) (4,2) (4,3) (4,4)". All possible paths are stored in a string list.
public static List<String> robotPaths(int n){
List<String> pathList = new ArrayList<String>();
getPaths(n, 1,1, "", pathList);
return pathList;
}
public static void getPaths(int n, int i, int j, String path, List<String> pathList){
path += String.format(" (%d,%d)", i , j);
if( i ==n && j == n){ //reach the (n,n) point
pathList.add(path);
}else if( i > n || j > n){//wrong way
return;
}else {
getPaths(n, i +1, j , path, pathList);
getPaths(n, i , j +1, path, pathList);
}
}
I see no indications for obstacles in your question so we can assume there are none.
Note that for an n+1 by n+1 grid, a robot needs to take exactly 2n steps in order to reach the lower right corner. Thus, it cannot make any more than 2n moves.
Let's start with a simpler case: [find all paths to the right down corner]
The robot can make exactly choose(n,2n)= (2n)!/(n!*n!) paths: It only needs to choose which of the 2n moves will be right, with the rest being down (there are exactly n of these).
To generate the possible paths: just generate all binary vectors of size 2n with exactly n 1's. The 1's indicate right moves, the 0's, down moves.
Now, let's expand it to all paths:
First choose the length of the path. To do so, iterate over all possibilities: 0 <= i <= 2n, where i is the length of the path. In this path there are max(0,i-n) <= j <= min(i,n) right steps.
To generate all possibilities, implement the following pseudo-code:
for each i in [0,2n]:
for each j in [max(0,i-n),min(i,n)]:
print all binary vectors of size i with exactly j bits set to 1
Note 1: printing all binary vectors of size i with j bits set to 1 could be computationally expensive. That is expected since there are an exponential number of solutions.
Note 2: For the case i=2n, you get j in [n,n], as expected (the simpler case described above).
https://math.stackexchange.com/questions/104032/finding-points-in-a-grid-with-exactly-k-paths-to-them - look here at my solution. Seems that it is exactly what you need (yes, statements are slightly different, but in general case they are just the same).
This is for if the robot can go 4 directions rather than just 2, but the recursive solution below (in Javascript) works and I've tried to make it as legible as possible:
//first make a function to create the board as an array of arrays
var makeBoard = function(n) {
var board = [];
for (var i = 0; i < n; i++) {
board.push([]);
for (var j = 0; j < n; j++) {
board[i].push(false);
}
}
board.togglePiece = function(i, j) {
this[i][j] = !this[i][j];
}
board.hasBeenVisited = function(i, j) {
return !!this[i][j];
}
board.exists = function(i, j) {
return i < n && i > -1 && j < n && j > -1;
}
board.viablePosition = function(i, j) {
return board.exists(i, j) && !board.hasBeenVisited(i,j);
}
return board;
};
var robotPaths = function(n) {
var numPaths = 0;
//call our recursive function (defined below) with a blank board of nxn, with the starting position as (0, 0)
traversePaths(makeBoard(n), 0, 0);
//define the recursive function we'll use
function traversePaths(board, i, j) {
//BASE CASE: if reached (n - 1, n - 1), count as solution and stop doing work
if (i === (n - 1) && j === (n - 1)) {
numPaths++;
return;
}
//mark the current position as having been visited. Doing this after the check for BASE CASE because you don't want to turn the target position (i.e. when you've found a solution) to true or else future paths will see it as an unviable position
board.togglePiece(i, j);
//RECURSIVE CASE: if next point is a viable position, go there and make the same decision
//go right if possible
if (board.viablePosition(i, j + 1)) {
traversePaths(board, i, j + 1);
}
//go left if possible
if (board.viablePosition(i, j - 1)) {
traversePaths(board, i, j - 1);
}
//go down if possible
if (board.viablePosition(i + 1, j)) {
traversePaths(board, i + 1, j);
}
//go up if possible
if (board.viablePosition(i - 1, j)) {
traversePaths(board, i - 1, j);
}
//reset the board back to the way you found it after you've gone forward so that other paths can see it as a viable position for their routes
board.togglePiece(i, j);
}
return numPaths;
};
A cleaner version:
var robotPaths = function(n, board, i, j) {
board = board || makeBoard(n),
i = i || 0,
j = j || 0;
// If current cell has been visited on this path or doesn't exist, can't go there, so do nothing (no need to return since there are no more recursive calls below this)
if (!board.viablePosition(i, j)) return 0;
// If reached the end, add to numPaths and stop recursing
if (i === (n - 1) && j === (n - 1)) return 1;
// Mark current cell as having been visited for this path
board.togglePiece(i, j);
// Check each of the four possible directions
var numPaths = robotPaths(n, board, i + 1, j) + robotPaths(n, board, i - 1, j) + robotPaths(n, board, i, j + 1) + robotPaths(n, board, i, j - 1);
// Reset current cell so other paths can go there (since board is a pointer to an array that every path is accessing)
board.togglePiece(i, j);
return numPaths;
}
So:
robotPaths(5); //returns 8512
Scenario:
1. Imagine there is NxN zero indexed matrix.
2. Initial position of robot is upper-left corner i.e. (N-1, N-1)
3. Robot wants to reach lower right corner i.e. at (0,0)
Solution:
-- In any possible solution robot will move N rights steps and N down steps to reach (0,0), or we can say that initial robot has permission to move N rights steps and N down steps.
-- When ever robot moves right we reduce its remaining number of right steps by 1, same is for down movement.
-- At every position(except at boundary, where it will have only one option) robot have two options, one is it can go down or other is it can go right.
-- It will terminate when robot will have no remaining down of right steps.
**Below code also have driver method main(), you can change the value of N. N can be >=1
public class RobotPaths {
public static int robotPaths(int down, int right, String path)
{
path = path+ down +","+ right +" ";
if(down==0 && right==0)
{
System.out.println(path);
return 1;
}
int counter = 0;
if(down==0)
counter = robotPaths(down, right-1, path);
else if(right==0)
counter = robotPaths(down-1, right, path);
else
counter = robotPaths(down, right-1, path) + robotPaths(down-1, right, path);
return counter;
}
public static void main(String[] args)
{
int N = 1;
System.out.println("Total possible paths: "+RobotPaths.robotPaths(N-1, N-1, ""));
}
}
If you just need a count of the valid paths:
Let's say you have a matrix n*m matrix and you set all cells to zero and the "offlimit" cells to -1.
You can then solve the problem with dynamic programming:
// a is a matrix with 0s and -1s
// n, m are the dimensions
// M is 10^9-7 incase you have a large matrix
if (a[0][0] == 0) a[0][0] = 1;
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
if (a[i][j] == -1) continue;
if (i > 0) a[i][j] = (a[i][j] + max(a[i-1][j], 0LL)) % M;
if (j > 0) a[i][j] = (a[i][j] + max(a[i][j-1], 0LL)) % M;
}
}
// answer at lower right corner
cout << a[n-1][m-1];
Blazing fast without recursion or bloaty data structures.
NOTE: this was deleted due to being duplicate but since this is the best thread on this topic, I've deleted my answer from elsewhere and will add this here.
Here is c# version (just for reference) to find unique paths (note here is the version which returns number of paths using dynamic programming (memorization - lazy) - Calculating number of moves from top left corner to bottom right with move in any direction) (you may refer to my blog for more details: http://codingworkout.blogspot.com/2014/08/robot-in-grid-unique-paths.html)
Tuple<int, int>[][] GetUniquePaths(int N)
{
var r = this.GetUniquePaths(1, 1, N);
return r;
}
private Tuple<int, int>[][] GetUniquePaths(int row, int column, int N)
{
if ((row == N) && (column == N))
{
var r = new Tuple<int, int>[1][];
r[0] = new Tuple<int, int>[] { new Tuple<int,int>(row, column) };
return r;
}
if ((row > N) || (column > N))
{
return new Tuple<int, int>[0][];
}
var uniquePathsByMovingDown = this.GetUniquePaths(row + 1, column, N);
var uniquePathsByMovingRight = this.GetUniquePaths(row, column + 1, N);
List<Tuple<int, int>[]> paths = this.MergePaths(uniquePathsByMovingDown,
row, column).ToList();
paths.AddRange(this.MergePaths(uniquePathsByMovingRight, row, column));
return paths.ToArray();
}
where
private Tuple<int, int>[][] MergePaths(Tuple<int, int>[][] paths,
int row, int column)
{
Tuple<int, int>[][] mergedPaths = new Tuple<int, int>[paths.Length][];
if (paths.Length > 0)
{
Assert.IsTrue(paths.All(p => p.Length > 0));
for (int i = 0; i < paths.Length; i++)
{
List<Tuple<int, int>> mergedPath = new List<Tuple<int, int>>();
mergedPath.Add(new Tuple<int, int>(row, column));
mergedPath.AddRange(paths[i]);
mergedPaths[i] = mergedPath.ToArray();
}
}
return mergedPaths;
}
Unit Tests
[TestCategory(Constants.DynamicProgramming)]
public void RobotInGridTests()
{
int p = this.GetNumberOfUniquePaths(3);
Assert.AreEqual(p, 6);
int p1 = this.GetUniquePaths_DP_Memoization_Lazy(3);
Assert.AreEqual(p, p1);
var p2 = this.GetUniquePaths(3);
Assert.AreEqual(p1, p2.Length);
foreach (var path in p2)
{
Debug.WriteLine("===================================================================");
foreach (Tuple<int, int> t in path)
{
Debug.Write(string.Format("({0}, {1}), ", t.Item1, t.Item2));
}
}
p = this.GetNumberOfUniquePaths(4);
Assert.AreEqual(p, 20);
p1 = this.GetUniquePaths_DP_Memoization_Lazy(4);
Assert.AreEqual(p, p1);
p2 = this.GetUniquePaths(4);
Assert.AreEqual(p1, p2.Length);
foreach (var path in p2)
{
Debug.WriteLine("===================================================================");
foreach (Tuple<int, int> t in path)
{
Debug.Write(string.Format("({0}, {1}), ", t.Item1, t.Item2));
}
}
}
Here is a full implementation that works for both rectangular and square grids. I will leave you to figure out how to take care of the excess "=>" at the end of each path.
import java.util.Arraylist;
public class PrintPath
{
static ArrayList<String> paths = new ArrayList<String>();
public static long getUnique(int m, int n, int i, int j, String pathlist)
{
pathlist += ("(" + i + ", " + (j) + ") => ");
if(m == i && n == j)
{
paths.add(pathlist);
}
if( i > m || j > n)
{
return 0;
}
return getUnique(m, n, i+1, j, pathlist)+getUnique(m, n, i, j+1, pathlist);
}
public static void printPaths()
{
int count = 1;
System.out.println("There are "+paths.size() + " unique paths: \n");
for (int i = paths.size()-1; i>=0; i--)
{
System.out.println( "path " + count + ": " + paths.get(i));
count++;
}
}
public static void main(String args[])
{
final int start_Point = 1;
int grid_Height = 2;
int grid_Width = 2;
getUnique(grid_Height, grid_Width, start_Point, start_Point, "");
printPaths();
}
}
Below is the code in Java to count all the possible paths from top left corner to bottom right corner of a NXN matrix.
public class paths_in_matrix {
/**
* #param args
*/
static int n=5;
private boolean[][] board=new boolean[n][n];
int numPaths=0;
paths_in_matrix(){
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
board[i][j]=false;
}
}
}
private void togglePiece(int i,int j){
this.board[i][j]=!this.board[i][j];
}
private boolean hasBeenVisited(int i,int j){
return this.board[i][j];
}
private boolean exists(int i,int j){
return i < n && i > -1 && j < n && j > -1;
}
private boolean viablePosition(int i,int j){
return exists(i, j) && !hasBeenVisited(i,j);
}
private void traversePaths(int i,int j){
//BASE CASE: if reached (n - 1, n - 1), count as path and stop.
if (i == (n - 1) && j == (n - 1)) {
this.numPaths++;
return;
}
this.togglePiece(i, j);
//RECURSIVE CASE: if next point is a viable position, go there and make the same decision
//go right if possible
if (this.viablePosition(i, j + 1)) {
traversePaths(i, j + 1);
}
//go left if possible
if (this.viablePosition(i, j - 1)) {
traversePaths( i, j - 1);
}
//go down if possible
if (this.viablePosition(i + 1, j)) {
traversePaths( i + 1, j);
}
//go up if possible
if (this.viablePosition(i - 1, j)) {
traversePaths(i - 1, j);
}
//reset the board back to the way you found it after you've gone forward so that other paths can see it as a viable position for their routes
this.togglePiece(i, j);
}
private int robotPaths(){
traversePaths(0,0);
return this.numPaths;
}
public static void main(String[] args) {
paths_in_matrix mat=new paths_in_matrix();
System.out.println(mat.robotPaths());
}
}
Here you go (python):
def numPathsFromULtoRD(m,n):
return factorial(m+n-2)//(factorial(m-1)*factorial(n-1))
def solution(m,n):
result = 0
for i in range(m):
for j in range(n):
if i == 0 and j == 0:
continue
result += numPathsFromULtoRD(i+1,j+1)
return result
int N;
function num_paths(intx,int y)
{
int[][] arr = new int[N][N];
arr[N-1][N-1] = 0;
for(int i =0;i<N;i++)
{
arr[N-1][i]=1;
arr[i][N-1]=1;
}
for(int i = N-2;i>=0;i--)
{
for(int j=N-2;j>=0;j--)
{
arr[i][j]= arr[i+1][j]+arr[i][j+1];
}
}
return arr[0][0];
}

Categories