34
8
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
Could someone please re-upload the test cases? I want to write my own version of this program to compare with the others. – Alexander Revo – 2016-01-20T14:57:37.477
2
@AlexanderRevo I thought I didn't move the file, but apparently the link's up and changed without me doing so. Here's the link again.
– Joe Z. – 2016-01-20T16:53:08.1802Judging by your own submission the output shouldn't actually contain spaces? – Martin Ender – 2014-04-23T23:56:39.133
The output can be in whatever format you like, as long as it's actually a sequence of numbers. – Joe Z. – 2014-04-24T00:11:33.713
5It's worth noting that the test input data does not have spaces between the numbers. – nderscore – 2014-04-24T01:21:05.603
I did that for compression. – Joe Z. – 2014-04-24T02:44:31.817
Accepted already? :(. I was about to write my own code... – avall – 2014-04-24T14:50:48.923
3You can still write it. If it undercuts the current winner, I will change the accepted answer. – Joe Z. – 2014-04-24T14:51:12.240
Okay, give me a day :). – avall – 2014-04-24T14:51:57.590
Well, I failed. My code turned out to be slow and far from optimal... – avall – 2014-04-25T11:43:40.167
One idea, which I don't have time to code: Create a neighbor graph, where each edge has a distance of zero if the neighbors have the same value, and one if they are different. For each node, find the shortest path and distance to the center node. Solution = flooding the path to the most distant node. – MrBackend – 2014-04-25T13:15:06.767
Comment to self: Perhaps it is necessary to recalculate for each iteration. – MrBackend – 2014-04-25T13:21:02.313
Is there any time constraints? I'm pretty sure a brute force breadth-first search is optimal. – Cruncher – 2014-04-25T14:15:52.443
4The time constraint is "it needs to be fast enough for you to run it and post the actual results here". – Joe Z. – 2014-04-25T14:42:50.750
Are the test cases randomly generated or is there any logic behind them? – tomsmeding – 2014-04-25T15:59:27.373
They're randomly generated. – Joe Z. – 2014-04-25T16:03:09.667
I'm just going through all the submissions and converting all the digit grouping to a similar scheme. – Joe Z. – 2014-04-28T19:32:54.630
Ok, so there was a bug in the verifer (my bad), accidental wraparound on the 1D array. Once my edit comes in, re-run your tests! – BurntPizza – 2014-04-28T21:58:10.363
Been fiddling with a playable format for this. For those interested, see full size demo.
– Origineil – 2014-05-02T18:44:31.787I took the 19x19 example and got to a whole different solution :/ much much shorter 20 steps shorter – Teun Pronk – 2014-05-08T12:42:57.397
I made a game based on this. Here's the GitHub link. http://github.com/hexafluoride/floodfill
– user3188175 – 2014-07-05T17:31:00.583