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

public class TestsGen {

	static final Random rnd = new Random(556668949239L);

	static String str = "../tests/";

	static TestWriter testWriter = new TestWriter(false);

	static class WaterTest {
		int n;
		int max;
		int q;
		int[] a;
		ArrayList<String> list;

		public WaterTest(int n, int max, int q) {
			this.n = n;
			this.max = max;
			this.q = q;
			a = new int[n];
			list = new ArrayList<>();
		}

		public String toString() {
			StringBuilder ans = new StringBuilder(n + " " + max + " " + q
					+ "\r\n");
			for (int i = 0; i < n - 1; i++) {
				ans.append(a[i] + " ");
			}
			ans.append(a[n - 1] + "\r\n");
			for (String s : list) {
				ans.append(s + "\r\n");
			}
			return ans.toString();
		}

	}

	static void genSample() throws IOException {
		WaterTest test = new WaterTest(3, 3, 7);
		test.a = new int[] { 1, 2, 1 };
		test.list.add("1 1 2 1");
		test.list.add("2 1 3");
		test.list.add("1 2 3 1");
		test.list.add("2 1 3");
		test.list.add("2 1 1");
		test.list.add("2 2 2");
		test.list.add("2 3 3");
		testWriter.printSimpleTest(test);
	}

	static int maxM = (int) (1e+9);

	static void genOne(int m) throws IOException {
		WaterTest test = new WaterTest(1, maxM, 2 * m);
		for (int i = 0; i < m - 2; i++) {
			test.list.add("1 1 1 1");
			test.list.add("2 1 1");
		}
		for (int i = 0; i < 2; i++) {
			test.list.add("1 1 1 " + maxM);
			test.list.add("2 1 1");
		}
		testWriter.printSimpleTest(test);
	}

	static void genTwo(int m) throws IOException {
		WaterTest test = new WaterTest(2, maxM, 12 * m);
		for (int i = 0; i < m; i++) {
			int val = i < m - 2 ? 1 : maxM;
			test.list.add("1 1 1 " + val);
			test.list.add("2 1 1");
			test.list.add("2 2 2");
			test.list.add("2 1 2");
			test.list.add("1 2 2 " + val);
			test.list.add("2 1 1");
			test.list.add("2 2 2");
			test.list.add("2 1 2");
			test.list.add("1 1 2 " + val);
			test.list.add("2 1 1");
			test.list.add("2 2 2");
			test.list.add("2 1 2");
		}
		testWriter.printSimpleTest(test);
	}

	static void genOverFlow(int n, int q) throws IOException {
		int val = maxM - rnd.nextInt(20) - 20;
		WaterTest test = new WaterTest(n, val, q);
		for (int i = 0; i < q; i++) {
			int len = rnd.nextInt(n) + 1;
			int left = rnd.nextInt(n - len + 1) + 1;
			int right = left + len - 1;
			if (i % 2 == 0) {
				test.list
						.add(new String("1 " + left + " " + right + " " + val/2));
			} else {
				test.list.add(new String("2 " + left + " " + right));
			}
		}
		testWriter.printSimpleTest(test);
	}

	
	
	static void genFull(int n, int q) throws IOException {
		int val = maxM - rnd.nextInt(20) - 20;
		WaterTest test = new WaterTest(n, val, q);
		Arrays.fill(test.a, val);
		for (int i = 0; i < q; i++) {
			int len = rnd.nextInt(n) + 1;
			int left = rnd.nextInt(n - len + 1) + 1;
			int right = left + len - 1;
			if (i % 2 == 0) {
				test.list
						.add(new String("1 " + left + " " + right + " " + val));
			} else {
				test.list.add(new String("2 " + left + " " + right));
			}
		}
		testWriter.printSimpleTest(test);
	}

	static void genNonFull(int n, int q) throws IOException {
		int val = maxM - rnd.nextInt(20) - 20;
		WaterTest test = new WaterTest(n, val, q);
		for (int i = 0; i < q; i++) {
			if (i % 2 == 0) {
				test.list.add(new String("1 1 " + n + " " + 1));
			} else {
				test.list.add(new String("2 1 " + n));
			}
		}
		testWriter.printSimpleTest(test);
	}

	static void genLittle(int n, int q, double pr) throws IOException {
		WaterTest test = new WaterTest(n, n, q);
		for (int i = 0; i < q; i++) {
			int len = rnd.nextInt(n) + 1;
			int left = rnd.nextInt(n - len + 1) + 1;
			int right = left + len - 1;
			if (rnd.nextDouble() < pr) {
				test.list.add("2 " + left + " " + right);
			} else {
				test.list.add("1 " + left + " " + right + " "
						+ (rnd.nextInt(10) + 1));
			}
		}
		testWriter.printSimpleTest(test);
	}

	static void genBig(int n, int q, double pr) throws IOException {
		int coef = maxM / n;
		WaterTest test = new WaterTest(n, n * coef, q);
		for (int i = 0; i < n; i++) {
			if (rnd.nextBoolean()) {
				test.a[i] = maxM - rnd.nextInt(10) * coef;
			}
		}
		for (int i = 0; i < q; i++) {
			int len = rnd.nextInt(n) + 1;
			int left = rnd.nextInt(n - len + 1) + 1;
			int right = left + len - 1;
			if (rnd.nextDouble() < pr) {
				test.list.add("2 " + left + " " + right);
			} else {
				test.list.add("1 " + left + " " + right + " "
						+ (rnd.nextInt(10) + 1) * coef);
			}
		}
		testWriter.printSimpleTest(test);
	}

	static void genCorrectnes() throws IOException {
		genOverFlow(100, 200);
		genFull(100, 200);
		genNonFull(100, 200);
		genLittle(1000, 1000, 1.0 / 2);
		genLittle(1000, 1000, 1.0 / 3);
		genLittle(1000, 1000, 0);
		genLittle(1000, 1000, 2.0 / 3);
		genLittle(1000, 1000, 1);
		genBig(1000, 1000, 1.0 / 2);
		genBig(1000, 1000, 1.0 / 3);
		genBig(1000, 1000, 0);
		genBig(1000, 1000, 2.0 / 3);
		genBig(1000, 1000, 1);
	}
	
	static void genPerfomance() throws IOException {
		genOverFlow(200000, 200000);
		genFull(200000, 200000);
		genNonFull(200000, 200000);
		genLittle(200000, 200000, 1.0 / 2);
		genLittle(200000, 200000, 1.0 / 3);
		genLittle(200000, 200000, 0);
		genLittle(200000, 200000, 2.0 / 3);
		genLittle(200000, 200000, 1);
		genBig(200000, 200000, 1.0 / 2);
		genBig(200000, 200000, 1.0 / 3);
		genBig(200000, 200000, 0);
		genBig(200000, 200000, 2.0 / 3);
		genBig(200000, 200000, 1);
	}


	

	public static void main(String[] args) throws IOException {
		new File("../tests").mkdir();
		genSample();
		genOne(5);
		genOne(100000);
		genTwo(5);
		genTwo(10000);
		genCorrectnes();
		genPerfomance();

		return;
	}

	public static class TestWriter {
		private boolean isMultiTest;
		private int done;

		private boolean isOpened;
		private PrintWriter out;
		private int printedTests;
		private int countTests = 0;

		public TestWriter(boolean isMultiTest) {
			this.isMultiTest = isMultiTest;
			this.done = 0;
		}

		public void init(int n) throws FileNotFoundException {
			printedTests = 0;
			if (isOpened) {
				throw new AssertionError("Please close prevoius multitest");
			}
			isOpened = true;
			countTests = n;
			done++;
			out = new PrintWriter(str + ((done < 10) ? "0" : "")
					+ String.valueOf(done));
			if (isMultiTest) {
				out.println(countTests);
			}
		}

		public void close() {
			if (!isOpened) {
				System.err.println("Before closing test was not created");
			}
			isOpened = false;
			if (printedTests != countTests) {
				throw new AssertionError("Wrong number of tests: all: "
						+ countTests + " printed: " + printedTests);
			}
			out.close();
		}

		public void printTest(Object test) throws IOException {
			if (!isMultiTest) {
				throw new AssertionError("Multi test doesn't allowed");
			}
			if (!isOpened) {
				throw new AssertionError("Please create test");
			}
			printedTests++;
			out.println(test.toString());
		}

		public void printSimpleTest(Object test) throws IOException {
			init(1);
			printedTests++;
			out.print(test.toString());
			close();
		}
	}

}
