improve recursion for calculating remainder - java

I had to write a code to calculate the remainder using a certain way. I know that there are better ways to do it but that's how I have to proceed.
The if (rem(x - 1, y) + 1 == y) is making extra calls. As it enters there every time before getting to the last return, but it is an important step for my algorithm. I was wondering if there was any way to avoid it.
Also, I know that I have to check if y == 0; I am just trying to improve the performance for now.
Thanks
int rem(int x, int y)
{
if (x == 0)
{
return 0;
}
if (rem(x - 1, y) + 1 == y)
{
return 0;
}
return rem((x - 1), y) + 1;
}
I get 9 recursive calls for rem(3/2)

Sure, this is how you can make it much better.
int rem(int x, int y) {
if (x == 0) {
return 0;
}
int ret = rem(x - 1, y);
if (ret + 1 == y) {
return 0;
}
return ret + 1;
}
We can just call the function once and store its output in a variable.

Yeah sure, In java you do this in following way:
public static void main(String args[]) {
int remainder = remainder(3,2);
System.out.println(remainder);
}
static int remainder(int n1, int n2) {
int x;
x = n1;
if (x >= n2) {
x = x - n2;
remainder(x, n2);
}
return x;
}
Note: I've not added condition to check 0 in the code.
Hope this helps.

Related

Finding if a number is a power of another number recursivly

Consider this code
public static boolean isPower(int x, int n) {
if (x == 1)
return (n == 1);
int pow = 1;
while (pow < n)
pow = pow * x;
return (pow == n);
}
The goal is to find if the number x is a power of the number n.I've come up with this algorithm,and it works.I'd like to solve it recursivly as well.I read through the linked post someone put in the coments(https://softwareengineering.stackexchange.com/questions/279004/general-way-to-convert-a-loop-while-for-to-recursion-or-from-a-recursion-to-a)
I tried to replicate,or use the pattern that was provided in the answers.
First I tried to identify what my header,condition loop and tail was.
public static boolean isPower(int x, int n) {
if (x == 1)//header
return (n == 1);//header
int pow = 1;//header
while (pow < n)//condition
pow = pow * x;//loop
return (pow == n);//tail
}
Now I tried to apply the pattern;
public static boolean isPower_recursive(int x,int n) {
if(x == 1)
return (n==1);
return isPower_recursion( x, n, 1);
}
public static boolean isPower_recursion(int x,int n, int pow) {
if( 1 > n) {
return (pow == n);
}
pow = pow * x;
return isPower_recursion(x,n,pow);
}
This only works for the case when both x and n are one,in every other case I get a Stackoverflow error.The compiler says the error happens at the return statement in the isPower_recursive method,which leads me to think that i am not calculating this right.Some insight would be great.
I've solved the problem.I applied the patter wrong,it should look like this.
public static boolean isPower_recursive(int x,int n) {
if(x == 1)
return (n==1);
return isPower_recursion( x, n, 1);
}
public static boolean isPower_recursion(int x,int n, int pow) {
if( pow >= n) {
return (pow == n);
}
pow = pow * x;
return isPower_recursion(x,n,pow);
}

How to get all the neihbors neighbors of a point in a 2d array?

I am trying to get all the neighbors of a combination of simple one character strings in a 2d array. Meaning, my output looks like this currently in a 3x5:
A B C
D E F
A S D
F S A
G S A
So the neighbor of (1,0) should be = A B E S A .
Currently I have the following:
public void getNeighborsOfPoint(int x, int y) {
for (int xx = -1; xx <= 1; xx++) {
for (int yy = -1; yy <= 1; yy++) {
if (xx == 0 && yy == 0) {
continue; // You are not neighbor to yourself
}
if (Math.abs(xx) + Math.abs(yy) > 1) {
continue;
}
if (isOnMap(x + xx, y + yy)) {
System.out.println(grid[x+xx][y+yy]);
}
}
}
public boolean isOnMap(int x, int y) {
return x >= 0 && y >= 0 && x < length && y < width;
}
However it is only returning A E A in the example I provided.(it is not returning the ones cross-wise)
What is the right code to make it work? Note that the input will not always be 3 x 5. It may be a lot of different combination of x and y s.
The diagonals aren't included because of this code:
if (Math.abs(xx) + Math.abs(yy) > 1) {
continue;
}
When it's on the diagonal Math.abs(xx) == 1 && Math.abs(yy) == 1. So their sum will be greater than 1. You're skipping over the diagonals by having this code here.
The reason you're not getting the diagonals in your current group is that second if statement. You need to cover, for example, (2, 1) which is when xx is 1 and yy is 1. But abs(1) + abs(1) = 2 and 2 > 1, so you don't include it.
As a refactoring exercise, it might be a little cleaner if you have the inside of that for loop simplified to one conditional.
if (expression) {
continue
};
// other stuff
is equivalent to
if (!expression) {
// other stuff.
}
And for you, expression (in psuedocode) is not(xx=0 and yy=0) and isOnMap(xx, yy)
In a loop, the continue keyword means that you will skip to the next iteration of the loop. In your case, you have :
if (Math.abs(xx) + Math.abs(yy) > 1) {
continue;
}
if (isOnMap(x + xx, y + yy)) {
System.out.println(grid[x+xx][y+yy]);
}
So if the first condition is verified, you will not print any answer, meaning that your program won't consider A(xx, yy) to be a neighbord.
In your ABESA example, B and S are ignored because of this.
If you want to use 2d arrays with variable number of rows and columns you have to pass them as parameters in your's isOnMap method like below:
public static boolean isOnMap(int x, int y, int length, int width) {
return x >= 0 && y >= 0 && x < length && y < width;
}
You can handle the special cases of your 2d array (when one or both rownumber and columnnumber of your element are equal to 0) rewriting your getNeighborsOfPoint method in this way:
public static void getNeighborsOfPoint(int x, int y, char[][] grid) {
final int length = grid.length;
final int width = grid[0].length;
if (isOnMap(x, y, length, width)) {
for (int i = Math.max(0, x - 1); i < Math.min(length, x + 2); ++i) {
for (int j = Math.max(0, y - 1); j < Math.min(width, y + 2); ++j) {
if (i != x || j != y) {
System.out.println(grid[i][j]);
}
}
}
}
}

Print any exit path, from any arbitrary point to outside grid?

This question was asked in interview. Given grid 4X4, you are give some arbitrary point suppose point (2,2)(index starting from 0), from there you want to start, print one any path from there you can exit grid. You are allow to move LEFT, RIGHT, TOP, BOTTON. In following grid, 1 - represents block, 0 : you can move.
1 0 1 1
0 0 0 0
1 1 0 1
1 1 1 1
Exit path for above grid is, (2, 2)=> (1, 2) => (1, 1) => (0, 1)
I tried to solve this problem (below), through DFS, but I am not able find the solution how to print any one of Path, Following is printing all Path, I just want to print any Path.
public boolean isValidMove(Point point){
if(array[point.getX()][point.getY()]==0){
return true;
}
return false;
}
public void printTraversal(int [][] array, int M, int N, Point start){
boolean [] visited = boolean[M*N];
Arrays.fill(visited, false);
int index = start.getX()*M+ start.getY();
boolean[index] = true;
Stack<Point> stack = new Stack<Point>();
stack.push(start);
while(!stack.isEmpty()){
Point point = stack.pop();
System.out.println(point.getX()+", "+ point.getY());
int x = point.getX();
int y = point.getY();
if(isValidMove(x-1, y-1)){
stack.push(new Point(x-1, y-1));
}
if(isValidMove(x-1, y)){
stack.push(new Point(x-1, y));
}
if(isValidMove(x, y-1)){
stack.push(new Point(x, y-1));
}
if(isValidMove(x+1, y+1)){
stack.push(new Point(x+1, y+1));
}
}
}
class Point{
private int X;
private int Y;
public Point(int X, int Y){
this.X = X;
this.Y = Y;
}
public int getX(){
return this.X;
}
public int getY(){
return this.Y;
}
}
You need another utility function to check if current point is about to exit or not.
public boolean isExit(Point point, int M, int N) {
int x = Point.getX();
int y = point.getY();
return (x == 0 || y == 0 || x == M - 1 || y == N - 1);
}
And now in while loop, when you encounter a exit point, print and exit the loop. Also you need to correct the isValidMove and printTraversal function a bit.
public boolean isValidMove(Point point, int M, int N) {
int x = Point.getX();
int y = point.getY();
if(x >= 0 && y >= 0 && x < M && y < N && array[x][y] == 0 ) {
return true;
}
return false;
}
private int getIndx(Point p, int M) {
return p.getX() * M + p.getY();
}
public void printTraversal(int [][] array, int M, int N, Point start){
if(M == 0 || N == 0) {
return;
}
boolean [] visited = boolean[M * N];
Arrays.fill(visited, false);
visited[ getIndx(start, M) ] = true;
Stack<Point> stack = new Stack<Point>();
stack.push(start);
while(!stack.isEmpty()) {
Point point = stack.pop();
System.out.println(point.getX()+", "+ point.getY());
if(isExit(point, M, N))
break;
int x = point.getX();
int y = point.getY();
Point neigh = new Point(x-1, y-1);
if(isValidMove(x-1, y-1, M, N) && !visited[ getIndx(neigh, M) ]){
stack.push( neigh );
visited[ getIndx(neigh, M) ] = true;
}
// For other 3 sides
// .............
}
}

Find Number Of Square Roots Between Two Numbers

I have written this function for finding the number of Square Roots between two numbers (inclusive).
static int FindRoot(int no1, int no2) {
int res = 0;
for (int x = no1; x <= no2; x++) {
for (int y = 1; y <= no2; y++) {
if (y * y == x)
res++;
}
}
return res;
}
This will work fine, but I was thinking about it's performance.
Because in this case the inner For loop will execute from starting position(1), so it'll take time if someone passes a large number range to the method.
So, my question is:
Is there any other way i can find this with better performance?
P.S.- I can't use Math.sqrt() function
static int FindRoot(int no1, int no2) {
int res = 0;
int x = 0;
// Ignore squares less than no1
while(x*x < no1) {
x++;
}
// Count squares up to and including no2
while(x*x <= no2) {
res++;
x++;
}
return res;
}
You can get away with having a single for loop by getting rid of the outer loop
static int findRoot(int lo, int hi) {
int numRoots = 0;
for (int x = 0, x2 = 0; x2 <= hi; x++, x2 = x * x) {
if (x2 >= lo) {
numRoots++;
}
}
return numRoots;
}
here you effectively just do your inner loop once, incrementing numRoots when x2 (x-squared) is between lo and hi, and terminating the loop when x2 is greater than hi (instead of when x is greater than hi like in your code).
It'll work as well.
static int FindRoot2(int no1, int no2) {
int res = 0;
int inner=1;
for (int x = no1; x <= no2; x++) {
for (int y = inner; y <= no2; y++) {
if (y * y == x)
{
inner=y;
res++;
}
}
}
return res;
}
In this case inner loop will not start executing from 1.
There are many reasons why your current algorithm is ineffecient, but the biggest one is that the inner for loop is not necessary.
The idea behind the algorithm you're looking for, is to start at the lowest perfect square higher than or equal to no1, then go to the next perfect square and the next and the next, keeping track of how many you hit, until the perfect square you're on is higher than no2.
static int FindRoot(int no1, int no2) {
int res = 0;
int x = 1;
// This loop gets x to the first perfect square greater than
// or equal to no1
while( (x * x) < no1 ) {
x++;
}
// This loop adds 1 to res and increases x
// as long as x^2 is less than or equal to no2
for(; (x * x) <= no2; x++, res++) { }
return res;
}

Unable to create a proper method for a quadrant checker program

I'm not sure how to exactly use the the public static method with if/else statements that only return a character. The program is supposed to take x,y and return what quadrant the coordinates are located within. (A noob to java!)
import javax.swing.JOptionPane;
public class Assignment13 {
public static void main(String[] args) {
String userInputx,
userInputy;
double x, y, answer;
userInputx = JOptionPane.showInputDialog("Please enter your x coordinate.");
x = Double.parseDouble(userInputx);
userInputy = JOptionPane.showInputDialog("Please enter your y coordinate.");
y = Double.parseDouble(userInputy);
answer = MethodQuad.quadrant(x, y);
System.out.println("The coordinates " + x + y + "are located Quadrant " + answer);
}
}
class MethodQuad {
public static double quadrant(double x, double y) {
if (x > 0 && y > 0) {
return System.out.println("1");
} else if (x < 0 && y > 0) {
return System.out.println("2");
} else if (x < 0 && y < 0) {
return System.out.println("3");
} else if (x < 0 && y > 0) {
return System.out.println("4");
} else {
return System.out.println("0");
}
}
}
It work like in another programming language. If you wrote return value, you must return some value)
class MethodQuad {
public static int quadrant(double x, double y)
{
if(x > 0 && y > 0)
return 1;
else if(x < 0 && y > 0)
return 2;
else if(x < 0 && y < 0)
return 3;
else if (x<0 && y >0)
return 4;
else
return 0;
}
}
You're telling the method that it will return a double in its signature line:
public static double quadrant(double x, double y)
The compiler won't like this since the method is not in fact returning a double (nor should it). I suggest you change that line so that it knows it will return a String instead. You probably know how to do this, right?
Also, in your class, you're declaring answer to be a double variable which doesn't make logical sense:
double x,
y,
answer;
What variable type should answer be declared as?
Edit
You'll also want to post your assignment instructions so we can see exactly what you're supposed to be doing. You could potentially make answer an int and have the method return an int -- if that's what the teacher wanted. So let's see what they told you to do.

Categories

Resources