This is a small java program which takes on the command line the puzzle parameters extracted from the puzzle's HTML page, and when a solution is found it prints out the list of coordinates for the shapes, as well as a formatted string that can be used to post the solution to the server without having the manually click on the page (HINT: you can automate all this solving stuff, and let it run while you sleep).
Code: Select all
import java.util.ArrayList;
final class Shape {
public int[][] cells;
int rows;
int columns;
public Shape(String spec) {
String[] rowSpecs = spec.split("\\,");
rows = rowSpecs.length;
columns = rowSpecs[0].length();
ArrayList coordinates = new ArrayList();
for (int row=0; row<rows; row++) {
for (int column=0; column<columns; column++) {
if (rowSpecs[row].charAt(column) == 'X') coordinates.add(new int[] {column, row});
}
}
cells = new int[coordinates.size()][];
coordinates.toArray(cells);
}
}
final class Board {
public int depth;
public int[] cells;
public int columns;
public int rows;
public Board(String spec, int depth) {
this.depth = depth;
cells = new int[spec.length()];
String[] rowSpecs = spec.split(",");
rows = rowSpecs.length;
columns = rowSpecs[0].length();
for (int row=0; row<rows; row++) {
for (int column=0; column<columns; column++) {
cells[column+row*columns] = (byte)(rowSpecs[row].charAt(column)-'0');
}
}
}
public void apply(Shape shape, int column, int row, int delta) {
for (int i=0; i<shape.cells.length; i++) {
int o = column+shape.cells[i][0]+(row+shape.cells[i][1])*columns;
cells[o] = (cells[o]+delta)%(depth+1);
}
}
}
class Solver {
Board board;
Shape[] shapes;
int[][] positions;
public Solver(Board board, Shape[] shapes) {
this.board = board;
this.shapes = shapes;
positions = new int[shapes.length][2];
}
int[][] solve(int index) {
if (index == shapes.length) {
for (int i=0; i<board.cells.length; i++) {
if (board.cells[i] != 0) return null;
}
return positions;
} else {
Shape shape = shapes[index];
for (int column = 0; column<=board.columns-shape.columns; column++) {
for (int row = 0; row<=board.rows-shape.rows; row++) {
positions[index][0] = column;
positions[index][1] = row;
board.apply(shape, column, row, 1);
int[][] t = solve(index+1);
board.apply(shape, column, row, board.depth);
if (t != null) return t;
}
}
return null;
}
}
}
public class Modulo {
public static void main(String[] args) throws Exception {
// parse command line args: <depth> <pieces> <board>
// where <depth>, <pieces> and <board> parameters are obtained from
// the <applet> tag found in the puzzle HTML page
// NOTE: the <pieces> string contains spaces, so you will need to surround
// the string with quotes on the command line
int depth = Integer.parseInt(args[0])-1;
Board board = new Board(args[1], depth);
String[] shapeSpecs = args[2].split(" ");
Shape[] shapes = new Shape[shapeSpecs.length];
for (int i=0; i<shapeSpecs.length; i++) {
shapes[i] = new Shape(shapeSpecs[i]);
}
// solve the puzzle
Solver solver = new Solver(board, shapes);
int[][] solution = solver.solve(0);
if (solution != null) {
for (int i=0; i<solution.length; i++) {
System.out.println("Shape " + i + " at " + solution[i][0] + "," + solution[i][1]);
}
System.out.println("Formatted solution sequence (for the modulo.php?seq= part of the submit URL:");
for (int i=0; i<solution.length; i++) {
System.out.print(String.format("%02x%02x", solution[i][0], solution[i][1]));
}
System.out.println("");
} else {
System.out.println("????????? no solution found ????????");
}
}
}