-
-
Notifications
You must be signed in to change notification settings - Fork 691
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
7edff84
commit 3f5c931
Showing
9 changed files
with
262 additions
and
163 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
24 changes: 24 additions & 0 deletions
24
exercises/practice/two-bucket/.meta/src/reference/java/Result.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
final class Result { | ||
|
||
private final int totalMoves; | ||
private final String finalBucket; | ||
private final int otherBucket; | ||
|
||
Result(int totalMoves, String finalBuckets, int otherBucket) { | ||
this.totalMoves = totalMoves; | ||
this.finalBucket = finalBuckets; | ||
this.otherBucket = otherBucket; | ||
} | ||
|
||
public int getTotalMoves() { | ||
return totalMoves; | ||
} | ||
|
||
public String getFinalBucket() { | ||
return finalBucket; | ||
} | ||
|
||
public int getOtherBucket() { | ||
return otherBucket; | ||
} | ||
} |
223 changes: 99 additions & 124 deletions
223
exercises/practice/two-bucket/.meta/src/reference/java/TwoBucket.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,149 +1,124 @@ | ||
import java.util.ArrayList; | ||
import java.util.Objects; | ||
import java.util.List; | ||
import java.util.Map; | ||
|
||
class TwoBucket { | ||
final class TwoBucket { | ||
|
||
private int totalMoves = Integer.MAX_VALUE; | ||
private String finalBucket = ""; | ||
private int otherBucket = Integer.MAX_VALUE; | ||
|
||
private class State { | ||
int moves; | ||
int bucketOne; | ||
int bucketTwo; | ||
|
||
State (int moves, int bucketOne, int bucketTwo) { | ||
this.moves = moves; | ||
this.bucketOne = bucketOne; | ||
this.bucketTwo = bucketTwo; | ||
} | ||
|
||
@Override | ||
public boolean equals(Object o) { | ||
State otherState = (State) o; | ||
return this.moves == otherState.moves && | ||
this.bucketOne == otherState.bucketOne && | ||
this.bucketTwo == otherState.bucketTwo; | ||
} | ||
|
||
@Override | ||
public int hashCode() { | ||
return Objects.hash(moves, bucketOne, bucketTwo); | ||
} | ||
} | ||
|
||
private State finalState; | ||
|
||
private int bucketOneCap; | ||
private int bucketTwoCap; | ||
private int desiredLiters; | ||
private String startBucket; | ||
private final List<Map.Entry<Integer, Integer>> statesReached = new ArrayList<>(); | ||
|
||
TwoBucket(int bucketOneCap, int bucketTwoCap, int desiredLiters, String startBucket) { | ||
this.bucketOneCap = bucketOneCap; | ||
this.bucketTwoCap = bucketTwoCap; | ||
this.desiredLiters = desiredLiters; | ||
this.startBucket = startBucket; | ||
|
||
finalState = computeFinalState(); | ||
checkIfImpossible(desiredLiters, bucketOneCap, bucketTwoCap); | ||
|
||
fillBuckets( | ||
startBucket.equals("one") ? bucketOneCap : 0, | ||
bucketOneCap, | ||
startBucket.equals("two") ? bucketTwoCap : 0, | ||
bucketTwoCap, | ||
desiredLiters, | ||
1, | ||
startBucket | ||
); | ||
} | ||
|
||
private ArrayList<State> getAdjacentStates (State state) { | ||
ArrayList<State> adjacentStates = new ArrayList<State>(); | ||
|
||
//Empty bucket one | ||
adjacentStates.add(new State(state.moves + 1, 0, state.bucketTwo)); | ||
|
||
//Empty bucket two | ||
adjacentStates.add(new State(state.moves + 1, state.bucketOne, 0)); | ||
|
||
//Fill bucket one | ||
adjacentStates.add(new State(state.moves + 1, bucketOneCap, state.bucketTwo)); | ||
|
||
//Fill bucket two | ||
adjacentStates.add(new State(state.moves + 1, state.bucketOne, bucketTwoCap)); | ||
|
||
//pour from bucket one to bucket two | ||
if (state.bucketOne + state.bucketTwo > bucketTwoCap) { | ||
adjacentStates.add(new State(state.moves + 1, | ||
state.bucketOne - (bucketTwoCap - state.bucketTwo), | ||
bucketTwoCap)); | ||
} else { | ||
adjacentStates.add(new State(state.moves + 1, 0, state.bucketOne + state.bucketTwo)); | ||
private void fillBuckets( | ||
int bucketOne, | ||
int bucketOneCap, | ||
int bucketTwo, | ||
int bucketTwoCap, | ||
int desiredLiters, | ||
int actionsTaken, | ||
String startingBucket | ||
) { | ||
if (startingBucket.equals("one") && bucketOne == 0 && bucketTwo == bucketTwoCap | ||
|| startingBucket.equals("two") && bucketTwo == 0 && bucketOne == bucketOneCap | ||
|| statesReached.contains(Map.entry(bucketOne, bucketTwo)) | ||
|| bucketOne > bucketOneCap | ||
|| bucketTwo > bucketTwoCap) { | ||
return; | ||
} | ||
|
||
//pour from bucket two to bucket one | ||
if (state.bucketTwo + state.bucketOne > bucketOneCap) { | ||
adjacentStates.add(new State(state.moves + 1, | ||
bucketOneCap, | ||
state.bucketTwo - (bucketOneCap - state.bucketOne))); | ||
} else { | ||
adjacentStates.add(new State(state.moves + 1, state.bucketTwo + state.bucketOne, 0)); | ||
if (bucketOne == desiredLiters) { | ||
if (actionsTaken < totalMoves) { | ||
this.totalMoves = actionsTaken; | ||
this.finalBucket = "one"; | ||
this.otherBucket = bucketTwo; | ||
} | ||
return; | ||
} | ||
|
||
return adjacentStates; | ||
} | ||
|
||
private boolean isValid(State state) { | ||
if (state.bucketOne == bucketOneCap && state.bucketTwo == 0 && startBucket.equals("two")) { | ||
return false; | ||
} else if (state.bucketOne == 0 && state.bucketTwo == bucketTwoCap && startBucket.equals("two")) { | ||
return false; | ||
} else { | ||
return true; | ||
if (bucketTwo == desiredLiters) { | ||
if (actionsTaken < totalMoves) { | ||
this.totalMoves = actionsTaken; | ||
this.finalBucket = "two"; | ||
this.otherBucket = bucketOne; | ||
} | ||
return; | ||
} | ||
} | ||
|
||
private State computeFinalState() { | ||
ArrayList<State> paths = new ArrayList<State>(); | ||
statesReached.add(Map.entry(bucketOne, bucketTwo)); | ||
|
||
State initialState; | ||
if (startBucket.equals("one")) { | ||
initialState = new State(1, bucketOneCap, 0); | ||
} else { | ||
initialState = new State(1, 0, bucketTwoCap); | ||
if (bucketOne != 0) { | ||
fillBuckets(0, bucketOneCap, bucketTwo, bucketTwoCap, desiredLiters, actionsTaken + 1, startingBucket); | ||
} | ||
|
||
if (initialState.bucketOne == desiredLiters || initialState.bucketTwo == desiredLiters) { | ||
return initialState; | ||
if (bucketTwo != 0) { | ||
fillBuckets(bucketOne, bucketOneCap, 0, bucketTwoCap, desiredLiters, actionsTaken + 1, startingBucket); | ||
} | ||
|
||
paths.add(initialState); | ||
|
||
for (int i = 0; i < 10000; i++) { | ||
State currentState = paths.remove(0); | ||
ArrayList<State> adjacentStates = getAdjacentStates(currentState); | ||
for (State state : adjacentStates) { | ||
if (state.bucketOne == desiredLiters || state.bucketTwo == desiredLiters) { | ||
return state; | ||
} | ||
|
||
if (!paths.contains(state) && isValid(state)) { | ||
paths.add(state); | ||
} | ||
} | ||
fillBuckets( | ||
bucketOneCap, bucketOneCap, bucketTwo, bucketTwoCap, desiredLiters, | ||
actionsTaken + 1, startingBucket | ||
); | ||
fillBuckets( | ||
bucketOne, bucketOneCap, bucketTwoCap, bucketTwoCap, desiredLiters, | ||
actionsTaken + 1, startingBucket | ||
); | ||
|
||
if (bucketOne + bucketTwo <= bucketTwoCap) { | ||
fillBuckets( | ||
0, bucketOneCap, bucketTwo + bucketOne, bucketTwoCap, desiredLiters, | ||
actionsTaken + 1, startingBucket | ||
); | ||
} else { | ||
fillBuckets( | ||
bucketOne + bucketTwo - bucketTwoCap, bucketOneCap, bucketTwoCap, bucketTwoCap, | ||
desiredLiters, actionsTaken + 1, startingBucket | ||
); | ||
} | ||
if (bucketOne + bucketTwo <= bucketOneCap) { | ||
fillBuckets( | ||
bucketOne + bucketTwo, bucketOneCap, 0, bucketTwoCap, desiredLiters, | ||
actionsTaken + 1, startingBucket | ||
); | ||
} else { | ||
fillBuckets( | ||
bucketOneCap, bucketOneCap, bucketTwo + bucketOne - bucketOneCap, bucketTwoCap, | ||
desiredLiters, actionsTaken + 1, startingBucket | ||
); | ||
} | ||
|
||
return null; | ||
} | ||
|
||
int getTotalMoves() { | ||
return finalState.moves; | ||
private void checkIfImpossible(int desiredLiters, int bucketOneCap, int bucketTwoCap) { | ||
boolean exceedsCapacity = desiredLiters > bucketOneCap && desiredLiters > bucketTwoCap; | ||
boolean invalidDivision = desiredLiters % gcd(bucketOneCap, bucketTwoCap) != 0; | ||
|
||
if (exceedsCapacity || invalidDivision) { | ||
throw new UnreachableGoalException(); | ||
} | ||
} | ||
|
||
String getFinalBucket() { | ||
if (finalState.bucketOne == desiredLiters) { | ||
return "one"; | ||
} else if (finalState.bucketTwo == desiredLiters) { | ||
return "two"; | ||
} else { | ||
return "No solution found in " + finalState.moves + " iterations!"; | ||
private int gcd(int a, int b) { | ||
while (b != 0) { | ||
int temp = b; | ||
b = a % b; | ||
a = temp; | ||
} | ||
return a; | ||
} | ||
|
||
int getOtherBucket() { | ||
if (getFinalBucket().equals("one")) { | ||
return finalState.bucketTwo; | ||
} else if (getFinalBucket().equals("two")) { | ||
return finalState.bucketOne; | ||
} else { | ||
return -1; | ||
} | ||
Result getResult() { | ||
return new Result(totalMoves, finalBucket, otherBucket); | ||
} | ||
} |
14 changes: 14 additions & 0 deletions
14
exercises/practice/two-bucket/.meta/src/reference/java/UnreachableGoalException.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
public class UnreachableGoalException extends RuntimeException { | ||
|
||
public UnreachableGoalException() { | ||
super(); | ||
} | ||
|
||
public UnreachableGoalException(String message) { | ||
super(message); | ||
} | ||
|
||
public UnreachableGoalException(String message, Throwable cause) { | ||
super(message, cause); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
final class Result { | ||
|
||
private final int totalMoves; | ||
private final String finalBucket; | ||
private final int otherBucket; | ||
|
||
Result(int totalMoves, String finalBuckets, int otherBucket) { | ||
this.totalMoves = totalMoves; | ||
this.finalBucket = finalBuckets; | ||
this.otherBucket = otherBucket; | ||
} | ||
|
||
public int getTotalMoves() { | ||
return totalMoves; | ||
} | ||
|
||
public String getFinalBucket() { | ||
return finalBucket; | ||
} | ||
|
||
public int getOtherBucket() { | ||
return otherBucket; | ||
} | ||
} |
14 changes: 4 additions & 10 deletions
14
exercises/practice/two-bucket/src/main/java/TwoBucket.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,17 +1,11 @@ | ||
class TwoBucket { | ||
|
||
TwoBucket(int bucketOneCap, int bucketTwoCap, int desiredLiters, String startBucket) { | ||
throw new UnsupportedOperationException("Please implement the TwoBucket(int, int, int, String) constructor."); | ||
} | ||
|
||
int getTotalMoves() { | ||
throw new UnsupportedOperationException("Please implement the TwoBucket.getTotalMoves() method."); | ||
} | ||
|
||
String getFinalBucket() { | ||
throw new UnsupportedOperationException("Please implement the TwoBucket.getFinalBucket() method."); | ||
} | ||
|
||
int getOtherBucket() { | ||
throw new UnsupportedOperationException("Please implement the TwoBucket.getOtherBucket() method."); | ||
Result getResult() { | ||
throw new UnsupportedOperationException("Please implement the TwoBucket(int, int, int, String) constructor."); | ||
} | ||
|
||
} |
Oops, something went wrong.