SolitaireBitSet.java [src/java/m/example/solitaire] Revision: Date:
package m.example.solitaire;
import csip.utils.CheckPointing;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.BitSet;
import java.util.List;
/**
*
* @author od
*/
public class SolitaireBitSet {
static final int FROM = 0;
static final int OVER = 1;
static final int TO = 2;
static final int[][] MOVES = new int[][]{
{0, 2, 5},
{0, 1, 3},
{1, 4, 8},
{1, 3, 6},
{2, 5, 9},
{2, 4, 7},
{3, 1, 0},
{3, 4, 5},
{3, 7, 12},
{3, 6, 10},
{4, 8, 13},
{4, 7, 11},
{5, 9, 14},
{5, 8, 12},
{5, 4, 3},
{5, 2, 0},
{6, 3, 1},
{6, 7, 8},
{7, 4, 2},
{7, 8, 9},
{8, 7, 6},
{8, 4, 1},
{9, 8, 7},
{9, 5, 2},
{10, 6, 3},
{10, 11, 12},
{11, 7, 4},
{11, 12, 13},
{12, 8, 5},
{12, 13, 14},
{12, 11, 10},
{12, 7, 3},
{13, 12, 11},
{13, 8, 4},
{14, 13, 12},
{14, 9, 5}
};
static void init() {
boards = 0;
solutions = new int[15];
}
static int boards = 0;
static int[] solutions = new int[15];
static class Board {
BitSet board;
int from;
int to;
Board prev;
Board(BitSet board, int from, int to, Board prev) {
this.board = board;
this.from = from;
this.to = to;
this.prev = prev;
boards++;
}
Board jump(int from, int over, int to) {
if (board.get(from) && board.get(over) && !board.get(to)) {
BitSet b = (BitSet) board.clone();
b.set(from, false);
b.set(over, false);
b.set(to, true);
return new Board(b, from, to, this);
}
return null;
}
List<Board> allJumps() {
List<Board> bs = new ArrayList<>();
Board b;
for (int[] mv : MOVES) {
if ((b = jump(mv[FROM], mv[OVER], mv[TO])) != null)
bs.add(b);
}
return bs;
}
int getCount() {
return (int) board.stream().count();
}
@Override
public String toString() {
return new StringBuffer().append(from)
.append('\u2192').append(to).toString();
}
}
static void solve(Board b) {
List<Board> moves = b.allJumps();
if (moves.isEmpty()) {
// no more moves
// if (b.getCount() == 1)
// System.out.println(allMoves(b));
solutions[b.getCount()]++;
return;
}
for (Board board : moves) {
solve(board);
}
}
static StringBuffer allMoves(Board b) {
if (b.prev == null)
return new StringBuffer();
return allMoves(b.prev).append(b).append(", ");
}
// layout
//
// x
// x x
// x _ x
// x x x x
// x x x x x
//
// 0
// 1 2
// 3 4 5
// 6 7 8 9
// 10 11 12 13 14
//
public static void main(String[] args) {
CheckPointing cp = new CheckPointing();
cp.check("start");
for (int i = 0; i < 15; i++) {
m(i);
}
cp.check("done");
System.out.println(cp);
}
static BitSet fromArr(boolean[] bo) {
BitSet b = new BitSet(bo.length);
for (int i = 0; i < bo.length; i++) {
b.set(i, bo[i]);
}
return b;
}
public static void m(int i) {
boolean[] initialBoard = new boolean[]{
true,
true, true,
true, true, true,
true, true, true, true,
true, true, true, true, true
};
initialBoard[i] = false;
init();
Board b = new Board(fromArr(initialBoard), 0, 0, null);
solve(b);
// cp.check("solve");
System.out.println("start: " + i);
System.out.println("# of Solutions per remaining pins (0..14): " + Arrays.toString(solutions));
System.out.println("total # Solutions: " + Arrays.stream(solutions).sum());
System.out.println("# of 'One remaining pin' Solutions: " + solutions[1]);
System.out.println("% of 'One remaining pin' per total: " + (double) solutions[1] / (double) Arrays.stream(solutions).sum());
System.out.println("Boards created on the way: " + boards);
System.out.println();
// cp.check("print");
// System.out.println(cp);
}
}