Skip to content

Instantly share code, notes, and snippets.

@dcposch
Created December 26, 2017 07:20
Show Gist options
  • Save dcposch/b6d2cc95013852346277c76dec8540a5 to your computer and use it in GitHub Desktop.
Save dcposch/b6d2cc95013852346277c76dec8540a5 to your computer and use it in GitHub Desktop.
Lights Out algorithms challenge - breadth first, can extend to A*
public class Bulbs {
public static void main(String[] args) {
Board challenge = new Board(3);
challenge.set(1, 0, true);
System.out.println("CHALLENGE");
System.out.println(challenge);
System.out.println("SOLUTION");
Board solution = solve(challenge);
if (solution == null) {
System.out.println("(no solution found)");
return;
}
Board after = challenge;
for (int i = 0; i < solution.moves.length; i++) {
Point move = solution.moves[i];
System.out.println("FLIP " + move.x + ", " + move.y);
after = after.toggle(move.x, move.y);
System.out.println(after);
}
}
private static Board solve(Board challenge) {
Queue<Board> q = new LinkedList<>();
q.add(challenge);
int n = challenge.n;
while (!q.isEmpty()) {
Board current = q.poll();
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
Board next = current.toggle(i, j);
if (next.isClear()) {
return next;
}
q.add(next);
}
}
}
return null;
}
private static class Board {
private final int n;
private final boolean[] board;
private final Point[] moves;
private Board(int n) {
this.n = n;
board = new boolean[n * n];
moves = new Point[0];
}
public boolean isClear() {
for (int i = 0; i < n * n; i++) {
if (board[i]) {
return false;
}
}
return true;
}
@Override
public String toString() {
StringBuilder ret = new StringBuilder();
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
ret.append(board[i * n + j] ? "1" : "0");
}
ret.append('\n');
}
return ret.toString();
}
private Board(Board prev, Point move) {
this.n = prev.n;
board = Arrays.copyOf(prev.board, prev.board.length);
moves = Arrays.copyOf(prev.moves, prev.moves.length + 1);
moves[prev.moves.length] = move;
}
private void set(int i, int j, boolean val) {
board[i * n + j] = val;
}
private Board toggle(int i, int j) {
Board ret = new Board(this, new Point(i, j));
ret.flip(i - 1, j);
ret.flip(i + 1, j);
ret.flip(i, j - 1);
ret.flip(i, j + 1);
ret.flip(i, j);
return ret;
}
private void flip(int i, int j) {
if (i < 0 || j < 0 || i >= n || j >= n) {
return;
}
board[i * n + j] = !board[i * n + j];
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment