import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Arrays;
import java.util.Random;

public class TestsGen {
    class Test {
        boolean[][] f;

        Test(boolean[][] f) {
            this.f = f;
        }
    }

    int testCount;

    void write(Test t) throws IOException {
        PrintWriter pw = new PrintWriter(String.format("../tests/%02d", ++testCount));
        pw.println(t.f.length);
        for (int i = 0; i < t.f.length; i++) {
            for (int j = 0; j < t.f.length; j++) {
                pw.print(t.f[i][j] ? 'C' : 'D');
            }
            pw.println();
        }
        pw.close();
    }

    Test makeTestWithTwoCities(int n, int x1, int y1, int x2, int y2) {
        boolean[][] f = new boolean[n][n];
        f[x1][y1] = f[x2][y2] = true;
        return new Test(f);
    }

    Test makeTestWithTwoCities(int n) {
        return makeTestWithMCities(n, 2);
    }

    Test makeTestWithMCities(int n, int m) {
        if (m % 2 != 0) {
            throw new AssertionError();
        }
        boolean[][] f = new boolean[n][n];
        for (int i = 0; i < m; i++) {
            int x, y;
            do {
                x = random.nextInt(n);
                y = random.nextInt(n);
            } while (f[x][y]);
            f[x][y] = true;
        }
        return new Test(f);
    }

    Test makeTestWithAllCities(int n) {
        boolean[][] f = new boolean[n][n];
        for (int i = 0; i < n; i++) {
            Arrays.fill(f[i], true);
        }
        return new Test(f);
    }
    Test makeTestWithBorder(int n) {
        boolean[][] f = new boolean[n][n];
        for (int i = 0; i < n; i++) {
            f[0][i] = f[i][0] = f[n-1][i] = f[i][n-1] = true;
        }
        return new Test(f);
    }

    Random random = new Random(1);
    int MAXN = 50;

    void run() throws IOException {
    	genPreliminary();
    	
        //Group 1, two cities
        write(makeTestWithTwoCities(2, 0, 0, 1, 1));
        write(makeTestWithTwoCities(2, 0, 0, 0, 1));
        write(makeTestWithTwoCities(21));
        write(makeTestWithTwoCities(37));
        write(makeTestWithTwoCities(MAXN - 1));
        write(makeTestWithTwoCities(MAXN));
        write(makeTestWithTwoCities(MAXN, MAXN / 2 - 1, MAXN / 2 - 1, MAXN / 2, MAXN / 2));
        write(makeTestWithTwoCities(MAXN, MAXN / 2 - 1, MAXN / 2, MAXN / 2, MAXN / 2 - 1));
        //Group 2
        write(makeTestWithAllCities(2));
        write(makeTestWithMCities(3, 4));
        write(makeTestWithMCities(4, 4));
        write(makeTestWithBorder(5));
        write(makeTestWithMCities(9, 20));
        write(makeTestWithMCities(13, 64));
        write(makeTestWithMCities(18, 122));
        write(makeTestWithMCities(42, 42));
        write(makeTestWithBorder(MAXN));
        write(makeTestWithMCities(MAXN, MAXN));
        write(makeTestWithMCities(MAXN, MAXN * MAXN / 4 * 2));
        write(makeTestWithAllCities(MAXN));

    }

    public static void main(String[] args) throws IOException {
        new TestsGen().run();
    }
    
    String[][] prelim = new String[][]{
    		{"DDD", 
    	     "DDC", 
    	     "DDC"},
    	    {"DDDDD",
    	     "CDCDC",
    	     "DCCDC",
    	     "DDDDD",
    	     "DDDDD"
    	    }
    };
    
    void genPreliminary() throws IOException {
		new File("../preliminary").mkdir();
    	for (int t = 0; t < prelim.length; t++) {
    		PrintWriter out = new PrintWriter(String.format("../preliminary/%02d", t + 1));
    		out.println(prelim[t].length);
    		for (int i = 0; i < prelim[t].length; i++) {
    			out.println(prelim[t][i]);
    		}
    		out.close();
    	}
    }

}
