Problem p00732 - Generation 3

Orig Description

Problem E: Twirl Around
Let's think about a bar rotating clockwise as if it were a
twirling baton moving on a planar surface surrounded by a
polygonal wall (see Figure 1).
Figure 1.  A bar rotating in a polygon
Initially, an end of the bar (called "end A") is at (0,0), and
the other end (called "end B") is at (0,L) where L is the
length of the bar.  Initially, the bar is touching the wall only
at the end A.
The bar turns fixing a touching point as the center.
The center changes as a new point touches the wall.
Your task is to calculate the coordinates of the end A when the
bar has fully turned by the given count R.
Figure 2.  Examples of turning bars
In Figure 2, some examples are shown.  In cases (D) and
(E), the bar is stuck prematurely (cannot rotate clockwise anymore 
with any point touching the wall as the center)
before R rotations.  In such cases, you should answer the
coordinates of the end A in that (stuck) position.
You can assume the following:
When the bar's length L changes by ε (|ε| <
0.00001), the final (x,y) coordinates
will not change more than 0.0005.
Input
The input consists of multiple datasets.  The number of
datasets is no more than 100.  The end of the input is represented
by "0 0 0".
The format of each dataset is as follows:
L R N
X1 Y1
X2 Y2
...
XN YN
L is the length of the bar.
The bar rotates 2π× R radians (if it is not
stuck prematurely).
N is the number of vertices which make the polygon.
The vertices of the polygon are arranged in a counter-clockwise order.
You may assume that the polygon is simple, that is,
its border never crosses or touches itself.
N, Xi and Yi are
integer numbers; R and L are decimal fractions.
Ranges of those values are as follows:
1.0 ≤ L ≤ 500.0,
1.0 ≤ R ≤ 10.0,
3 ≤ N ≤ 100,
-1000 ≤ Xi ≤ 1000,
-1000 ≤ Yi ≤ 1000,
X1 ≤ -1,  Y1 = 0,
X2 ≥ 1,  Y2 = 0.
Output
For each dataset, print one line containing x- and
y-coordinates of the final position of the end A,
separated by a space.
The value may contain an error less than or equal to 0.001.
You may print any number of digits after the decimal point.
Sample Input
4.0 2.0 8
-1 0
5 0
5 -2
7 -2
7 0
18 0
18 6
-1 6
4.0 2.0 4
-1 0
10 0
10 12
-1 12
4.0 1.0 7
-1 0
2 0
-1 -3
-1 -8
6 -8
6 6
-1 6
4.0 2.0 6
-1 0
10 0
10 3
7 3
7 5
-1 5
5.0 2.0 6
-1 0
2 0
2 -4
6 -4
6 6
-1 6
6.0 1.0 8
-1 0
8 0
7 2
9 2
8 4
11 4
11 12
-1 12
0 0 0
Output for the Sample Input
16.0 0.0
9.999999999999998 7.4641016151377535
0.585786437626906 -5.414213562373095
8.0 0.0
6.0 0.0
9.52786404500042 4.0
Note that the above sample input corresponds to the
cases in Figure 2.  For convenience, in Figure 3, we will show an
animation and corresponding photographic playback for the case (C).
Figure 3.  Animation and photographic playback for case (C)

Extracted Specification

An integer L (1.0 ≤ L ≤ 500.0), representing some length.
A decimal R (1.0 ≤ R ≤ 10.0), representing some count.
An integer N (3 ≤ N ≤ 100), representing some quantity.
N pairs of integers (Xi, Yi) (-1000 ≤ Xi ≤ 1000, -1000 ≤ Yi ≤ 1000), where each pair represents coordinates.

### Example Input:

```
4.0 2.0 8
-1 0
5 0
5 -2
7 -2
7 0
18 0
18 6
-1 6
```

### Function Signature:
Write a function f(inputs) that takes in the input as a list of tuples. 
def f(inputs: List[Tuple[float, float, int, List[Tuple[int, int]]]]): 
    ''' 
    inputs: a list of tuples, where each tuple contains:
        L: a decimal
        R: a decimal
        N: an integer
        coordinates: a list of tuples of integers
    '''

Test Case Generator

Here is a Python function to generate test cases for the "Twirl Around" problem statement:

```python
import random

def generate_dataset():
    # Length of the bar (1.0 ≤ L ≤ 500.0)
    L = round(random.uniform(1.0, 500.0), 6)
    
    # Rotations (1.0 ≤ R ≤ 10.0)
    R = round(random.uniform(1.0, 10.0), 6)
    
    # Number of vertices (3 ≤ N ≤ 100)
    N = random.randint(3, 100)
    
    # Generate vertices (Xi, Yi) for the polygon
    vertices = []
    
    # Ensure the first vertex meets the condition X1 ≤ -1, Y1 = 0
    first_vertex = (random.randint(-1000, -1), 0)
    vertices.append(first_vertex)
    
    # Ensure the second vertex meets the condition X2 ≥ 1, Y2 = 0
    second_vertex = (random.randint(1, 1000), 0)
    vertices.append(second_vertex)
    
    # Generate the remaining vertices
    for _ in range(N - 2):
        x = random.randint(-1000, 1000)
        y = random.randint(-1000, 1000)
        vertices.append((x, y))
    
    # Ensure the vertices are in counter-clockwise order (convex polygon)
    vertices = sorted(vertices, key=lambda v: (v[1], v[0]))
    
    # Format dataset as a string
    dataset = f"{L} {R} {N}\n"
    for vertex in vertices:
        dataset += f"{vertex[0]} {vertex[1]}\n"
    
    return dataset

def tcgen():
    # Number of datasets (up to 100)
    num_datasets = random.randint(1, 100)
    
    # Generate datasets
    datasets = [generate_dataset() for _ in range(num_datasets)]
    
    # Add the end of input indicator "0 0 0"
    datasets.append("0 0 0\n")
    
    # Join datasets into a single string
    input_data = ''.join(datasets)
    
    return input_data

# Example usage
if __name__ == "__main__":
    print(tcgen())
```

This code generates a random test case for the "Twirl Around" problem, ensuring that the conditions specified for the input are met. Each dataset includes the length of the bar \(L\), the number of rotations \(R\), and the vertices of the polygon. The function `tcgen()` generates up to 100 such datasets and appends the end-of-input indicator "0 0 0" at the end.

Extract Arguments

def extract_arguments(fh):
    datasets = []
    while True:
        L, R, N = map(float, fh.readline().strip().split())
        if L == 0 and R == 0 and N == 0:
            break
        N = int(N)
        vertices = []
        for _ in range(N):
            X, Y = map(int, fh.readline().strip().split())
            vertices.append((X, Y))
        datasets.append((L, R, N, vertices))
    return datasets

# if __name__ == "__main__":
#     input_path = sys.argv[1]
#     with open(input_path, 'r') as fh:
#         datasets = extract_arguments(fh)
#         for dataset in datasets:
#             f(*dataset)