Mathematical induction of this Code? - java

I don't really understand how I use proof by induction on this Code.
I just wanna know how to prove the correctness of this code and algorithm.
Prove that we will never count items which already counted .
Algorithm for countCells(x,y)
if the cell at(x,y) is outside
the grid the result is 0;
else if
the color of the cell at (x, y) is not the abnormal color the result is 0;
else
set the color of the cell at (x, y) to a temporary
color; the result is 1 plus the number of cells in each piece of the
blob that includes a nearest neighbor;
public int countCells(int x, int y)
{
int result;
if(x<0 || x>=N || y<0 || y>=N) // N is the maximum value of the matrix
return 0;
else if(!getColor(x,y).equals(ABNORMAL)) //
return 0;
else
{
recolor(x, y, TEMPORARY);
return 1 + countCells(x-1, y+1) + countCells(x, y+1)
+ countCells(x+1, y+1) + countCells(x-1, y)
+ countCells(x+1, y) + countCells(x-1, y-1)
+ countCells(x, y-1) + countCells(x+1, y-1)
}
}
the following link show how this works
http://kin.naver.com/qna/detail.nhn?d1id=1&dirId=104&docId=186514818

Proof by induction
Prove for base case condition (n = 1)
Prove for all assumption step ( n = k )
Prove for inductive step + 1 (n = k + 1)
So call your function with a base for step 1, let k equal some other generic input, then do the input + 1.
Basically you want to test the edge cases of your functions to ensure that they work properly. Your teacher probably wants you to just write test conditions for the function above.

Related

How can I fix the error "This method must return a result of type int" without breaking the current code?

As far as I know, I understand this error. I know that within my program there is a situation where no conditions are met and the computer doesn't know what to do. That being said, I'm not sure how to fix it properly without breaking the current code. I've added a return 0 at the end of all the if statements, which gets rid of the error, but in some cases the 0 prints out which of course I don't want it to. I also tried putting it within an else statement at the very end as-well, but I still get the same error.
Assignment instructions are as follows: "If the two parameters are within 1 of each other, return the smaller number; Otherwise, subtract one from the larger parameter and add one to the smaller parameter and balance the result."
Here is what I have:
public static int balance (int x, int y) {
if(x == y) {
System.out.println("The values X and Y (" + x + " and " + y + ") are already balanced; They are equal to each other!");
}
else if(Math.abs(x-y) == 1) { //Checks to see if numbers are within 1 of each other (Math.abs because negative numbers don't matter in this case)
if(x > y) {
return y;
}
else return x;
}
else if(x > y) {
x = x - 1; //X is larger so we subtract
y = y + 1; //Y is smaller so we add
return balance(x,y); //Recursion happens
}
else if(x < y) {
y = y - 1; //Y is larger so we subtract
x = x + 1; //X is smaller so we add
return balance(x,y); //Recursion happens
}
}
The calculations and everything on that side seem to work exactly like the instructions are asking. I just can't seem to get rid of the "This method must return a result of type int" error without having random values that are unneeded showing up in the console.
You need to make two changes.
Decide what to return in the case where x == y, and add the appropriate return statement to the first branch.
Change else if (x < y) { to else {. You know that you've exhausted all the possibilities, but the compiler doesn't. This is a sure-fire way of telling the compiler that there's nowhere else to end up.
Unless you do these two things, the compiler believes there's a possibility that it could run out of lines to execute in the method, without encountering a return statement. That's not valid for a method that you've declared as returning an int.

Difficulty in writing a recursive solution to "Rat in a maze" problem

My question is essentially a doubt about recursion. I was solving the classic "Rat in a Maze" DFS traversal problem. My input was an n*n int array a[][] where for indices i and j, a[i][j] could either be 0 or 1. 0 meant the hypothetical rat couldn't visit the element and 1 meant it could. The rat could only go downwards("D") or rightwards("R"). The task was to output all movement Strings like RDRDRD that represented the rat's movement through the maze. The rat starts from a[0][0] and must reach a[n-1][n-1]. The input was the maze itself.
I wrote the following code
public boolean isSafe(int x, int y, int[][] a, int n)
{
if(x >= 0 && x < n && y >= 0 && y < n && a[x][y] == 1)
return true;
else
return false;
}
public ArrayList<String> printPath(int[][] a, int n)
{
ArrayList<String> res = new ArrayList<String>();
solve(0,0,new String(), res,a,n);
return res;
}
public void solve(int x, int y, String sol, ArrayList<String> res ,
int[][]a, int n)
{
if(x == n-1 && y == n-1)
{
res.add(sol);
return;
}
y++;
if(isSafe(x,y,a,n))
{
solve(x,y,sol + "R",res,a,n);
}
else
y--;
x++;
if(isSafe(x,y,a,n))
{
solve(x,y,sol+"D",res,a,n);
}
else
x--;
}`
where isSafe check whether a movement is permitted, printPath is a helper function for printing the output and solve is the recursive function used to traverse the maze.a represents the maze array as a 2-D array.
For the input
{1 0 0 0
1 1 0 1
0 1 0 0
0 1 1 1}
I get the following output
DRDDRR DDDRR
Obviously the second string represents an incorrect result.
However, when I changed the solve function like so
public void solve(int x, int y, String sol, ArrayList<String> res,
int[][]a, int n)
{
if(x == n-1 && y == n-1)
{
res.add(sol);
return;
}
if(!isSafe(x,y,a,n))
return;
solve(x+1,y,sol + "D",res,a,n);
solve(x,y+1,sol + "R",res,a,n);
return;
}
I get the correct output. What I am failing to understand is what resulted in the incorrect output in my previous solution, as to me the two solutions are logically similar.
I know it's a long read, but any insight would be greatly appreciated.
In the first solution the variable increment y++ is only undone if the call to isSafe with the incremented value comes back negative and is carried over to the check of x if it was true. This means that the down check on a field that has a valid neighbor to the right, in particular the field [1][0], will be performed with the incremented value of y instead of the correct one.
If you modify the first solution like this
y++;
if(isSafe(x,y,a,n)){
solve(x,y,sol + "R",res,a,n);
}
y--;
the first solution will work correctly as does the second one. In the second solution the increment is only done on the function argument, not a local variable.
A general advice is to not modify your input. And it is the case that your problem comes from just that. Here I modified your code so it doesn't do that. It's much more readable in my opinion and now you're sure of what x or y value you're using.:
if (isSafe(x, y + 1, a, n)) {
solve(x, y + 1, sol + "R", res, a, n);
}
if (isSafe(x + 1, y, a, n)) {
solve(x + 1, y, sol + "D", res, a, n);
}

What is wrong with my Java recursive function?

I'm trying to write a relatively straightforward recursive program in Java to compute all the possible ways to traverse a 4x4 matrix (not necessarily traveling through every spot), starting at the top left and ending in the bottom right spaces. I use a 2-D array to do this, marking off visited spaces with "1"s as I go.
It's been a while since I've worked recursively and I can't seem to get the output I expect. The output from the code below is "2" - obviously, the result should be much higher. I know there's something tiny I'm overlooking. Can someone tell me what it is?
public static void main(String[] args) {
int[][] matrix = new int[4][4];
int result = moveRobot(matrix, 0, 0);
System.out.print(result + "");
}
public static int moveRobot(int[][] matrix, int x, int y) {
if (x == 3 && y == 3) {
return 1;
} else if (x < 0 || y < 0 || x > 3 || y > 3) {
return 0;
} else if (matrix[x][y] == 1) {
return 0;
} else {
matrix[x][y] = 1;
return moveRobot(matrix, x, y+1) + moveRobot(matrix, x+1, y) + moveRobot(matrix, x, y-1) +
moveRobot(matrix, x-1, y);
}
}
The problem is that the matrix is not copied but passed by value of the reference to it. Every time you modify it such in matrix[x][y] = 1 other successive code paths will see the modification instead that working on an unmodified state.
For example here:
moveRobot(matrix, x, y+1) + moveRobot(matrix, x+1, y)
Entering the first call will modify matrix, so in second moveRobot call you'd end up with 1 in matrix[x][y+1] while that's not what you want.

Java - Recursive function of the Euclidean Algorithm

I can't seem to convert the following algorithm into Java successfully, please forgive the horrible picture quality but a question I'm working on asks:
I have tried to use the following code to represent the Euclidean Algorithm, but it doesn't seem to work. I don't really know how I would go about representing it in Java code. Any help?
public static int gcd(int x, int y) {
if (y == 0) {
return x;
} else if (x >= y && y > 0) {
return gcd(y, (x % y));
}
}
Thank you.
There is no arbitrary order between x and y.
Your code is not complete!
What if x < y? Your code does not return a value then!
What the book fails to mention is that the two parameters to the function do not necessarily need to be in descending order (ie x >= y). What you need to do is compute the gcd considering this fact.
Simply you can do the following:
public static int gcd ( int x , int y )
{
if ( y == 0 )
return x;
else if ( x >= y && y > 0)
return gcd ( y , x % y );
else return gcd ( y , x ); // if x < y then go ahead and switch them around.
}
You are almost there. You need to consider what happens when y > x, and return the result from the final else branch (hint: x and y can freely switch places).
You are almost there.
Your code does not compile, because there is no catch all clause that return from the function.
It really depends on whether you are going to pass negative values of y into this function. If you expect only positive values, just throw an exception.
public static int gcd(int x, int y) {
if (y == 0) {
return x;
} else if (x >= y && y > 0) {
return gcd(y, (x % y));
}
throw
new IllegalArgumentException(
String.format(
"Unexpected values for x(%d) and y(%d)",
Integer.valueOf( x ),
Integer.valueOf( y )
)
);
}
Here's what I have that accounts for negative numbers:
public static int gcd(int x, int y)
{
if (y == 0)
return x;
if (x < 0)
return gcd(x * -1, y); //turns the first parameter to a positive if it's initally negative
if (y < 0)
return gcd(x, y * -1); //turns the second parameter to a positive if it's initally negative
if (y <= x && x % y == 0)
return y;
return gcd(y, x%y);
}
Note with negative numbers, if you try to find the greatest common divisor, and either of the numbers is negative, you can just change it to a positive and the result would be the same.
If both of the numbers are negative, then I'm not sure what the gcd should be. 1? -1? idk so I left that out. The code I have just treats it as if they were both positive.

Clojure/Java Mandelbrot Fractal drawing

I am trying to port this algorithm to clojure.
My code is
(defn calc-iterations [x y]
(let [c (struct complex x y)]
(loop [z (struct complex 0 0)
iterations 0]
(if (and (< 2.0 (abs z))
(> max-iterations iterations))
iterations
(recur (add c (multiply z z)) (inc iterations))))))
Multiply, add and abs functions are working as they should. I have tested them with a calculator. However for the following values:
(calc-iterations 0.60703135 -0.33984375) ; should give me 2, instead I get 4
(calc-iterations -1.8421874 0.3515625 ) ; should give me 1, instead I get 3
I am checking the correct iteration numbers using another java applet that I have found on the net. it seems to be working since it produces correct output. Its iteration function is
protected int calcIterations( float x, float y ) {
int iterations = 0;
float xn = x, yn = y;
while ( iterations < MAX_ITERATIONS ) {
float xn1 = xn*xn - yn*yn;
float yn1 = 2*xn*yn;
xn = xn1 + x;
yn = yn1 + y;
float magsq = xn*xn + yn*yn;
if ( magsq > 4 )
break;
iterations++;
}
System.out.println( x + " " + y + " " + iterations );
return iterations;
}
Can anyone spot my error?
I've spotted two differences.
The Java implementation starts at z = (x, y) rather than yours which starts at (0, 0). As your recursive formula is z = z^2 + c, (0, 0)^2 + (x, y) = (x, y) so starting at (x, y) is the same as doing the first iteration. So the number of iterations will come out one less than yours because of this.
The Java implementation increments the number of iterations after checking whether the result, z, is within 2 units from the origin, and doesn't increment it otherwise, whereas yours increments iterations every time. The number of iterations will come out one less than yours because of this also.
So that probably accounts for the differences in your results.
I'd argue that your implementation is more correct, because it distinguishes between the cases where |z| > 2 after one iteration (i.e. where |(x,y)| > 2), and where |z| > 2 after two iterations (i.e. where |(x^2-y^2+x, 2xy+y)| > 2), whereas the Java implementation will perform its first iteration, giving (x^2-y^2+x, 2xy+y), and exit before incrementing the number of iterations, thus not distinguishing between that case.

Categories