Trying to remove auxiliary counter variable from recursive method - java

Project Euler 15 (spoilers):
I solved this problem by realizing that it was a sequence of central binomial coefficients. Another good way is through dynamic programming. Nonetheless, it seemed so natural to do recursively, that I did it anyway.
Here's my solution:
public long getNumberOfPaths()
{
getPaths(board[0][0]); //2D array of Positions
return count; //instance member (long)
}
private void getPaths(Position p)
{
if (p.hasDown())
{
getPaths(p.getDown());
}
if (p.hasRight())
{
getPaths(p.getRight());
}
if ((p.getRow() == board.length - 1) && (p.getColumn() == board.length -1))
{
count++;
}
}
NB: Size of board is: 1 + inputSize, so in this case it would be 21, since we have a 20x20 grid. This is because solving the above 2x2 problem is equivalent to solving the 3x3 problem, but going through the squares instead of traveling on their borders.
The logic of getPaths(Position p) is: go down for as long as you can, then go right for as long as you can. Once you hit the bottom right Position, add 1 to number of paths (count), go back to where you last stepped down and now instead of going down, go right instead (if you can't go right, backtrack again, etc). Repeat process. Of course, the recursion itself is keeping track of all of this. If it's not clear, or if anyone want to screw with working code, there are two, small, classes here. Adding a few print statements to getPaths(Position p) should make what's going on pretty obvious.
Anyway, this all works properly, my question is how to implement this without using count. Again, as I stated above, I know that there are better ways to solve this problem, that's not my issue. My issue is trying to get the same functionality as above, but without using an auxiliary variable. This would mean changing getPaths(Position p) from void to making it return a long. It may be a simple fix, but I'm just not seeing it right now. Thanks in advance.
Essentially I want the recursive calls them selves to keep track of the count, not any sort of actual counter.

I believe this should work
private long getPaths(Position p) {
return (p.hasDown() ? getPaths(p.getDown()) : 0) +
(p.hasRight() ? getPaths(p.getRight()) : 0) +
((p.getRow() == board.length - 1) && (p.getColumn() == board.length -1) ? 1 : 0);
}

Without using the auxiliary variable:
public long getNumberOfPaths()
{
return getPaths(new Position(0,0)); //2D array of Positions
}
private long getPaths(Position p)
{
long result= 0;
if (p.hasDown())
{
result+= getPaths(p.getDown());
}
if (p.hasRight())
{
result+= getPaths(p.getRight());
}
if ((p.getRow() == board.length - 1) && (p.getColumn() == board.length -1))
{
result+= 1;
}
return result;
}
Try this then:
private long getPaths(Position p)
{
return (p.hasDown() ? getPaths(p.getDown()) : 0) +
(p.hasRight() ? getPaths(p.getRight()) : 0) +
((p.getRow() == board.length - 1) &&
(p.getColumn() == board.length -1) ? 1 : 0);
}

You could simply change your method signature to keep count as a parameter:
private long getPaths(Position p, long count) {
if (p.hasDown()) {
getPaths(p.getDown(), count);
}
if (p.hasRight()) {
getPaths(p.getRight(), count);
}
if ((p.getRow() == board.length - 1) && (p.getColumn() == board.length - 1)) {
count++;
}
return count;
}

Related

Is there a more elegant way to search the station index?

I work on a genetic algorithm for a robotic assembly line balancing problem (assigning assembly operations and robots to stations to minimize the cycle time for a given number of stations). The solution is represented by an ArrayList (configuration) which holds all the operations in the sequence assigned to different stations. Furthermore, I have two more ArrayLists (robotAssignment, operationPartition) which indicate where a new station starts and which robot is assigned to a station. For example, a solution candidate looks like this (configuration, robotAssignment, operationPartition from top to bottom):
Initial cycle time: 50.0
|2|7|3|9|1|5|4|6|8|10|
|2|1|3|2|
|0|2|5|7|
From this solution representation we know that operations 3, 9, and 1 are assigned to the second sation and robot 1 is used.
I need to keep track of the station an operation is assigned to. I tried a lot to store this in the Object Operation itself but I always ended up in problems and therefore I want to write a method that gives me the stations index of an operation.
Here is what I have coded so far:
// Get the station of an operation
public int getStation(Operation operation) {
int stationIndex = 0;
int position = configuration.indexOf(operation);
for (int i = 0; i < GA_RALBP.numberOfStations ; i++ ) {
if (i < GA_RALBP.numberOfStations - 1 && operationPartition.get(i) != null) {
if (isBetween(position, (int) operationPartition.get(i), (int) operationPartition.get(i + 1))) {
return stationIndex + 1;
} else {
stationIndex++;
}
}
else if (i >= GA_RALBP.numberOfStations - 1 && operationPartition.get(i) != null) {
if (isBetween(position, (int) operationPartition.get(i), configurationSize())) {
return stationIndex + 1;
}
}
}
return -1;
}
// Check if value x is between values left and right including left
public static boolean isBetween(int x, int left, int right) {
if (left <= x && x < right ) {
return true;
}
else {
return false;
}
}
However, this does not seem to be (a) very elegant and (b) if I have to do this for a large number of operations the runtime could become a problem. Has anoyone an idea how to solve this more efficiently?
Why not make the partitioning explicit (replaces your operationPartition) - something like:
Map<Integer, Integer> operationToStationMapping = new HashMap<>();
operationToStationMapping.put(2,0);
operationToStationMapping.put(7,0);
operationToStationMapping.put(3,2);
operationToStationMapping.put(9,2);
operationToStationMapping.put(1,2);
operationToStationMapping.put(5,5);
operationToStationMapping.put(6,7);
operationToStationMapping.put(8,-1);
operationToStationMapping.put(10,-1);
Then getStation() becomes:
getStation(int operation) {return operationToStationMapping.get(operation);}

A child is climbing up a staircase with n steps, and can hop either 1 step, 2 steps, or 3 steps (only once per session)

I have a school assignment and I dont know what to do.
Here is the question:
A child is climbing up a staircase with n steps, and can hop either 1 step, 2 steps, or 3 steps (only once per session) at a time. Implement a method to count how many possible ways the child can jump up the stairs
I know how to write a code with constant number of jumps' however don't know how to make that the 3 step jump made only once per session.
I have a boolean value which I must use and I don't get what.
static int climb3(int n, boolean can) {
if (n < 0)
return 0;
else if (n == 0)
return 1;
else if(can==false)
return climb3(n - 1,can) + climb3(n - 2,can) + climb3(n - 3,can);
}
How do I shut down climb 3 after one use to not count it?
Thanks!
Keep going. You are nearly there:
Hint: you need a final "branch: in your "if else if ..." chain to deal with the can == true case.
Hint 2: Assuming can == false means you can't make a 3 step jump, then you have the recursion incorrect for that case.
Solution: (not tested)
static int climb3(int n, boolean canMake3stepJump) {
if (n < 0) {
return 0;
} else if (n == 0) {
return 1;
} else if (canMake3stepJump) {
return climb3(n - 1, true) + climb3(n - 2, true) +
climb3(n - 3, false);
} else {
return climb3(n - 1, false) + climb3(n - 2, false);
}
}
I advise you to try to understand how the recursion works in the case where canMake3stepJump is true. It might help to write out the tree of recursive calls.

Non-recursive Merge Sort using Stacks

I'm currently working on an assignment where I am supposed to write mergeSort using stacks! I have a pretty good idea on how stacks and mergesort works, however I am not sure how to finish my code with stacks. I've set up a base case, and here I'm trying to use an in-place method where I just theoretically divide up my array without creating a new one by changing the markers. I am pretty new to this and unsure of how I should proceed..
I think this is the sort of thing I'm going for :
Base Case --> PC = 1
if (callStack.peek().PC == 1) {
if (callStack.peek().start == callStack.peek().stop) { //length <=1
callStack.pop(); //either done, or array length was 1
merge(A, callStack.peek().start, callStack.peek().mid, callStack.peek().stop);
if (callStack.empty()){
break;
}
callStack.peek().PC++;
} else {
callStack.peek().PC++;
}
continue;
}`
any left divided array --> PC = 2
any right divided array --> PC == 3
int mid = (callStack.peek().stop-callStack.peek().start)/2;
if (callStack.peek().PC == 2) {
if (callStack.peek().start != callStack.peek().stop) {
current = new ProgramFrame(callStack.peek().start, callStack.peek().mid, 1);
callStack.push(current);
continue;
}
}
if (callStack.peek().PC == 3) {
if (callStack.peek().start != callStack.peek().stop) {
current = new ProgramFrame(callStack.peek().mid+1, callStack.peek().stop, 1);
callStack.push(current);
continue;
}
}
the merged of both --> PC ==4
if (callStack.peek().PC == 4) {
merge(A, callStack.peek().start, callStack.peek().mid, callStack.peek().stop);
callStack.pop();
if (!callStack.empty()) {
if (callStack.peek().PC == 2) callStack.peek().start callStack.peek().mid; //help??
if (callStack.peek().PC == 3) callStack.peek().mid+1, callStack.peek().stop; //help??
callStack.peek().PC++;
continue;
I'm sorry this is such a long post :( I am just really unsure of how to fix it and how to continue it...
** also merge and my programeFrame look okay, but if you need to see them I can send them too!

Why isn't my if-else block ever getting hit, even though it should be? (Just need another pair of eyes.)

I am making a Falling Sand style game in Java, and I'm having weird issues with an if-else block that I have. In my doGravity() method, I have an various blocks of conditions that will cause different things to happen, and for some odd reason, one block is NEVER getting hit.
When I have this block count how many times each condition is hit, the left and right blocks are hit almost evenly:
else if(world[x][y+1]==EMPTY && (x-1 >= 0) && world[x-1][y+1] == EMPTY && (x+1 < world.length) && world[x+1][y+1]==EMPTY) {
int r = rand.nextInt(50);
if(r == 0) {
world[x-1][y+1] = world[x][y];
//System.out.println("GO: right");
countRight++;
}
else if(r == 1) {
world[x+1][y+1] = world[x][y];
//System.out.println("GO: left");
countLeft++;
}
else {
world[x][y+1] = world[x][y];
countCenter++;
}
world[x][y] = EMPTY;
}
Next comes this condition, which also equally distributes left and right.
else if((x-1 >= 0) && world[x-1][y+1] == EMPTY && (x+1 < world.length) && world[x+1][y+1]==EMPTY) {
if(rand.nextBoolean()) {
world[x-1][y+1] = world[x][y];
//countLeft++;
}
else {
world[x+1][y+1] = world[x][y];
//countRight++;
}
world[x][y] = EMPTY;
}
But when I count these blocks, the left block NEVER gets hit, even when the space to the left is open. I feel like its probably just some stupid typo that I can't see for some reason.
else if((x-1 >= 0) && world[x-1][y+1] == EMPTY) {
world[x-1][y+1] = world[x][y];
world[x][y] = EMPTY;
countLeft++;
System.out.println("Hit Left");
}
else if((x+1 < world.length) && world[x+1][y+1] == EMPTY) {
world[x+1][y+1] = world[x][y];
world[x][y] = EMPTY;
countRight++;
System.out.println("Hit Right");
}
UPDATE: If I remark out the left block at the end, absolutely nothing changes. The sand acts exactly the same. If I remark out the right block at the end, it acts the same as if I remark out both blocks. I cannot figure this out. It should work... but it doesn't.
UPDATE: Here's the full source code. I have no idea what this could possibly be. It will, in fact, drive me insane. http://pastebin.com/mXCbCvmb
Your pastebin code does show "Hit left", you just need to change the creation of world (line 65 pastebin) to
world = new Color[worldWidth][worldHeight+1];
Because of the y+1 part i would suppose. Other than that it grows both to the left and to the right.
EDIT: http://pastebin.com/GVmSzN4z I twiddled a little with your doGravity to make the drops a little more symmetric.
I dont see anything strange in the posted code... however the "else" at the beginning of the second block makes me think that probably the above condition is being executed in cases that insted you would like to be handled by the "left" case.
What is the condition in the if before that part?
EDIT
After checking your full source code I finally found where the problem is. Your doGravity update function always goes left->right and this introduces the asymmetry. By changing it so that the update direction is alternating between left->right and right->left for odd/even scanlines the asymmetry disappears.
private void doGravity() {
for(int i = worldHeight - 1; i >= 0; i--) {
if (i % 2 == 0)
{
for(int j = 0; j < worldWidth; j++) {
if(world[j][i] != EMPTY) {
if(hasGravity(world[j][i])) {
dropParticle(j, i);
}
}
}
}
else
{
for(int j = worldWidth-1; j >= 0; --j) {
if(world[j][i] != EMPTY) {
if(hasGravity(world[j][i])) {
dropParticle(j, i);
}
}
}
}
}
}
I downloaded your code from paste bin the first thing I did was extract this method and use it instead of all the embedded array cell checking so I could set a break point and see what the values for x and y and what the contents of that indexed cell was.
private boolean isEmpty(final int x, final int y)
{
return world[x][y] == EMPTY;
}
I would extract all the EMPTY checks to something more readable, such as isLeftEmpty(x,y) and isRightEmpty(x,y) and isNextLeftEmpty(x,y) it will help you reason about the correctness of your logic in your code.
I would also extract the (x + 1 < world.length) to isNextXOutsideWorld(x), this will help document your intentions and help with reasoning about the logic you intend as well.
This also has a side effect of simplifying the logic in the if/elseif/else statements.
I did some brief debugging and I let it run for a few minutes and came to the conclusion that the following line matches always and supersedes the next else if statement.
else if ((x + 1 < world.length) && isEmpty(x + 1, y + 1) &&
(x - 1 >= 0) && isEmpty(x - 1,y + 1))
is always true when I run it, so it never reaches the next statement
else if ((x - 1 >= 0) && isEmpty(x - 1,y + 1))
I would try and break each of the else/if statements out to method calls with descriptive names and just all them all in order using a Strategy pattern since they are all mutually exclusive. That large of a method is definitely a code smell, compounded with all those else/if blocks, the stinky factor is high.
It is very hard to extrapolate what your intended behavior is from all the noise in the if/elseif/else blocks.

tic tac toe using alpha beta prunning in java

I am trying to play tic tac toe using iterative Alpha-Beta prunning,
I have one second limit for a move but for some reason it
doesnt work well.
I modified the regular alpha-beta code so instead of returning
alpha or beta, it returns a state (which is the board with the next move)
Each time I create children I update their depth.
But again for some reason I keep losing and I see that
my alpha beta doesnt see the best move to make.
Here is my code:
The outer loop:
while (watch.get_ElapsedMilliseconds() < 900 && d <= board.length * board[0].length - 1)
{
s = maxiMin(beginSt, d, watch);
if (s.getNextMove().getIsWin() == true)
{
break;
}
d++;
}
return new location(s.getNextMove().getRow(), s.getNextMove().getCol());
The alpha beta:
public State maxiMin(State s, int depth, Stopwatch timer)
{
if (s.getDepth() == 7)
{
Console.WriteLine();
}
if (timer.get_ElapsedMilliseconds() > 850 || s.getDepth() == depth || goalTest(s.getBoard()) != 0)
{
s.evaluationFunc(line_length, PlayerShape);
s.setAlpha(s.getEvaluation());
s.setBeta(s.getEvaluation());
return s;
}
LinkedList<State> children = createChildren(s, true);
// No winner, the board is full
if (children.get_Count() == 0)
{
s.evaluationFunc(line_length, PlayerShape);
s.setAlpha(s.getEvaluation());
s.setBeta(s.getEvaluation());
return s;
}
while (children.get_Count() > 0)
{
State firstChild = children.get_First().get_Value();
children.RemoveFirst();
State tmp = miniMax(firstChild, depth, timer);
int value = tmp.getBeta();
if (value > s.getAlpha())
{
s.setAlpha(value);
s.setNextMove(tmp);
}
if (s.getAlpha() >= s.getBeta())
{
return s;
}
}
return s;
}
public State miniMax(State s, int depth, Stopwatch timer)
{
if (s.getDepth() == 7)
{
Console.WriteLine();
}
if (timer.get_ElapsedMilliseconds() > 850 || s.getDepth() == depth || goalTest(s.getBoard()) != 0)
{
s.evaluationFunc(line_length, PlayerShape);
s.setAlpha(s.getEvaluation());
s.setBeta(s.getEvaluation());
return s;
}
LinkedList<State> children = createChildren(s, false);
// No winner, the board is full
if (children.get_Count() == 0)
{
s.evaluationFunc(line_length, PlayerShape);
s.setAlpha(s.getEvaluation());
s.setBeta(s.getEvaluation());
return s;
}
while (children.get_Count() > 0)
{
State firstChild = children.get_First().get_Value();
children.RemoveFirst();
State tmp = maxiMin(firstChild, depth, timer);
int value = tmp.getAlpha();
if (value < s.getBeta())
{
s.setBeta(value);
s.setNextMove(tmp);
}
if (s.getAlpha() >= s.getBeta())
{
return s;
}
}
return s;
}
Would appriciate much if anyone can tell me if something is wrong. I suspect maybe
it something to do with that I am returning "s" instead of the regular alpha beta
which returns the evaluation but I didnt manage to find the error.
Thanks in advance,
Lena
Firstly tic-tac-toe is a very simple game, and I believe it is solvable with a much simpler code, mainly because we know there is always a tie option and the total number of states is less then 3^9 (including symmetrical and many impossible states).
As for your code I believe one of your problems is that you don't seem to increment your depth in the recursive calls.
you also have many issues of bad style in your code, you separated miniMax and MaxiMin into two functions though they are fundamentally the same. you iterate over a collection by removing elements from it as opposed to using for-each or an iterator(or even an int iterator).

Categories

Resources