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.List;
import java.util.Random;

/**
 * Created with IntelliJ IDEA.
 * User: Roman Rubanenko
 * Date: 04.10.13
 * Time: 23:36
 * To change this template use File | Settings | File Templates.
 */
public class TestGen implements Runnable {

    private PrintWriter out;
    private Random random;
    private int testNumber;

    class Test {

        public List<Integer> array;

        public static final int maxSize = 500 * 1000;
        public static final int maxElement = 1000 * 1000 * 1000;

        public void printTest() {
            try {
                if (testNumber < 10)
                    out = new PrintWriter("../tests/0" + testNumber);
                else
                    out = new PrintWriter("../tests/" + testNumber);
            } catch (IOException e) {
                e.printStackTrace();
            }

            System.err.println("[" + testNumber + "]");
            testNumber++;

            out.println(array.size());
            for (int i = 0; i < array.size(); i++) {
                if (i > 0)
                    out.print(" ");
                if (random.nextInt(100) == 74)
                    out.print(0);
                else if ((array.get(i)<0)||(array.get(i)>maxElement)) out.print(random.nextInt(maxElement)); else
                    out.print(array.get(i));
            }
            out.println();

            out.close();
        }

        public void printSampleTest() {
            try {
                out = new PrintWriter("../tests/01");
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            }
            out.print("5\r\n10 74 47 77 301\r\n");
            out.close();
        }

        public void generateRandomTest(int size) {
            if (size > maxSize) {
                throw new RuntimeException("too big array size");
            }
            init();
            for (int i = 0; i < size; i++) {
                array.add(random.nextInt(maxElement));
            }
        }

        public void generateAlmostRandomTest(int size, int[] masks) {
            if (size > maxSize) {
                throw new RuntimeException("too big array size");
            }
            init();
            for (int i = 0; i < size; i++) {
                int index = random.nextInt(masks.length);
                array.add(getNumberByMask(masks[index]));
            }
        }

        private int getNumberByMask(int mask) {
            if (mask > (1 << 10) - 1) {
                mask ^= 1 << random.nextInt(10);
            }
            List<Integer> digits = new ArrayList<Integer>();
            for (int i = 1; i < (1 << 10); i <<= 1)
                if ((mask & i) > 0)
                    digits.add(i - 1);
            int length = digits.size();// + random.nextInt(10 - digits.size());
            Collections.shuffle(digits, random);
            for (int i = digits.size(); i < length; i++)
                digits.add(digits.get(random.nextInt(digits.size())));
            int sum = 0;
            for (int digit : digits)
                sum += digit;
            while (digits.get(0) == 0 && sum > 0)
                Collections.swap(digits, 0, 1 + random.nextInt(digits.size() - 1));
            int number = 0;
            for (int digit : digits)
                number = number * 10 + digit;
            return number;
        }

        private void init() {
            array = new ArrayList<Integer>();
        }

    }

    private void generate() {
        new File("../tests").mkdir();
        random = new Random(31);
        Test tester = new Test();

        tester.printSampleTest();
        testNumber = 2;
        int[] masks = new int[]{477};

        for (int i = 0; i < 10; i++) {
            tester.generateRandomTest(7);
            tester.printTest();
        }
        for (int i = 0; i < 10; i++) {
            tester.generateRandomTest(Test.maxSize);
            tester.printTest();
        }

        tester.generateAlmostRandomTest(random.nextInt(Test.maxSize) + 1, masks);
        tester.printTest();

        for (int i = 0; i < 10; i++) {
            masks = new int[15];
            for (int j = 0; j < 15; j++) {
                masks[j] = random.nextInt((1 << 10) - 1) + 1;
            }
            tester.generateAlmostRandomTest(random.nextInt(Test.maxSize) + 1, masks);
            tester.printTest();
        }

        masks = new int[100];
        for (int j = 0; j < masks.length; j++)
            masks[j] = j + 1;
        for (int i = 0; i < 10; i++) {
            tester.generateAlmostRandomTest(random.nextInt(Test.maxSize) + 1, masks);
            tester.printTest();
        }
    }

    @Override
    public void run() {
        try {
            generate();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

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

}
