import java.io.*;
import java.util.*;

public class TestGen {

	PrintWriter out;
	Random rnd;
	int tNumber;

	class Test {
		
		boolean[][] a;
		boolean[] c = {true, false};
		
		void printTest() throws IOException {
			if (tNumber < 10)
				out = new PrintWriter("../tests/0" + tNumber);
			else
				out = new PrintWriter("../tests/" + tNumber);
			tNumber++;
			out.println(a.length + " " + a[0].length);
			for (boolean[] b : a) {
				for (boolean c : b) {
					out.print(c ? "#" : ".");
				}
				out.println();
			}
			out.close();
			initC();
		}
		
		void destroy(int k) {
			for (int t = 0; t < k; t++) {
				int x = rnd.nextInt(a.length);
				int y = rnd.nextInt(a[0].length);
				a[x][y] = !a[x][y];
			}
			
		}
		
		void initC() {
			c = new boolean[2];
			c[0] = rnd.nextBoolean();
			c[1] = !c[0];
			
		}
		
		void genEmpty(int n, int m, int k) throws IOException {
			a = new boolean[n][m];
			destroy(k);
			printTest();
		}
		
		void genFull (int n, int m, int k) throws IOException {
			a = new boolean[n][m];
			for (boolean[] b : a) {
				Arrays.fill(b, true);
			}
			
			destroy(k);
			printTest();
		}
		
		void genChess(int n, int m, int k) throws IOException {
			a = new boolean[n][m];
			for (int i = 0; i < n; i++) {
				for (int j = 0; j < m; j++) {
					a[i][j] = c[(i + j) % 2];
				}
			}
			
			destroy(k);
			printTest();
		}
		
		void genRandom(int n, int m) throws IOException {
			a = new boolean[n][m];
			for (int i = 0; i< n; i++) {
				for (int j = 0 ;j < m; j++) {
					a[i][j] = rnd.nextBoolean();
				}
			}
			printTest();
		}
		
		void genHorizontal(int n, int m, int k) throws IOException {
			a = new boolean[n][m];
			for (int i = 0; i< n; i++) {
				for (int j = 0; j < m; j++) {
					a[i][j] = c[i % 2];
				}
			}
			destroy(k);
			printTest();
		}
		
		void genVertical(int n, int m, int k) throws IOException {
			a = new boolean[n][m];
			for (int i = 0 ;i< n; i++) {
				for (int j = 0; j < m; j++) {
					a[i][j] = c[j % 2];
				}
			}
			destroy(k);
			printTest();
		}
		
		void genDiagonal1(int n, int m, int k) throws IOException {
			a = new boolean[n][m];
			for (int i = 0 ;i < n; i++) {
				for (int j = 0; j <m; j++) {
					a[i][j] = c[(i + j) / 2 % 2];
				}
			}
			destroy(k);
			printTest();
		}
		
		void genDiagonal2(int n, int m, int k) throws IOException {
			a = new boolean[n][m];
			for (int i = 0; i < n; i++) {
				for (int j = 0; j < m; j++) {
					a[i][j] = c[(i - j + 10000) / 2 % 2];
				}
			}
			destroy(k);
			printTest();
		}
		
		private void genOneStepOfSimpleSpiral(int sx, int fx, int sy, int fy) {
			if (sx >= fx)
				return;
			if (sy >= fy)
				return;
			for (int i = sx; i < fx; i++) {
				a[i][sy] = c[1];
				a[i][fy - 1] = c[1];
			}
			for (int i = sy; i < fy; i++) {
				a[sx][i] = c[1];
				a[fx - 1][i] = c[1];
			}
			if (sx >= fx - 4 || sy >= fy - 4) {
				return;
			}
			a[sx][sy + 1] = c[0];

			a[sx + 1][sy + 2] = c[1];
			genOneStepOfSimpleSpiral(sx + 2, fx - 2, sy + 2, fy - 2);
		}

		public void genSimpleSpiral(int n, int m) throws IOException {
			a = new boolean[n][m];

			genOneStepOfSimpleSpiral(0, n, 0, m);
			printTest();
		}

	}

	public void solve() throws IOException {
		tNumber = 1;
		rnd = new Random(31);
		
		Test t = new Test();
		
		t.genEmpty(1, 1, 0);
		t.genEmpty(1, 1000, 0);
		t.genEmpty(1000, 1, 0);
		t.genEmpty(2, 1000 - rnd.nextInt(50), 0);
		t.genEmpty(1000 - rnd.nextInt(50), 2, 0);
		t.genEmpty(1, 2, 0);
		t.genEmpty(2, 1, 0);
		t.genEmpty(2, 2, 0);
		t.genEmpty(1000 - rnd.nextInt(50), 1000 - rnd.nextInt(50), 0);
		t.genEmpty(1000, 1000, 0);
		
		t.genFull(1000, 1000, 0);
		t.genFull(1000, 1000, 1000);
		
		t.genChess(1000 - rnd.nextInt(50), 1000 - rnd.nextInt(50), 0);
		t.genChess(1000 - rnd.nextInt(50), 1000 - rnd.nextInt(50), 1000);
		
		t.genDiagonal1(1000 - rnd.nextInt(50), 1000 - rnd.nextInt(50), 0);
		t.genDiagonal1(1000 - rnd.nextInt(50), 1000 - rnd.nextInt(50), 100);
		t.genDiagonal1(1000 - rnd.nextInt(50), 1000 - rnd.nextInt(50), 10000);
		t.genDiagonal1(1000 - rnd.nextInt(50), 1000 - rnd.nextInt(50), 100000);
		
		t.genDiagonal2(1000 - rnd.nextInt(50), 1000 - rnd.nextInt(50), 0);
		t.genDiagonal2(1000 - rnd.nextInt(50), 1000 - rnd.nextInt(50), 100);
		t.genDiagonal2(1000 - rnd.nextInt(50), 1000 - rnd.nextInt(50), 10000);
		t.genDiagonal2(1000 - rnd.nextInt(50), 1000 - rnd.nextInt(50), 100000);
		
		t.genHorizontal(1000 - rnd.nextInt(50), 1000 - rnd.nextInt(50), 0);
		t.genHorizontal(1000 - rnd.nextInt(50), 1000 - rnd.nextInt(50), 100);
		t.genHorizontal(1000 - rnd.nextInt(50), 1000 - rnd.nextInt(50), 10000);
		
		t.genVertical(1000 - rnd.nextInt(50), 1000 - rnd.nextInt(50), 0);
		t.genVertical(1000 - rnd.nextInt(50), 1000 - rnd.nextInt(50), 100);
		t.genVertical(1000 - rnd.nextInt(50), 1000 - rnd.nextInt(50), 10000);
		
		t.genSimpleSpiral(952, 952);
		t.genRandom(1000, 1000);
		
		
	}

	public void run() {
		try {

			solve();

		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	public static void main(String[] args) {
		new TestGen().run();
	}
}
