import random
import math
random.seed("personal02")

class TestGen:
    def __init__(self):
        self.test_number = 0
        self.desc_file = open("../tests.desc", "w")

    def generate_samples(self):
        self.print_test(2, 3, [[1, 1, 2], [1, 2, 3]], "subtask0", "test from sample", 0, "preliminary")
        self.print_test(2, 4, [[1, 1, 2], [1, 2, 3]], "subtask0", "test from sample", 0, "preliminary")

    def generate_random_test(self, maxn, maxk, maxx, subtask):
        n = maxn
        k = random.randint(1, maxk)
        penguins = [[0, 0, 0] for i in range(n)]
        for i in range(n):
            penguins[i] = [random.randint(1, maxx), 0, random.randint(1, maxx)]
            if (random.randint(1, 2) == 1) and (penguins[i][0] <= k):
                diff = k - penguins[i][0]
                mx = int(math.sqrt(diff)) + 2
                for it in range(10):
                    ds = random.randint(2, mx)
                    if diff % ds == 0:
                        penguins[i][1] = ds
                        break
                if penguins[i][1] != 0:
                    continue
                for ds in range(2, 10):
                    if diff % ds == 0:
                        penguins[i][1] = ds
                        break
                if penguins[i][1] != 0:
                    continue
                if random.randint(1, 2) == 1:
                    penguins[i][1] = 1
                else:
                    penguins[i][1] = diff
            else:
                penguins[i][1] = random.randint(1, maxx)
        self.print_test(n, k, penguins, subtask, "n = %d, k = %d" % (n, k), 0)

    def generate_max_test(self, maxn, maxk, subtask):
        k = 931170240
        maxc = 10**9
        if maxk <= 1000:
            k = 840
            maxc = 1000
        d = 2
        ds = []
        while d * d <= k:
            if k % d == 0:
                ds.append(d)
            if d * d != k:
                ds.append(k // d)
            d += 1
        ds.sort()
        n = maxn
        penguins = [[0, 0, 0] for i in range(n)]
        for i in range(n):
            penguins[i][0] = 1
            penguins[i][1] = ds[random.randint(0, len(ds) - 1)]
            penguins[i][2] = random.randint(1, maxc)
        self.print_test(n, k + 1, penguins, subtask, "n = %d, k = %d" % (n, k), 0)

    def generate_first_group(self):
        self.print_test(1, 1, [[1, 1, 1]], "subtask1", "n = 1, k = 1", 0)
        self.print_test(1, 1000, [[1, 1, 1]], "subtask1", "n = 1, k = 1000", 0)
        self.print_test(1, 1000, [[1, 2, 239]], "subtask1", "n = 1, k = 1000", 0)
        self.print_test(1, 1000, [[1, 3, 239]], "subtask1", "n = 1, k = 1000", 0)
        self.print_test(1, 1000, [[1, 1000, 1000]], "subtask1", "n = 1, k = 1000", 0)
        for t in range(5):
            self.generate_random_test(10, 10, 10, "subtask1")
        for t in range(5):
            self.generate_random_test(300, 300, 300, "subtask1")
        for t in range(5):
            self.generate_random_test(1000, 1000, 1000, "subtask1")
        self.print_test(2, 1000, [[1001, 1, 1000], [1000, 1, 239]], "subtask1", "n = 2, k = 1000", 0)
        self.generate_max_test(1000, 1000, "subtask1")

    def generate_second_group(self):
        self.print_test(1, 1, [[1, 1, 1]], "subtask2", "n = 1, k = 1", 0)
        self.print_test(1, 10**9, [[1, 1, 1]], "subtask2", "n = 1, k = 10^9", 0)
        self.print_test(1, 10**9, [[1, 2, 293181723]], "subtask2", "n = 1, k = 10^9", 0)
        self.print_test(1, 10**9, [[1, 3, 293181723]], "subtask2", "n = 1, k = 10^9", 0)
        self.print_test(1, 10**9, [[1, 1000, 1000000000]], "subtask2", "n = 1, k = 10^9", 0)
        for t in range(5):
            self.generate_random_test(100, 100, 100, "subtask2")
        for t in range(5):
            self.generate_random_test(10000, 1000000, 1000000, "subtask2")
        for t in range(5):
            self.generate_random_test(10**5, 10**9, 10**9, "subtask2")
        self.print_test(2, 10**9 - 1, [[10**9, 1, 10**9], [10**9 - 1, 1, 239]], "subtask2", "n = 2, k = 10^9-1", 0)
        self.generate_max_test(10**5, 10**9, "subtask2")

    def print_test(self, n, k, jumps, subtask, description, points=0, folder="tests"):
        self.test_number += 1
        print("Generating test %s\%d" % (subtask, self.test_number))
        test_name = "../" + folder + "/{0:0=2d}".format(self.test_number)
        test_file = open(test_name, "w")
        print(n, k, file=test_file)
        print('\n'.join(' '.join(str(element) for element in jump) for jump in jumps), file=test_file)
        print(test_name + ", folder=" + folder + ", subtask=" + subtask + ", points=" + str(points) + ", comment=\"" + description + "\"", file=self.desc_file)
        test_file.close()                                                                                             

    def generate_all_tests(self):
        self.generate_samples()
        self.test_number = 0

        #First group of tests
        self.generate_first_group()       #tests 01-##
        print("comment_subtask1=\"n, k &lt;= 1000\"", file=self.desc_file)
        print("bonus_subtask1=50", file=self.desc_file)

        #Second group of tests
        self.generate_second_group()      #tests ##-##
        print("comment_subtask2=\"n &lt;= 100000; k &lt;= 1000000000\"", file=self.desc_file)
        print("bonus_subtask2=50", file=self.desc_file)
        
        self.desc_file.close()

import os, shutil
if os.path.exists('../preliminary'):
    print('Directory preliminary already exists')
    shutil.rmtree('../preliminary', ignore_errors=False, onerror=None)
if os.path.exists('../tests'):
    print('Directory tests already exists')
    shutil.rmtree('../tests', ignore_errors=False, onerror=None)
try:
    os.makedirs('../preliminary')
    os.makedirs('../tests')
except OSError:                                                                                                                      
    pass

import time
start = time.time()
writer = TestGen()
writer.generate_all_tests()
finish = time.time()
print('All tests were generated. Elapsed time: ', finish - start)