import random

random.seed(0)

def output(prefix, menu, n, events):
    with open(f'../data/secret/{prefix}.in', 'w') as file:
        file.write(f'{len(menu)}\n')
        line = ' '.join(map(str, menu))
        file.write(f'{line}\n')
        file.write(f'{n} {len(events)}\n')
        for t, p in events:
            file.write(f'{t} {p}\n')


def gen_small_random():
    n = random.randint(1, 15)
    m = random.randint(2, 15)
    menu = [random.randint(1, 100) for _ in range(m)]

    events = []

    sim = [0]*(n+1)
    mi = 0
    for time in range(100):
        if not sim[0]:
            sim[0] = menu[mi]
            mi = (mi+1)%m
        if time:
            for _ in range(3):
                if random.random() < 0.2:
                    pi = random.randint(1, n)
                    if sim[pi]:
                        events += [(time, pi)]
                        sim[pi] = 0
        sim = sim[-1:] + sim[:-1]

    return menu, n, events

# small input size

for i in range(10):
    output(f'00-small-random-{i:02d}', *gen_small_random())


# near max size input

max_n = 100
max_m = 100
max_t = 10000
max_e = 10000

def gen_big_random():
    n = random.randint(max_n-5, max_n)
    m = random.randint(max_m-5, max_m)
    menu = [random.randint(1, 100) for _ in range(m)]

    events = []

    sim = [0]*(n+1)
    mi = 0
    for time in range(max_t+1):
        if not sim[0]:
            sim[0] = menu[mi]
            mi = (mi+1)%m
        if time and random.random() < 0.9:
            while True:
                pi = random.randint(1, n)
                if sim[pi]:
                    events += [(time, pi)]
                    sim[pi] = 0
                    break
        sim = sim[-1:] + sim[:-1]

    return menu, n, events


for i in range(10):
    output(f'01-big-random-{i:02d}', *gen_big_random())

# edge cases

# person 2 doesn't take anything
output('02-edge-00',
    [1,10],
    2,
    [
        (1,1),
        (2,1),
        (3,1),
        (4,1)
    ]
)

# person 1 doesn't take anything
output('02-edge-01',
    [1,10],
    2,
    [
        (2,2),
        (3,2),
        (4,2),
        (5,2),
        (6,2),
    ]
)

# everyone takes stuff at the same time
output('02-edge-02',
    [1, 2, 4, 8, 16, 32, 64],
    100,
    [(100, 1+i) for i in range(100)] +
    [(200, 1+i) for i in range(100)]
)

# long wait for first item taken
output('02-edge-03',
    list(range(1,29)),
    100,
    [(max_t, 37)]
)

# long wait for first item taken
output('03-maxsize-00',
    list(range(1,101)),
    100,
    [(100*t, i) for t in range(1, 101) for i in range(1, 101)]
)
