I had some code that calculates powers, by calling square, cube and hypercube methods. Currently the cube method calls the square method in the program, and then the hypercube method calls the cube method. I want to replace the calls to cube and hypercube with calls to the power method, but I'm completely stuck.
Here's the original code which worked.
public int square( int x ){
int i = ( x*x );
return i;
}
public int cube( int x ){
int i = (x * square(x) );
return i;
}
public int hypercube( int x ){
int i = (x * cube(x) );
return i;
}
public int power(int x, int n){
int k;
if (n==2){
k = square(x);
}
else if (n==3){
k = cube(x);
}
else if (n==4){
k = hypercube(x);
}
else if (n==1){
k = x;
}
else {
k = 1;
for (int i = 0; i < n; i++) {
k *= x;
}
}
return k;
}
Now like I said I want to replace the calls in the cube and hypercube methods with calls to the power method, then I still have calls to square, cube etc in the power method. So I want to remove calls to these methods entirely since I no longer need them. Its really bugging me.
This is what I have so far but its giving me StackOverFlowError.
public int square( int x, int n ){
int i = power( x, n );
return i;
}
public int cube( int x, int n ){
int i = power(x , n );
return i;
}
public int hypercube( int x, int n ){
int i = power(x , n );
return i;
}
public int power(int x, int n){
int k;
if (n==2){
k = square(x, n);
}
else if (n==3){
k = cube(x, n);
}
else if (n==4){
k = hypercube(x, n);
}
else if (n==1){
k = x;
}
else {
k = 1;
for (int j = 0; j < n; j++) {
k *= x;
}
}
return k;
}
First off, as you've recognized this is a very bad way of going about things. So anybody else reading this, apart from the usual call to avoid reinventing the wheel (unless it's for educational purposes) don't implement your exponentiation methods this way!
That being said, the reason you're getting a stack overflow (so appropriate) is that you have a circular definition. The simplest way to see this is trying to track down how power works by hand. Let's say I want to run power(3, 2). What happens? Well power(3, 2) recognizes this as an instance of n == 2 and so goes to the square method. However, the square method relies on the power method to get things done and then you repeat ad infinitum. Hence you get function calls piling up on your stack until you run out of space.
P.S. Incidentally, if you are looking at implementing integer exponentiation for personal edification, you might want to look into repeated squaring. It makes your code much faster (a logarithmic number of multiplication operations as opposed to a linear number).
It looks to me that there is an infinite cycle going on here.
If n=2, then power calls sqaure which in turn calls power and n doesn't change either.
You get StackOverFlowError usually when you deal with infinities.
power(x,n) must be independent of cube or square if you want to get rid of those.
Related
I need to write some methods for a game in java and one of them is int[] findStone. The method returns an array, which gives the coordinate of the element that I am searching.
The field looks like this and is defined like this: private static int[][] gamefield = new int[8][6];
So if I use the method: findStone(3)[0], it should return 0 for the x coordinate and for findStone(3)1, 2. This is the code that I wrote.
private static int[] findStone(int stone) {
int[] position = new int[2];
for(int x = 0; x < 8; x++ ){
for(int y = 0; y < 6; y++ ) {
int a = gamefield[x][y];
int i = x;
int j = y;
if(a == stone) {
position[0] = i;
position[1] = j;
}
break;
}
}
return position;
}
The problem is: The method only returns the x-coordinates for the first row corectly, for the other elements it shows me 0. Could someone explain me what I did wrong and what I should change? Please, only simple explanation. I am only at the beginning and I don't have experience in java.
Thank you :)
You probably intended to put your break clause inside the if block. The way you have it now, the break keyword has no effect. It just breaks the inner loop (with y variable), but since this block of code ends here anyway, it simply does nothing.
You're searching for a single point on your map, so when you find the stone position, you can immediately return it, as there's nothing more to do.
Moreover, you don't need additional variables, a, i and j. Using them is not wrong, but code looks clearer and is more concise without them. Have a look at this code:
private static int[] findStone(int stone) {
int[] position = new int[2];
for (int x = 0; x < 8; x++) {
for (int y = 0; y < 6; y++) {
if (gamefield[x][y] == stone) {
position[0] = x;
position[1] = y;
return position;
}
}
}
return null; // if there's no given stone
}
During a 45 minute technical interview with Google, I was asked a Leaper Graph problem.
I wrote working code, but later was declined the job offer because I lacked Data structure knowledge. I'm wondering what I could have done better.
The problem was as following:
"Given an N sized board, and told that a piece can jump i positions horizontally (left or right) and j positions vertically (up or down) (I.e, sort of like a horse in chess), can the leaper reach every spot on the board?"
I wrote the following algorithm. It recursively finds out if every position on the board is reachable by marking all spots on the graph that were visited. If it was not reachable, then at least one field was false and the function would return false.
static boolean reachable(int i, int j, int n) {
boolean grid[][] = new boolean[n][n];
reachableHelper(0, 0, grid, i, j, n - 1);
for (int x = 0; x < n; x++) {
for (int y = 0; y < n; y++) {
if (!grid[x][y]) {
return false;
}
}
}
return true;
}
static void reachableHelper(int x, int y, boolean[][] grid, int i, int j, int max) {
if (x > max || y > max || x < 0 || y < 0 || grid[x][y]) {
return;
}
grid[x][y] = true;
int i2 = i;
int j2 = j;
for (int a = 0; a < 2; a++) {
for (int b = 0; b < 2; b++) {
reachableHelper(x + i2, y + j2, grid, i, j, max);
reachableHelper(x + j2, y + i2, grid, i, j, max);
i2 = -i2;
}
j2 = -j2;
}
}
Now, later it was pointed out that the optimal solution would be to implement Donald Knuth's co-prime implementation:
http://arxiv.org/pdf/math/9411240v1.pdf
Is this something that one should be able to figure out on a 45 minute technical interview??
Besides the above, is there anything I could have done better?
edit:
- I enquired about starting position. I was told starting at 0,0 is fine.
edit2
Based on feedback, I wrote a while-loop with queue approach.
The recursive approach runs into a stack-overflow when n = 85.
However, the while loop with queue method below works up to ~n = 30,000. (after that it runs into heap-issues with memory exceeding GB's). If you know how to optimize further, please let me know.
static boolean isReachableLoop(int i, int j, int n) {
boolean [][] grid = new boolean [n][n];
LinkedList<Point> queue = new LinkedList<Point>();
queue.add(new Point(0,0)); // starting position.
int nodesVisited = 0;
while (queue.size() != 0) {
Point pos = queue.removeFirst();
if (pos.x >= 0 && pos.y >= 0 && pos.x < n && pos.y < n) {
if (!grid[pos.x][pos.y]) {
grid[pos.x][pos.y] = true;
nodesVisited++;
int i2 = i;
int j2 = j;
for (int a = 0; a < 2; a++) {
for (int b = 0; b < 2; b++) {
queue.add(new Point(pos.x+i2, pos.y+j2));
queue.add(new Point(pos.x+j2, pos.y+i2));
i2 = -i2;
}
j2 = -j2;
}
}
}
}
if (nodesVisited == (n * n)) {
return true;
} else {
return false;
}
}
I ask a lot of interview questions like this. I don't think you would be expected to figure out the coprime method during the interview, but I would have docked you for using O(n^2) stack space -- especially since you passed all those parameters to each recursive call instead of using an object.
I would have asked you about that, and expected you to come up with a BFS or DFS using a stack or queue on the heap. If you failed on that, I might have a complaint like "lacked data structure knowledge".
I would also have asked questions to make sure you knew what you were doing when you allocated that 2D array.
If you were really good, I would ask you if you can use the symmetry of the problem to reduce your search space. You really only have to search a J*J-sized grid (assuming J>=i).
It's important to remember that the interviewer isn't just looking at your answer. He's looking at the way you solve problems and what tools you have in your brain that you can bring to bear on a solution.
Edit: thinking about this some more, there are lots of incremental steps on the way to the coprime method that you might also come up with. Nobody will expect that, but it would be impressive!
I'm sorry, I feel like I'm missing something.
If you can only go up or down by i and left or right by j, then a case (x,y) is reachable from a start case (a,b) if there are integers m and n so that
a + m*i = x
b + n*j = y
That is, everything is false for a square board where n > 1.
If you meant more like a knight in chess, and you can go up/down by i and left/right by j OR up/down by j and left/right by i, you can use the same technique. It just becomes 2 equations to solve:
a + m * i + n * j = x
b + o * i + p * j = y
If there are no integers m, n, o and p that satisfy those equations, you can't reach that point.
I have to make a recursive method which takes a double x, and int n, and return x^n. Initially I was going to just going to have something like this
public static double power(double x, int n){
if(n < 1){
return 1;
}else{
double total = x;
for(int i = 0; i < n-1; i++){
total = x*x;
power(total,x);
}
}
But in the problem it says "a recursive definition of this operation is x^n = x · x^n−1." I'm pretty new to Java and this way seems like it wouldn't be recursive as I would simply do x*x^n-1. I'm pretty new to Java so maybe I'm just confused but I'm just looking for some clarification on how that would be relate to a recursive method.
This is the easiest way that i can find:
public static double power(double x, int n){
if(n < 1){
return 1;
}else{
return x * power(x, n-1);
}
}
This is a solution:
public static double power(double x, double n){
if(n <= 1)
return x;
return x*power(x,n-1);
}
By using a for loop you are not solving the problem recursively.
Here is an example how you would use a for loop and a recursive method to do the same thing:
for(int i = 0;i<10;i++) //for loop
{
System.out.print(i);
}
public void print(int i) // recursive, call this method like so: print(0);
{
if(i<10)
{
System.out.println(i);
print(++i);
}
}
both techniques will print out the same result:
0
1
2
3
4
5
6
7
8
9
So I need to take a 2D array do calculations to each elements and transfer that into another 2D array while using the values to the "left" "right" "up" and "down" of the current element. If the current element is on the edge (x = 0, y = 0, x = array.length , y = array.length) I will get an array out of bounds error. I want to create a for loop that deals with each of those cases but I don't know how to do it. A sample of my code is
private void buildE(int[][] array, int y, int x)
{
int up = array[y - 1][x];
int down = array[y + 1][x];
int left = array[y][x - 1];
int right = array[y][x + 1];
if(up == 0){
buildETopRow(array);
}
E will be my new array. This method does not work because y does not equal 0, it just doesn't exist but I can't set ints to null either. In the case of an out of bounds error I need the element (up, down, left, or right) that is out of bounds to equal the current element. Is there a way I can still use a for loop for this or do I need to do something else?
If I read this correctly you want to effectively treat the difference of an element on the edge with an element off the edge as 0. If that's true I would write four methods right(), left(), up() and down(), with down() shown below as an example:
/*
* Return the difference between an element an the element below it
*/
public void down(int x, int y) {
if (y == array.length - 1) {
\\ on the bottom edge
return 0;
}
return array[y][x] - array[y + 1][x];
}
And inside your loop you'd calculate:
up(x,y) + down(x,y) + right(x,y) + left(x,y)
or whatever calculation it is you need to sum up.
The easiest way it to surround your array with a border region. So that your x dimension is really width+2.
import java.util.*;
import java.lang.*;
class Main
{
public static void main (String[] args) throws java.lang.Exception
{
int realWidth = 10;
int realHeight = 10;
int[][] in = new int[(realWidth+2)][(realHeight+2)];
int[][] out = new int[(realWidth+2)][(realHeight+2)];
for (int j = 1;j<realHeight+1;j++)
{
for (int i = 1;i<realWidth+1;i++)
{
int top = in[j-1][i];
int bottom = in[j+1][i];
int left= in[j][i-1];
int right = in[j][i+1];
out[j][i] = operation(top,bottom,left,right);
}
}
}
public static int operation (int top,int bottom,int left,int right)
{
return top+bottom+left+right;
}
}
I'm not totally sure what your question is, but (1) the usual structure for traversing a 2D array is to use nested for loops (one inside the other), and (2) when you want wrap-around counters (e.g. 2, 3, 0, 1, 2, ...) use the remainder operator %.
int numRows = theArray.length;
int numCols = theArray[0].length;
for (int i = 0; i < numRows; i++) {
for (int j = 0; j < numCols; j++) {
int right = theArray[(j+1) % numCols];
int down = theArray[(i+1) % numRows];
int left = theArray[(j+numCols-1) % numCols];
int up = theArray[(i+numRows-1) % numCols];
/* right, down, left, and up will be the elements to the right, down,
left, and up of the current element. Npw that you have them, you can
process them however you like and put them in the other array. */
}
}
What the remainder operator A%B does is sets A back to zero once it gets as large as B. Since B is the size of your array, that's exactly when it is too large and will cause an IndexOutOfBounds error. Note: That's not how % works but it's an ok way to think of what it does. To find out more about it you can google it, I found an ok explanation here.
I want a program that takes an int x as parameter and returns 2^x. The implementation is not allowed to use power of.
public int double2 (int x) {
int r = 2;
int y = 1;
for (int i=0; i < x; i++){
y = r* y;
}
return y;
}
Do you think this is a right solution?
The solution you posted using the for loop produces the right result, but you should look into a more efficient solution (bit shifting) as Adamski first mentioned.
How about this:
int power = someNumberHere;
int result = 1;
while (power-- > 0) result *= 2;
And I think that is what you want...I think. Are you trying to find a power of two? Maybe expand the question, scope and reasons behind what you want a little.
y = x*x;
or
y = x*2;
or
y = 42; // ;)
Depending in what do you mean by the "double of 2".
EDIT
naive implementation
public int 2powerOf( int n ) {
int r = 2;
for( int i = 1 ; i < n ; i++ ) {
r = r * 2;
}
return r;
}
It is almost as the one you posted, this might not handle negative values though.
If you want to know if yours works, then run it and find out for your self.
Just in case if you need such kind of explanatory code (it's in C though).
#include <stdio.h>
int main(void)
{
int base, power, index;
long answer;
base = 0;
power = 0;
answer = 1.00;
printf(" Enter a base number: ");
scanf("%d", &base);
printf(" Enter a power to raise the base to: ");
scanf("%d", &power);
for(index = 1; index <= power; index++)
answer = answer * base;
printf("%d raised to the power of %d is %ld.", base, power, answer);
getchar();
getchar();
return 0;
}
Does your implementation passes the following JUnit test?
import junit.framework.TestCase;
public class YourClassTest extends TestCase {
private YourClass sut = new YourClass();
public void testPowersOfTwo() {
assertEquals(1, sut.double2(0));
assertEquals(2, sut.double2(1));
assertEquals(4, sut.double2(2));
assertEquals(8, sut.double2(3));
assertEquals(16, sut.double2(4));
}
}
If it does, it is a working solution (but maybe not optimal).