In the game of Flood Paint, the goal of the game is to get the entire board to be the same colour in as few turns as possible.
The game starts with a board that looks something like this:
3 3 5 4 1 3 4 1 5
5 1 3 4 1 1 5 2 1
6 5 2 3 4 3 3 4 3
4 4 4 5 5 5 4 1 4
6 2 5 3[3]1 1 6 6
5 5 1 2 5 2 6 6 3
6 1 1 5 3 6 2 3 6
1 2 2 4 5 3 5 1 2
3 6 6 1 5 1 3 2 4
Currently, the number (representing a colour) at the center of the board is 3. Each turn, the square at the center will change colour, and all the squares of the same colour that are reachable from the center by moving horizontally or vertically (i.e. in the flood region of the center square) will change colours with it. So if the center square changes colour to 5:
3 3 5 4 1 3 4 1 5
5 1 3 4 1 1 5 2 1
6 5 2 3 4 3 3 4 3
4 4 4 5 5 5 4 1 4
6 2 5 5[5]1 1 6 6
5 5 1 2 5 2 6 6 3
6 1 1 5 3 6 2 3 6
1 2 2 4 5 3 5 1 2
3 6 6 1 5 1 3 2 4
then the 3 that was to the left of the center 3 will also change colour. Now there are a total of seven 5's reachable from the center one, and so if we then change colour to 4:
3 3 5 4 1 3 4 1 5
5 1 3 4 1 1 5 2 1
6 5 2 3 4 3 3 4 3
4 4 4 4 4 4 4 1 4
6 2 4 4[4]1 1 6 6
5 5 1 2 4 2 6 6 3
6 1 1 5 3 6 2 3 6
1 2 2 4 5 3 5 1 2
3 6 6 1 5 1 3 2 4
the painted region again increases in size dramatically.
Your task is to create a program that will take a 19-by-19 grid of colours from 1 to 6 as input, in whatever form you choose:
4 5 1 1 2 2 1 6 2 6 3 4 2 3 2 3 1 6 3
4 2 6 3 4 4 5 6 4 4 5 3 3 3 3 5 4 3 4
2 3 5 2 2 5 5 1 2 6 2 6 6 2 1 6 6 1 2
4 6 5 5 5 5 4 1 6 6 3 2 6 4 2 6 3 6 6
1 6 4 4 4 4 6 4 2 5 5 3 2 2 4 1 5 2 5
1 6 2 1 5 1 6 4 4 1 5 1 3 4 5 2 3 4 1
3 3 5 3 2 2 2 4 2 1 6 6 6 6 1 4 5 2 5
1 6 1 3 2 4 1 3 3 4 6 5 1 5 5 3 4 3 3
4 4 1 5 5 1 4 6 3 3 4 5 5 6 1 6 2 6 4
1 4 2 5 6 5 5 3 2 5 5 5 3 6 1 4 4 6 6
4 6 6 2 6 6 2 4 2 6 1 5 6 2 3 3 4 3 6
6 1 3 6 3 5 5 3 6 1 3 4 4 5 1 2 6 4 3
2 6 1 3 2 4 2 6 1 1 5 2 6 6 6 6 3 3 3
3 4 5 4 6 6 3 3 4 1 1 6 4 5 1 3 4 1 2
4 2 6 4 1 5 3 6 4 3 4 5 4 2 1 1 4 1 1
4 2 4 1 5 2 2 3 6 6 6 5 2 5 4 5 4 5 1
5 6 2 3 4 6 5 4 1 3 2 3 2 1 3 6 2 2 4
6 5 4 1 3 2 2 1 1 1 6 1 2 6 2 5 6 4 5
5 1 1 4 2 6 2 5 6 1 3 3 4 1 6 1 2 1 2
and return a sequence of colours that the center square will change to each turn, again in the format of your choosing:
263142421236425431645152623645465646213545631465
At the end of each sequence of moves, the squares in the 19-by-19 grid must all be the same colour.
Your program must be entirely deterministic; pseudorandom solutions are allowed, but the program must generate the same output for the same test case every time.
The winning program will take the fewest total number of steps to solve all 100,000 test cases found in this file (zipped text file, 14.23 MB). If two solutions take the same number of steps (e.g. if they both found the optimal strategy), the shorter program will win.
BurntPizza has written a program in Java to verify the test results. To use this program, run your submission and pipe the output to a file called steps.txt
. Then, run this program with steps.txt
and the floodtest
file in the same directory. If your entry is valid and produces correct solutions for all the files, it should pass all the tests and return All boards solved successfully.
import java.io.*;
import java.util.*;
public class PainterVerifier {
public static void main(String[] args) throws FileNotFoundException {
char[] board = new char[361];
Scanner s = new Scanner(new File("steps.txt"));
Scanner b = new Scanner(new File("floodtest"));
int lineNum = 0;
caseloop: while (b.hasNextLine()) {
for (int l = 0; l < 19; l++) {
String lineb = b.nextLine();
if (lineb.isEmpty())
continue caseloop;
System.arraycopy(lineb.toCharArray(), 0, board, l * 19, 19);
}
String line = s.nextLine();
if (line.isEmpty())
continue;
char[] steps = line.toCharArray();
Stack<Integer> nodes = new Stack<Integer>();
for (char c : steps) {
char targetColor = board[180];
char replacementColor = c;
nodes.push(180);
while (!nodes.empty()) {
int n = nodes.pop();
if (n < 0 || n > 360)
continue;
if (board[n] == targetColor) {
board[n] = replacementColor;
if (n % 19 > 0)
nodes.push(n - 1);
if (n % 19 < 18)
nodes.push(n + 1);
if (n / 19 > 0)
nodes.push(n - 19);
if (n / 19 < 18)
nodes.push(n + 19);
}
}
}
char center = board[180];
for (char c : board)
if (c != center) {
s.close();
b.close();
System.out.println("\nIncomplete board found!\n\tOn line " + lineNum + " of steps.txt");
System.exit(0);
}
if (lineNum % 5000 == 0)
System.out.printf("Verification %d%c complete...\n", lineNum * 100 / 100000, '%');
lineNum++;
}
s.close();
b.close();
System.out.println("All boards solved successfully.");
}
}
Also, a scoreboard, since the results aren't actually sorted by score and here it actually matters a lot:
- 1,985,078 - smack42, Java
- 2,075,452 - user1502040, C
- 2,098,382 - tigrou, C#
- 2,155,834 - CoderTao, C#
- 2,201,995 - MrBackend, Java
- 2,383,569 - CoderTao, C#
- 2,384,020 - Herjan, C
- 2,403,189 - Origineil, Java
- 2,445,761 - Herjan, C
- 2,475,056 - Jeremy List, Haskell
- 2,480,714 - SteelTermite, C (2,395 bytes)
- 2,480,714 - Herjan, Java (4,702 bytes)
- 2,588,847 - BurntPizza, Java (2,748 bytes)
- 2,588,847 - Gero3, node.js (4,641 bytes)
- 2,979,145 - Teun Pronk, Delphi XE3
- 4,780,841 - BurntPizza, Java
- 10,800,000 - Joe Z., Python