Permalink
Browse files

Refactor our previous solution to use Java 8 and Functional concepts

  • Loading branch information...
randeepbydesign committed Sep 7, 2018
1 parent f8de9aa commit 63d79218996856317a371700b8b757c89d4f1fd4
@@ -1,59 +1,48 @@
package org.waterpouring;

import java.util.ArrayList;
import java.util.Arrays;

/**
* Defines a single action that can be taken to proceed in solving a water-pouring problem.
* One or more actions will combine to create the total solution if it can be solved.
*/
public class Action {
private Integer[] jugIndex;
private MoveType moveType;
private Integer[] state;
Integer[] jugIndex;
MoveType moveType;
ArrayList<Integer> endState;

/**
* Create an action
* @param state The state at the time immediately before taking this action
* @param JUGS The jugs, in gallon size, that we are working with
* @param startState The state at the time of taking this action
* @param moveType
* @param jugIndex The indices of the jugs we are working with. Depending on the move type this can
* be 1 or 2 values
* @return
*/
public Action(Integer[] state, MoveType moveType, Integer... jugIndex) {
this.jugIndex = jugIndex;
this.moveType = moveType;
this.state = state;
public static Action of(Integer[] JUGS, ArrayList<Integer> startState, MoveType moveType, Integer... jugIndex) {
return new Action(JUGS, startState, moveType, jugIndex);
}

public Integer[] getJugIndex() {
return jugIndex;
}

public void setJugIndex(Integer[] jugIndex) {
private Action(Integer[] JUGS, ArrayList<Integer> startState, MoveType moveType, Integer... jugIndex) {
this.jugIndex = jugIndex;
}

public MoveType getMoveType() {
return moveType;
}

public void setMoveType(MoveType moveType) {
this.moveType = moveType;
this.endState = moveType==null ?
startState : moveType.move.doMove(JUGS, startState, jugIndex);
}

public Integer[] getState() {
return state;
}

public void setState(Integer[] state) {
this.state = state;
public ArrayList<Integer> getEndState() {
return endState;
}

@Override
public String toString() {
return "Action{" +
"jugIndex=" + Arrays.toString(jugIndex) +
", moveType=" + moveType +
", state=" + Arrays.toString(state) +
", endState=" + endState +
'}';
}
}
@@ -1,5 +1,7 @@
package org.waterpouring;

import java.util.ArrayList;

/**
* A move describes some action taken on one or more jugs
*/
@@ -12,5 +14,5 @@
* @param jugIndex The indices of the various jugs to be operated on
* @return the new state of the jugs after performing the given move
*/
Integer[] doMove(final Integer[] JUGS, Integer[] state, Integer[] jugIndex);
ArrayList<Integer> doMove(final Integer[] JUGS, ArrayList<Integer> state, Integer[] jugIndex);
}
@@ -1,62 +1,55 @@
package org.waterpouring;


import java.util.ArrayList;
import java.util.Arrays;

/**
* An enumeration of all possible moves
*/
public enum MoveType {
/** Dump a jug out so that it is empty. Receives a single index parameter in its associated move */
EMPTY(new Move() {
@Override
public Integer[] doMove(Integer[] JUGS, Integer[] state, Integer[] jugIndex) {
assert jugIndex.length==1;
Integer[] ret = Arrays.copyOf(state, state.length);
ret[jugIndex[0]] = 0;
return ret;
}
}),
EMPTY((JUGS, state, jugIndex) -> {
ArrayList<Integer> ret = new ArrayList<>(state);
ret.set(jugIndex[0], 0);
return ret;
}),
/** Pour water into a jug up so that it is full. Receives a single index parameter in its move */
FILL(new Move() {
@Override
public Integer[] doMove(Integer[] JUGS, Integer[] state, Integer[] jugIndex) {
assert jugIndex.length==1;
Integer[] ret = Arrays.copyOf(state, state.length);
ret[jugIndex[0]] = JUGS[jugIndex[0]];
return ret;
}
}),
FILL((JUGS, state, jugIndex) -> {
assert jugIndex.length==1;
ArrayList<Integer> ret = new ArrayList<>(state);
ret.set(jugIndex[0], JUGS[jugIndex[0]]);
return ret;
}),
/** Pour the contents from one jug to another. Receives two index parameters: 0 = the from jug, 1 = the to jug */
POUR(new Move() {
@Override
public Integer[] doMove(Integer[] JUGS, Integer[] state, Integer[] jugIndex) {
assert jugIndex.length ==2;
Integer[] ret = Arrays.copyOf(state, state.length);

Integer fromJug = jugIndex[0];
Integer toJug = jugIndex[1];

if(fromJug==toJug) {
//Invalid move, cannot pour jug into itself
return state;
}

Integer amtPourable = state[fromJug] <= (JUGS[toJug] - state[toJug]) ?
state[fromJug] : (JUGS[toJug] - state[toJug]);
ret[fromJug] = ret[fromJug] - amtPourable;
ret[toJug] = ret[toJug] + amtPourable;
return ret;
POUR((JUGS, state, jugIndex) -> {
assert jugIndex.length ==2;

Integer fromJug = jugIndex[0];
Integer toJug = jugIndex[1];

if(fromJug==toJug) {
//Invalid move, cannot pour jug into itself
return state;
}
});

private final Move move;
ArrayList<Integer> ret = new ArrayList<>(state);

public Move getMove() {
return move;
}
Integer amtPourable = Math.min(state.get(fromJug), (JUGS[toJug] - state.get(toJug)));
ret.set(fromJug, ret.get(fromJug) - amtPourable);
ret.set(toJug, ret.get(toJug) + amtPourable);
return ret;
}, true);

public final Move move;
public final Boolean requiresTwoJugs;

MoveType(Move move) {
this(move, false);
}

MoveType(Move move, Boolean requiresTwoJugs) {
this.move = move;
this.requiresTwoJugs = requiresTwoJugs;
}
}
Oops, something went wrong.

0 comments on commit 63d7921

Please sign in to comment.