import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Random;
import java.util.Scanner;
import java.util.TreeMap;

public class TestGen extends Thread {

	class Test {
		String[][] all;

		public Test(String[][] all) {
			this.all = all;
		}

	}

	private int testCount = 0;

	private void write(Test t) {
		try {
			++testCount;
			String filename = testCount / 10 + "" + testCount % 10;
			PrintWriter out = new PrintWriter(filename);
			System.err.println(testCount);
			out.println(t.all.length);
			for (int i = 0; i < t.all.length; i++) {
				out
						.println(t.all[i][0] + " " + t.all[i][1] + " "
								+ t.all[i][2]);
			}
			out.flush();
			out.close();
		} catch (IOException ex) {
			throw new RuntimeException(ex);
		}
	}

	void myAssert(boolean b) {
		if (!b)
			throw new AssertionError();
	}

	static Random rand = new Random(1);

	void shuffle(Object[] a) {
		for (int i = 0; i < a.length; i++) {
			int x = rand.nextInt(i + 1);
			Object o = a[x];
			a[x] = a[i];
			a[i] = o;
		}
	}

	int MAX = 100;

	class CountryWithResult {
		String country;
		int[] res;
		public CountryWithResult(String country, int... res) {
			this.country = country;
			this.res = res;
		}
	}	
	public void run() {
		loadCountries();
		write(firstXSizeEquals(0, 3, 10, true));
		write(firstXSizeEquals(1, 3, 10, true));
		write(firstXSizeEquals(2, 3, 10, true));
		write(firstXSizeEquals(3, 3, 10, true));
		write(realRandom(10));
		write(fullRandom(10));
		write(firstXSizeEquals(0, 3, 100, true));
		write(firstXSizeEquals(1, 3, 60, true));
		write(firstXSizeEquals(2, 3, 60, true));
		write(firstXSizeEquals(3, 3, 60, true));
		write(realRandom(MAX));
		write(fullRandom(MAX));
		write(strangeByYura(7));
		write(fullRandom(93));
		write(firstXSizeEquals(1, 2, 20, false));
		write(firstXSizeEquals(1, 5, 30, false));
		write(firstXSizeEquals(1, 4, 15, false));
		write(fullRandom(1));
		write(genAntik(1));
		write(genAntik(100));
	}

	Test genAntik(int n) {
		String[][] a = new String[n][3];
		for (int i = 0; i < n; i++) {
			a[i] = new String[] { "GREECE", "GREECE", "GREECE" };
		}
		return new Test(a);
	}

	Test strangeByYura(int n) {
		String[][] a = new String[n][3];
		String looser = "USSR";
		for (int i = 0; i < a.length; i++) {
			a[i][0] = getRealName();
			a[i][1] = a[i][2] = looser;
		}
		return new Test(a);

	}

	Test firstXSizeEquals(int x, int eqCountries, int numberOfCompetitions,
			boolean isReal) {
		int[] a = new int[x];
		for (int i = 0; i < a.length; i++) {
			a[i] = rand.nextInt(numberOfCompetitions / 3)
					+ numberOfCompetitions / 5;

		}

		TestBuilder tb = new TestBuilder(isReal);
		for (int i = 0; i < eqCountries; i++) {
			String s;
			if (isReal) {
				s = getRealName();
			} else {
				s = getRandName();
			}
			for (int j = 0; j < 3; j++) {
				if (j < x) {
					tb.win(s, j, a[j]);
				} else {
					tb.win(s, j, rand.nextInt(numberOfCompetitions / 3));
				}
			}
		}
		return tb.buildIt();
	}

	class TestBuilder {
		TreeMap<String, CountryWithResult> map;
		boolean isReal;

		public TestBuilder(boolean isReal) {
			map = new TreeMap<String, CountryWithResult>();
			this.isReal = isReal;
		}

		void win(String name, int medal) {
			if (!map.containsKey(name)) {
				map.put(name, new CountryWithResult(name, 0, 0, 0));
			}
			map.get(name).res[medal]++;
		}

		void win(String name, int medal, int times) {
			if (!map.containsKey(name)) {
				map.put(name, new CountryWithResult(name, 0, 0, 0));
			}
			map.get(name).res[medal] += times;
		}

		Test buildIt() {
			int[] sum = new int[3];
			for (CountryWithResult cwr : map.values()) {
				for (int i = 0; i < sum.length; i++) {
					sum[i] += cwr.res[i];
				}
			}
			int x = 0;
			for (int j : sum) {
				x = Math.max(x, j);
			}
			// System.err.println(x);
			if (x > 100) {
				throw new AssertionError();
			}
			for (int i = 0; i < sum.length; i++) {
				for (int j = 0; j < x - sum[i]; j++) {
					if (isReal) {
						win(getRealName(), i);
					} else {
						win(getRandName(), i);
					}
				}
			}
			return genDistribution(map.values().toArray(
					new CountryWithResult[0]));
		}

	}

	String getRealName() {
		return countries.get(rand.nextInt(countries.size()));
	}

	final int MAXLEN = (200 - 2) / 3;

	String getRandName() {
		String s = "";
		for (int i = 0; i < MAXLEN; i++) {
			s += (char) ('A' + rand.nextInt(26));
		}
		return s;
	}

	Test fullRandom(int len) {
		String[][] a = new String[len][3];
		for (String[] b : a) {
			for (int i = 0; i < b.length; i++) {
				b[i] = getRandName();
			}
		}
		return new Test(a);
	}

	Test realRandom(int len) {
		String[][] a = new String[len][3];
		for (String[] b : a) {
			for (int i = 0; i < b.length; i++) {
				b[i] = getRealName();
			}
		}
		return new Test(a);
	}

	@SuppressWarnings("unchecked")
	Test genDistribution(CountryWithResult... cwr) {
		ArrayList<String>[] res = new ArrayList[3];
		for (int i = 0; i < 3; i++) {
			res[i] = new ArrayList<String>();
			for (int j = 0; j < cwr.length; j++) {
				for (int k = 0; k < cwr[j].res[i]; k++) {
					res[i].add(cwr[j].country);
				}
			}
			Collections.shuffle(res[i], rand);
		}
		String[][] a = new String[res[0].size()][3];
		for (int i = 0; i < a.length; i++) {
			for (int j = 0; j < 3; j++) {
				a[i][j] = res[j].get(i);
			}
		}
		return new Test(a);
	}

	ArrayList<String> countries;

	void loadCountries() {
		try {
			Scanner countries = new Scanner(new File("countries.txt"));
			this.countries = new ArrayList<String>();
			while (countries.hasNext()) {
				this.countries.add(countries.next());
			}
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		}
	}

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

	// String RUSSIA = "RUSSIA";
	// String RUSIA = "RUSIA";
	// String ALBANIA = "ALBANIA";
	//
	// String[] G = { RUSSIA, RUSSIA, RUSSIA, RUSSIA, ALBANIA, ALBANIA, ALBANIA,
	// ALBANIA, RUSIA, RUSIA, RUSIA, RUSIA };
	//
	// String[] S = { RUSIA, RUSIA, RUSIA, RUSIA, RUSIA, RUSIA, RUSSIA, RUSSIA,
	// RUSSIA, RUSSIA, RUSSIA, RUSSIA };
	//
	// String[] B = { ALBANIA, ALBANIA, RUSIA, RUSIA, RUSIA, RUSIA, RUSIA,
	// RUSSIA,
	// RUSSIA, RUSSIA, RUSSIA, RUSSIA };
	// {
	// shuffle(G);
	// shuffle(S);
	// shuffle(B);
	// for (int i = 0; i < G.length; i++) {
	// System.out.println(G[i] + " " + S[i] + " " + B[i]);
	// }
	// }
}
