Problem p01882 - Generation 3

Orig Description

We don't wanna work!
ACM is an organization of programming contests. The purpose of ACM does not matter to you. The only important thing is that workstyles of ACM members are polarized: each member is either a workhorse or an idle fellow.
Each member of ACM has a motivation level. The members are ranked by their motivation levels: a member who has a higher motivation level is ranked higher. When several members have the same value of motivation levels, the member who joined ACM later have a higher rank. The top 20% highest ranked members work hard, and the other (80%) members never (!) work. Note that if 20% of the number of ACM members is not an integer, its fraction part is rounded down.
You, a manager of ACM, tried to know whether each member is a workhorse or an idle fellow to manage ACM. Finally, you completed to evaluate motivation levels of all the current members. However, your task is not accomplished yet because the members of ACM are dynamically changed from day to day due to incoming and outgoing of members. So, you want to record transitions of members from workhorses to idle fellows, and vice versa.
You are given a list of the current members of ACM and their motivation levels in chronological order of their incoming date to ACM. You are also given a list of incoming/outgoing of members in chronological order.
Your task is to write a program that computes changes of workstyles of ACM members.
Input
The first line of the input contains a single integer $N$ ($1 \leq N \leq 50,000$) that means the number of initial members of ACM. The ($i$ + 1)-th line of the input contains a string $s_i$ and an integer $a_i$ ($0 \leq a_i \leq 10^5$), separated by a single space. $s_i$ means the name of the $i$-th initial member and $a_i$ means the motivation level of the $i$-th initial member. Each character of $s_i$ is an English letter, and $1 \leq |s_i| \leq 20$. Note that those $N$ lines are ordered in chronological order of incoming dates to ACM of each member.
The ($N$ + 2)-th line of the input contains a single integer $M$ ($1 \leq M \leq 20,000$) that means the number of changes of ACM members. The ($N$ + 2 + $j$)-th line of the input contains information of the $j$-th incoming/outgoing member. When the $j$-th information represents an incoming of a member, the information is formatted as "$+ t_j b_j$", where $t_j$ is the name of the incoming member and $b_j$ ($0 \leq b_j \leq 10^5$) is his motivation level. On the other hand, when the $j$-th information represents an outgoing of a member, the information is formatted as "$- t_j$", where $t_j$ means the name of the outgoing member. Each character of $t_j$ is an English letter, and $1 \leq |t_j| \leq 20$. Note that uppercase letters and lowercase letters are distinguished. Note that those $M$ lines are ordered in chronological order of dates when each event happens.
No two incoming/outgoing events never happen at the same time. No two members have the same name, but members who left ACM once may join ACM again.
Output
Print the log, a sequence of changes in chronological order. When each of the following four changes happens, you should print a message corresponding to the type of the change as follows:
 Member $name$ begins to work hard : "$name$ is working hard now."
 Member $name$ begins to not work : "$name$ is not working now."
For each incoming/outgoing, changes happen in the following order:
 Some member joins/leaves.
 When a member joins, the member is added to either workhorses or idle fellows.
 Some member may change from a workhorse to an idle fellow and vice versa. Note that there are no cases such that two or more members change their workstyles at the same time.
Sample Input 1
4
Durett 7
Gayles 3
Facenda 6
Daughtery 0
1
+ Mccourtney 2
Output for the Sample Input 1
Mccourtney is not working now.
Durett is working hard now.
Initially, no member works because $4 \times 20$% $< 1$. When one member joins ACM, Durrett begins to work hard.
Sample Input 2
3
Burdon 2
Orlin 8
Trumper 5
1
+ Lukaszewicz 7
Output for the Sample Input 2
Lukaszewicz is not working now.
No member works.
Sample Input 3
5
Andy 3
Bob 4
Cindy 10
David 1
Emile 1
3
+ Fred 10
- David
+ Gustav 3
Output for the Sample Input 3
Fred is working hard now.
Cindy is not working now.
Gustav is not working now.
Sample Input 4
7
Laplant 5
Varnes 2
Warchal 7
Degregorio 3
Chalender 9
Rascon 5
Burdon 0
7
+ Mccarroll 1
- Chalender
+ Orlin 2
+ Chalender 1
+ Marnett 10
- Chalender
+ Chalender 0
Output for the Sample Input 4
Mccarroll is not working now.
Warchal is working hard now.
Orlin is not working now.
Chalender is not working now.
Marnett is working hard now.
Warchal is not working now.
Chalender is not working now.
Warchal is working hard now.
Some member may repeat incoming and outgoing.
Sample Input 5
4
Aoba 100
Yun 70
Hifumi 120
Hajime 50
2
- Yun
- Aoba
Output for the Sample Input 5
(blank)

Extracted Specification

An integer N (1 ≤ N ≤ 50,000), representing some quantity or size.
N lines follow, each containing a string s and an integer a (0 ≤ a ≤ 10^5). The string has a length between 1 and 20 characters and consists of English letters.
An integer M (1 ≤ M ≤ 20,000), representing another quantity.
M lines follow, each containing a string formatted as either "+ t b" or "- t". The string t has a length between 1 and 20 characters and consists of English letters, and b is an integer (0 ≤ b ≤ 10^5).

### Example Input:

```
4
NameA 7
NameB 3
NameC 6
NameD 0
1
+ NameE 2
```

### Function Signature:
Write a function f(N, A, M, B) that takes in the input.
def f(N: int, A: List[Tuple[str, int]], M: int, B: List[Union[Tuple[str, str, int], Tuple[str, str]]]): 
    ''' 
    N: an integer 
    A: a list of tuples, where each tuple contains a string and an integer
    M: an integer
    B: a list of tuples, where each tuple contains either two strings, or a string and an integer
    '''

Test Case Generator

Sure, I can help you write a test case generator for the "We don't wanna work!" problem. Here is a Python function that generates test cases for this problem:

```python
import random
import string

def generate_name():
    length = random.randint(1, 20)
    return ''.join(random.choices(string.ascii_letters, k=length))

def tcgen():
    N = random.randint(1, 50000)
    
    initial_members = []
    for _ in range(N):
        name = generate_name()
        motivation = random.randint(0, 100000)
        initial_members.append((name, motivation))
    
    M = random.randint(1, 20000)
    
    changes = []
    current_members = set(name for name, _ in initial_members)
    for _ in range(M):
        if random.choice([True, False]) and current_members:
            name = random.choice(list(current_members))
            changes.append(f"- {name}")
            current_members.remove(name)
        else:
            name = generate_name()
            while name in current_members:
                name = generate_name()
            motivation = random.randint(0, 100000)
            changes.append(f"+ {name} {motivation}")
            current_members.add(name)
    
    return N, initial_members, M, changes

def print_test_case(N, initial_members, M, changes):
    print(N)
    for name, motivation in initial_members:
        print(f"{name} {motivation}")
    print(M)
    for change in changes:
        print(change)

# Example usage
N, initial_members, M, changes = tcgen()
print_test_case(N, initial_members, M, changes)
```

### Explanation
1. **Function `generate_name`**:
   - Generates a random name of length between 1 and 20 characters using upper and lowercase English letters.

2. **Function `tcgen`**:
   - Generates the number of initial members \(N\) and initializes an empty list for initial members.
   - For each initial member, it generates a name and a motivation level, then adds them to the list.
   - Generates the number of changes \(M\) and initializes an empty set for current members (to keep track of members currently in ACM).
   - For each change, it randomly decides whether to add a new member or remove an existing one (if there are any current members). When adding, it ensures no duplicate names.

3. **Function `print_test_case`**:
   - Helper function to print out the generated test case in the required format.

### Usage
- Run the `tcgen` function to generate a test case.
- Use the `print_test_case` function to print the generated test case in the format required by the problem.

This will give you a variety of test cases with diverse inputs, helping you thoroughly test your solution to the problem.

Extract Arguments

def extract_arguments(fh):
    N = int(fh.readline().strip())
    members = []
    for _ in range(N):
        name, motivation = fh.readline().strip().split()
        motivation = int(motivation)
        members.append((name, motivation))
    
    M = int(fh.readline().strip())
    changes = []
    for _ in range(M):
        change = fh.readline().strip().split()
        if change[0] == '+':
            changes.append((change[0], change[1], int(change[2])))
        else:
            changes.append((change[0], change[1]))
    
    return N, members, M, changes