Can some one tell me what i have done wrong - java

I got a question in interview about a man who can take a step back or move double of his current distance . Considering each of them as a single move find minimum moves he can take to reach y from x.
import java.util.*;
import java.io.*;
public class Main
{
public static int Solve(int x,int y)
{
if(x==0)
{
return Integer.MAX_VALUE;
}
else if(x==y)
{
return 0;
}
else if(x==1)
{
return 1+Solve(x*2,y);
}
return Math.min(1+Solve(x*2,y),1+Solve(x-1,y));
}
public static void main(String[] args)
{
Scanner sc=new Scanner(System.in);
int x=sc.nextInt();
int y=sc.nextInt();
int z=Solve(x,y);
System.out.print(z);
}
}

This is an infinite loop. At what place will Solve( x * 2, y) ever
stop ?
Assuming all this is in one axis only (1D), since you defined int x and int y. Let’s say we have x and y, if y-x is positive, that means we have to go forward. Now if y-x is odd, let’s say 7 that means we have to go 8 steps (4*2) ahead, then 1 (1 step) back. Giving us 5 steps. So we have to go
(((y-x) + 1)/2) + 1
So 7+1 = 8, we go 8 steps ahead taking double steps, then 1 more step to come back.
If it is even, then that means we can go straight ahead ! So
(y-x)/2
If y-x is negative, which means we have to go back. Only way is 1 step back (x-1), so that will just be
-(y-x) steps.
You can write the code. I like the recursion aspect for your code, but it’s an overkill if it is 1D.

Not sure if a recursion-based solution is needed here.
We have two subproblems here:
count moves back when from >= to
otherwise count moves forward taking into account a case when difference to - from is odd: then 1 extra move forward is needed and 1 step back.
This can be resolved with the help of a ternary operator:
public static int findMoveCount(int from, int to) {
return from >= to ? from - to : (to - from) % 2 * 2 + (to - from)/2;
}

Related

Shortest path in Rat in a Maze with option to remove one wall

This is the problem:
You have maps of parts of the space station, each starting at a prison exit and ending at the door to an escape pod. The map is represented as a matrix of 0s and 1s, where 0s are passable space and 1s are impassable walls. The door out of the prison is at the top left (0,0) and the door into an escape pod is at the bottom right (w-1,h-1).
Write a function answer(map) that generates the length of the shortest path from the prison door to the escape pod, where you are allowed to remove one wall as part of your remodeling plans. The path length is the total number of nodes you pass through, counting both the entrance and exit nodes. The starting and ending positions are always passable (0). The map will always be solvable, though you may or may not need to remove a wall. The height and width of the map can be from 2 to 20. Moves can only be made in cardinal directions; no diagonal moves are allowed.
To Summarize the problem: It is a simple rat in a maze problem with rat starting at (0,0) in matrix and should reach (w-1,h-1). Maze is a matrix of 0s and 1s. 0 means path and 1 means wall.You have the ability to remove one wall(change it from 0 to 1). Find the shortest path.
I've solved the problem but 3 of 5 testcases fail and I don't know what those test cases are. and I'm unable to figure out why. Any help would be greatly appreciated.Thanks in Advance. Here is my code:
import java.util.*;
class Maze{//Each cell in matrix will be this object
Maze(int i,int j){
this.flag=false;
this.distance=0;
this.x=i;
this.y=j;
}
boolean flag;
int distance;
int x;
int y;
}
class Google4_v2{
public static boolean isPresent(int x,int y,int r,int c)
{
if((x>=0&&x<r)&&(y>=0&&y<c))
return true;
else
return false;
}
public static int solveMaze(int[][] m,int x,int y,int loop)
{
int r=m.length;
int c=m[0].length;
int result=r*c;
int min=r*c;
Maze[][] maze=new Maze[r][c];//Array of objects
for(int i=0;i<r;i++)
{
for(int j=0;j<c;j++)
{
maze[i][j]=new Maze(i,j);
}
}
Queue<Maze> q=new LinkedList<Maze>();
Maze start=maze[x][y];
Maze[][] spare=new Maze[r][c];
q.add(start);//Adding source to queue
int i=start.x,j=start.y;
while(!q.isEmpty())
{
Maze temp=q.remove();
i=temp.x;j=temp.y;
int d=temp.distance;//distance of a cell from source
if(i==r-1 &&j==c-1)
{
result=maze[i][j].distance+1;
break;
}
maze[i][j].flag=true;
if(isPresent(i+1,j,r,c)&&maze[i+1][j].flag!=true)//check down of current cell
{
if(m[i+1][j]==0)//if there is path, add it to queue
{
maze[i+1][j].distance+=1+d;
q.add(maze[i+1][j]);
}
if(m[i+1][j]==1 && maze[i+1][j].flag==false && loop==0)//if there is no path, see if breaking the wall gives a path.
{
int test=solveMaze(m,i+1,j,1);
if(test>0)
{
test+=d+1;
min=(test<min)?test:min;
}
maze[i+1][j].flag=true;
}
}
if(isPresent(i,j+1,r,c)&&maze[i][j+1].flag!=true)//check right of current cell
{
if(m[i][j+1]==0)
{
maze[i][j+1].distance+=1+d;
q.add(maze[i][j+1]);
}
if(m[i][j+1]==1 && maze[i][j+1].flag==false && loop==0)
{
int test=solveMaze(m,i,j+1,1);
if(test>0)
{
test+=d+1;
min=(test<min)?test:min;
}
maze[i][j+1].flag=true;
}
}
if(isPresent(i-1,j,r,c)&&maze[i-1][j].flag!=true)//check up of current cell
{
if(m[i-1][j]==0)
{
maze[i-1][j].distance+=1+d;
q.add(maze[i-1][j]);
}
if(m[i-1][j]==1 && maze[i-1][j].flag==false && loop==0)
{
int test=solveMaze(m,i-1,j,1);
if(test>0)
{
test+=d+1;
min=(test<min)?test:min;
}
maze[i-1][j].flag=true;
}
}
if(isPresent(i,j-1,r,c)&&maze[i][j-1].flag!=true)//check left of current cell
{
if(m[i][j-1]==0)
{
maze[i][j-1].distance+=1+d;
q.add(maze[i][j-1]);
}
if(m[i][j-1]==1 && maze[i][j-1].flag==false && loop==0)
{
int test=solveMaze(m,i,j-1,1);
if(test>0)
{
test+=d+1;
min=(test<min)?test:min;
}
maze[i][j-1].flag=true;
}
}
}
return ((result<min)?result:min);
}
public static int answer(int[][] m)
{
int count;
int r=m.length;
int c=m[0].length;
count=solveMaze(m,0,0,0);
return count;
}
public static void main(String[] args)
{
Scanner sc=new Scanner(System.in);
System.out.println("enter row size ");
int m=sc.nextInt();
System.out.println("enter column size ");
int n=sc.nextInt();
int[][] maze=new int[m][n];
System.out.println("Please enter values for maze");
for(int i=0;i<m;i++)
{
for(int j=0;j<n;j++)
{
maze[i][j]=sc.nextInt();
}
}
int d=answer(maze);
System.out.println("The maze can be solved in "+d+" steps");
}
}
Found the problem. maze[i][j].flag=true; needs to be put as soon as the cell is visited, inside the if(m[i+1][j]==0) condition. Otherwise, the distance for same cell can be added by more than one cells
Unfortunately it's quite hard to help you because your code is very difficult to read. The variables are generally single characters which makes it impossible to know what they are supposed to represent. Debugging it would be more help than most of us are willing to give :-)
I suggest you go about debugging your code as follows:
Split your solveMaze method into a number of smaller methods that each perform much simpler functions. For example, you have very similar code repeated 4 times for each direction. Work to get that code in a single method which can be called 4 times. Move your code to create the array into a new method. Basically each method should do one simple thing. This approach makes it much easier to find problems when they arise.
Write unit tests to ensure each of those methods do exactly what you expect before attempting to calculate the answer for entire mazes.
Once all the methods are working correctly, generate some mazes starting from very simple cases to very complex cases.
When a case fails, use an interactive debugger to walk through your code and see where it is going wrong.
Good luck.

Java recursion class variable value is reset to 0

I was trying to implement the coin change problem using recursion. I have written the following code and am facing a problem with the static class variable. 'answer' is a class variable and i am trying to add the return value to it in the loop. This works fine within the while loop but after the while loop ends the answer is reset to 0;
while (i * currentCoin <= sum) {
System.out.println("inside while; answer is " + answer);
answer = answer
+ findCombinations(
sum - i * currentCoin,
new ArrayList<Integer>(denominations.subList(1,
denominations.size())));
i++;
}
Below is all the code that I have written. You can copy and run it to check.
import java.util.ArrayList;
import java.util.Collections;
public class CoinChangeHashMap {
static int answer = 0;
public static void main(String[] args) {
int[] array = new int[] { 7, 3, 2 };
ArrayList<Integer> input = new ArrayList<Integer>();
getList(array, input);
findCombinations(12, input);
System.out.println(answer);
}
private static void getList(int[] array, ArrayList<Integer> input) {
for (int i : array) {
input.add(i);
}
}
public static int findCombinations(int sum, ArrayList<Integer> denominations) {
if (denominations.size() == 1) {
if (sum % denominations.get(0) == 0) {
return 1;
}
return 0;
}
int i = 0;
int currentCoin = denominations.get(0);
while (i * currentCoin <= sum) {
System.out.println("inside while; answer is " + answer);
answer = answer
+ findCombinations(
sum - i * currentCoin,
new ArrayList<Integer>(denominations.subList(1,
denominations.size())));
i++;
}
return 0;
}}
**The output that I get is 0. but the expected output is 4. While debugging the output that I got is **
inside while; answer is 0
inside while; answer is 0
inside while; answer is 1
inside while; answer is 1
inside while; answer is 2
inside while; answer is 2
inside while; answer is 0
inside while; answer is 0
inside while; answer is 0
0
Any Help is appreciated.
The problem is related to your odd code structure, in which you convey the outcome of your recursive call sometimes by modifying static variable answer, and sometimes via the method's return value.
If you analyzed the problem more closely, you would discover that it is not upon exit from the loop that the partial results are lost, but rather some time after return from the method. Therefore, consider carefully the way you update the answer:
answer = answer + findCombinations( /* ... */ );
At the top-most level of your recursion, answer is initially 0. When Java evaluates the above expression, it evaluates first the left operand and then the right operand, then it adds them. That is, it evaluates answer, getting the result 0, before it performs the recursive call. The value of answer may be updated in the course of the recursive call, but those changes come too late. Only the bottom-most level of the recursion ever returns a value different from zero, so if the recursive call itself recurses at least one level deeper then it will return zero. In that case, the sum is computed as 0 + 0, and assigned to answer, clobbering any update the method performed.
You could resolve the problem by swapping the order of the operands in your sum, but it would be better, and not much harder, to get rid of the static variable altogether. Use a local variable within the method to accumulate results, and in all cases convey the total back to the caller via the method's return value.

Recursive call has finish in a function but continue printing integers

I tried to investigate what will happen if I write some code after the recursive call and here is the code. I tried to trace the code but I didn't get what was going on. I thought the function will be terminated once my program prints the last value for x since the value for x doesn't satisfy the if loop condition. I executed this code, the result wasn't understandable. Any help would be appreciated.
public class Recursive {
public static void main(String []args){
int a=5;
call(a);
}
public static void call(int x) {
System.out.print(x+"\n");
if(x>0) {
x--;
call(x);
}
System.out.print(x);
}
}
Expected output:5 4 3 2 1 0 0
My output: 5 4 3 2 1 0 0 0 1 2 3 4
instead of while, you can try If condition and remove the last print.
public static void call(int x) {
System.out.print(x+"\n");
if (x>0) {
x--;
call(x--);
}
}
You forgot to say what was surprising or confusing, which indicates that you don't understand the problem (hence two downvotes). Here is what I think may be confusing. The decrement operator x-- first returns the value of a variable and then lowers it's value. So if you run
z= 25
dothedoo(z--)
the value inside dothedoo will be 25, not 24. The alternative --x will lower the value first and then return the value.
This is your code.
public static void call(int x) {
System.out.print(x + "\n");
while (x > 0) {
x--;
call(x);
}
}
Lets consider this call stack with an input of x=2
1) call(2)
2) print x // 2
2) x-- (becomes 1)
3) recursive call to call(1) // remember the call(2) is suspended right now.
4) print x //1
5) x -- (becomes 0)
6) recursive call to call(0)// remember the call(2) and call(1) is suspended right now.
7) print x //0
8) x-- (becomes -1)
9) recursive call to call(-1) // breaks the loop since it doesnt match the condition, resumes flow to the suspended call(1) function.
10) refer step 5 for the value of x.
11) breaks the loop for the call(1) function. // resumes call(2) which was suspended.
12) refer step 2 where x is still 1.
13) moves on with another call(1)
14) this results in printing an extra 0; from the call in step 13
Your while loop is messing up the program.
Your variable in the recursion is passed by value, hence your actual
value of x which is caller's value isnt decremented globally in the caller when you do this call(x) the x which is used after
decrementing in your recursive call is a copy of the x that you have
decremented in the caller.
Please refer to this article to understand more on it.
Also, the while loop is notorious here based on the explaination provided in this answer and what you actuall need is an if loop

Given a number, find which numbers below it divide it using recursion

I can't seem to figure this one out. I need to count how many numbers below a given number in which it is divisible.
Here is what I've tried:
public int testing(int x) {
if (x == 0) {
System.out.println("zero");
return x;
}
else if ((x % (x-1)) == 0) {
System.out.println("does this work?");
x--;
}
return testing(x-1);
}
That doesn't work and I don't know where to go from here. Anyone know what to do?
This is what is wrong:
public int testing(int x) {
If you want to make it recursive, you need to pass both the number to test and the number that you are currently checking. The first one will not change through the recursion, the second one will decrement. You cannot do what you express with only one parameter (unless you use a global variable).
This is not a task that should be solved with recursion.
If you MUST use recursion, the simplest way to do it is to have a second parameter, which is essentially an "I have checked until this number". Then you can increase/decrease this (depending on if you start at 0 or the initial number) and call the recursive on that.
Thing is, Java isn't a functional language, so doing all this is actually kind of dumb, so whoever gave you this exercise probably needs a bop on the head.
Your problem is that your expression x % (x - 1) is using the "current" value of x, which decrements on every call to the recursive function. Your condition will be false all the way down to 2 % (2 - 1).
Using a for loop is a much better way to handle this task (and look at the Sieve of Eratosthenes), but if you really have to use recursion (for homework), you'll need to pass in the original value being factored as well as the current value being tried.
You have a problem with your algorithm. Notice the recursion only ends when x == 0, meaning that your function will always return 0 (if it returns at all).
In addition, your algorithm doesn't seem to make any sense. You are basically trying to find all factors of a number, but there's only one parameter, x.
Try to make meaningful names for your variables and the logic will be easier to read/follow.
public int countFactors(int number, int factorToTest, int numFactors)
{
if (factorToTest == 0) // now you are done
return numFactors;
else
// check if factorToTest is a factor of number
// adjust the values appropriately and recurse
}
There is no need to use recursion here. Here's a non-recursive solution:
public int testing(int n) {
int count = 0;
for (int i = 1; i < n; i++)
if (n % i == 0)
count++;
return count;
}
BTW, you should probably call this something other than testing.
Using recursion:
private static int getFactorCount(int num) {
return getFactorCount(num, num - 1);
}
private static int getFactorCount(int num, int factor) {
return factor == 0 ? 0 : (num % factor == 0 ? 1 : 0)
+ getFactorCount(num, factor - 1);
}
public static void main(String[] args) {
System.out.println(getFactorCount(20)); // gives 5
System.out.println(getFactorCount(30)); // gives 7
}

Compute the different ways to make (money) change from $167.37?

This was an interview question:
Given an amount, say $167.37 find all the possible ways of generating the change for this amount using the denominations available in the currency?
Anyone who could think of a space and time efficient algorithm and supporting code, please share.
Here is the code that i wrote (working) . I am trying to find the running time of this, any help is appreciated
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.Map;
public class change_generation {
/**
* #param args
*/
public static void generatechange(float amount,LinkedList<Float> denominations,HashMap<Float,Integer> useddenominations)
{
if(amount<0)
return;
if(amount==0)
{
Iterator<Float> it = useddenominations.keySet().iterator();
while(it.hasNext())
{
Float val = it.next();
System.out.println(val +" :: "+useddenominations.get(val));
}
System.out.println("**************************************");
return;
}
for(Float denom : denominations)
{
if(amount-denom < 0)
continue;
if(useddenominations.get(denom)== null)
useddenominations.put(denom, 0);
useddenominations.put(denom, useddenominations.get(denom)+1);
generatechange(amount-denom, denominations, useddenominations);
useddenominations.put(denom, useddenominations.get(denom)-1);
}
}
public static void main(String[] args) {
// TODO Auto-generated method stub
float amount = 2.0f;
float nikle=0.5f;
float dollar=1.0f;
float ddollar=2.0f;
LinkedList<Float> denominations = new LinkedList<Float>();
denominations.add(ddollar);
denominations.add(dollar);
denominations.add(nikle);
HashMap<Float,Integer> useddenominations = new HashMap<Float,Integer>();
generatechange(amount, denominations, useddenominations);
}
}
EDIT
This is a specific example of the combination / subset problem, answered here.
Finding all possible combinations of numbers to reach a given sum
--- I am retaining my answer below (as it was usefull to someone), however, admittedly, it is not a direct answer to this question ---
ORIGINAL ANSWER
The most common solution is dynamic programming :
First, you find the simplest way to make change of 1, then you use that solution to make change for 2, 3, 4, 5, 6, etc.... At each iteration, you "check" if you can go "backwards" and decrease the amount of coins in your answer. For example, up to "4" you must add pennies. But, once you get to "5", you can remove all pennies, and your solution has only one coin required : the nickel. But then, until 9, you again must add pennies, etc etc etc.
However, the dynamic programming methodology is not gauranteed to be fast.
Alternatively, you can use a greedy method, where you continually pick the largest coin possible. This is extremely fast , but doesnt always give you an optimal solution. However, if your coins are 1 5 10 and 25 , Greedy works perfectly, and is much faster then the linear programming method.
Memoization (kind of) is your friend here. A simple implementation in C:
unsigned int findRes(int n)
{
//Setup array, etc.
//Only one way to make zero... no coins.
results[0] = 1;
for(i=0; i<number_of_coins; i++)
{
for(j=coins[i]; j<=n; j++)
{
results[j] += results[j - coins[i]];
}
}
return results[n];
}
So, what we're really doing here is saying:
1) Our only possible way to make 0 coins is 0 (this is our base case)
2) If we are trying to calculate value m, then let's check each coin k. As long as k <= m, we can use that coin k in a solution
3) Well, if we can use k in a solution, then couldn't we just take the solution for (m-k) and add it to our current total?
I'd try to model this in real life.
If you were at the till and you knew you had to find $167.37 you would probably initially consider $200 as the "simplest" tender, being just two notes. Then, if I had it, I may consider $170, i.e. $100, $50 and $20 (three notes). See where I am going?
More formally, try to over-tender with the minimum number of notes/coins. This would be much easier to enumerate than the full set of possibilities.
Don't use floats, even tiniest inaccuracies will destroy your algorithm.
Go from biggest to lowest coin/banknote. For every possible amount call the function recursively. When there are no more coins left pay the rest in ones and print the solution. This is how it looks in pseudo-C:
#define N 14
int coinValue[N]={20000,10000,5000,2000,1000,500,200,100,50,20,10,5,2,1};
int coinCount[N];
void f(int toSpend, int i)
{
if(coinValue[i]>1)
{
for(coinCount[i]=0;coinCount[i]*coinValue[i]<=toSpend;coinCount[i]++)
{
f(toSpend-coinCount[i]*coinValue[i],i+1);
}
}
else
{
coinCount[i]=toSpend;
print(coinCount);
}
}
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.Map;
public class change_generation {
static int jj=1;
public static void generatechange(float amount,LinkedList<Float> denominations,
HashMap<Float,Integer> useddenominations) {
if(amount<0)
return;
if(amount==0) {
Iterator<Float> it = useddenominations.keySet().iterator();
while(it.hasNext()) {
Float val = it.next();
System.out.println(val +" :: "+useddenominations.get(val));
}
System.out.println("**************************************");
return;
}
for(Float denom : denominations) {
if(amount-denom < 0)
continue;
if(useddenominations.get(denom)== null)
useddenominations.put(denom, 0);
useddenominations.put(denom, useddenominations.get(denom)+1);
generatechange(amount-denom, denominations, useddenominations);
useddenominations.put(denom, useddenominations.get(denom)-1);
}
}
public static void main(String[] args) {
float amount = 2.0f;
float nikle=0.25f;
float dollar=1.0f;
float ddollar=2.0f;
LinkedList<Float> denominations = new LinkedList<Float>();
denominations.add(ddollar);
denominations.add(dollar);
denominations.add(nikle);
HashMap<Float,Integer> useddenominations = new HashMap<Float,Integer>();
generatechange(amount, denominations, useddenominations);
}
}

Categories

Resources