Skip to content

Instantly share code, notes, and snippets.

@fsarradin
Created April 13, 2012 12:57
Show Gist options
  • Save fsarradin/2376724 to your computer and use it in GitHub Desktop.
Save fsarradin/2376724 to your computer and use it in GitHub Desktop.
Mastermind
package mmind;
import com.google.common.collect.AbstractIterator;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
public class Mmind {
private List<Integer> expected;
public Mmind(List<Integer> expected) {
this.expected = expected;
}
/* Mmind main methods */
public int getWellPlacedCount(List<Integer> proposition) {
Iterable<Boolean> booleans = zipWith(IS_EQUAL, expected, proposition);
return reduce(0, booleans, COUNT_TRUE);
}
public int getPresentCount(List<Integer> proposition) {
return reduce(0, proposition, countOnceIn(expected));
}
public int getMisPlacedCount(List<Integer> proposition) {
return getPresentCount(proposition) - getWellPlacedCount(proposition);
}
/* Mmind Utilities */
private static final Function2<Integer, Boolean, Integer> COUNT_TRUE = new Function2<Integer, Boolean, Integer>() {
@Override
public Integer apply(Integer count, Boolean isTrue) {
return isTrue ? count + 1 : count;
}
};
private static final Function2<Integer, Integer, Boolean> IS_EQUAL = new Function2<Integer, Integer, Boolean>() {
@Override
public Boolean apply(Integer input1, Integer input2) {
return input1.equals(input2);
}
};
private Function2<Integer, Integer, Integer> countOnceIn(final List<Integer> expected) {
return new Function2<Integer, Integer, Integer>() {
private List<Integer> listForCount = new ArrayList<Integer>(expected);
@Override
public Integer apply(Integer count, Integer value) {
if (listForCount.contains(value)) {
listForCount.remove(value);
return count + 1;
} else {
return count;
}
}
};
}
/* FP Utilities */
public interface Function2<T1, T2, R> {
R apply(T1 input1, T2 input2);
}
public static <T, R> R reduce(R init, Iterable<T> iterable, Function2<R, T, R> function) {
R result = init;
for (T element : iterable) {
result = function.apply(result, element);
}
return result;
}
public static <T1, T2, R> Iterable<R> zipWith(final Function2<T1, T2, R> function, final Iterable<T1> iterable1, final Iterable<T2> iterable2) {
return new Iterable<R>() {
@Override
public Iterator<R> iterator() {
return new AbstractIterator<R>() {
private Iterator<T1> iterator1 = iterable1.iterator();
private Iterator<T2> iterator2 = iterable2.iterator();
@Override
protected R computeNext() {
if (!(iterator1.hasNext() && iterator2.hasNext())) {
return endOfData();
}
return function.apply(iterator1.next(), iterator2.next());
}
};
}
};
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment