import os
import random
import sys

MAX_N = 100
MAX_DIGS = 15
MAX_V = 10**MAX_DIGS


CASE = 1
DEST = os.path.join(os.getcwd(), '../data/secret')

def next_file(short_desc=None, long_desc=None):
    global CASE
    basename = os.path.join(DEST, '%02d' % CASE)
    CASE += 1
    if short_desc is not None:
        basename += '-' + short_desc
    if long_desc is not None:
        with open(basename+'.desc', 'w') as desc_out:
            desc_out.write(long_desc)
    return open(basename+'.in', 'w')

def save_case(A, short_desc=None, long_desc=None, shuffle_adj_list=True):
    assert 1 <= len(A) <= MAX_N
    assert list(sorted(A)) == A
    sys.stderr.write('save case n=%d\n' % (len(A)))
    f = next_file(short_desc, long_desc)
    f.write('%d\n' % len(A))
    f.write('%s\n' % ' '.join(map(str, A)))
    f.close()


def gen_random_case(n, min_v=0, max_v=MAX_V, short_desc='random'):
    A = list(sorted(random.randint(min_v, max_v) for _ in range(n)))
    save_case(A, short_desc=short_desc)


def get_max_imposs():
    r = [0]
    for d in range(1, MAX_DIGS+1):
        r.append(10**d-1)
        r.append(10**d)
    return r
    
def main():
    random.seed(13)

    save_case(list(range(10)))
    save_case([0,0])
    save_case([0,1])
    save_case([0,9])
    save_case([1,9])
    save_case([9,9])
    save_case([0,0,9])
    save_case([0,1,9])
    save_case([0,9,9])
    save_case([1,1,9])
    save_case([1,9,9])
    
    lo = 0
    hi = 10
    r = []
    while lo <= MAX_V:
        r.append(random.randint(lo, min(hi-1, MAX_V)))
        (lo, hi) = (hi, 10*hi)
    save_case(r, short_desc='all_different_lengths')

    gen_random_case(MAX_N, min_v=0, max_v=9, short_desc='max_1digit')
    gen_random_case(MAX_N, min_v=MAX_V/10, max_v=MAX_V-1, short_desc='max_maxdigits')
    
    max_imposs = get_max_imposs()
    save_case(max_imposs, short_desc='max_impossible')
    max_imposs[0] = 1
    save_case(max_imposs, short_desc='max_forced0')
    max_imposs[0] = 0
    i = len(max_imposs)/2
    save_case(max_imposs[:i] + [max_imposs[i]] + max_imposs[i:],
              short_desc='max_forced_middle')
    used = set([i, len(max_imposs)-1])
    while len(used) < 5:
        i = random.randint(0, len(max_imposs)-1)
        if i not in used:
            used.add(i)
            save_case(max_imposs[:i] + [max_imposs[i]] + max_imposs[i:],
                      short_desc='max_forced_middle')
    max_imposs.append(max_imposs[-1])
    save_case(max_imposs,
              short_desc='max_forced_end')

    save_case([0]*MAX_N, 'max_const')
    save_case([MAX_V-1]*MAX_N, 'max_const')
    save_case([MAX_V]*MAX_N, 'max_const')
    
    for i in range(4):
        gen_random_case(i+2)
    for i in range(6):
        n = random.randint(2, 10)
        mind = random.randint(1, MAX_DIGS)
        maxd = random.randint(1, MAX_DIGS)
        if mind > maxd: (mind, maxd) = (maxd, mind)
        gen_random_case(n, min_v = 10**(mind-1), max_v = 10**maxd-1)
    for i in range(4):
        gen_random_case(random.randint(2, MAX_N))
    
if __name__=='__main__':
    main()
