Problem p01040 - Generation 2

Orig Description

Problem D: Friday the 13th
Problem
The "Ritsumeikan University Programming Camp" is held again this year. I'm looking forward to this camp, which is held every year. However, I couldn't resist my desires and spent a lot of money before the camp, so I ran out of money. Therefore, I decided to use the cheapest "Seishun 18 ticket" to travel to Minami-Kusatsu, the nearest station to Ritsumeikan University. This ticket is cheap, but requires many transfers and takes a whole day to travel, so it is very tiring. I realized that the day I was going to travel was Friday the 13th after leaving Aizuwakamatsu Station. I was forced to ride the train for 12 hours while feeling anxious.
Today is the second day of the camp, March 15, 2015, Sunday. Although nothing special happened on the 13th, and I arrived at Minami-Kusatsu, I didn't want to experience such anxiety again. Therefore, as the judge of the second day of the camp, I decided to give a problem that asks for the number of Friday the 13ths that exist within a specified period and have the participants write a program to solve it.
The definition of a leap year is as follows.
A year that is divisible by 4 is a leap year.
However, a year that is divisible by 100 is not a leap year.
However, a year that is divisible by 400 is a leap year.
Input
Six integers Y1, M1, D1, Y2, M2, D2 separated by a space are given in one line.
Constraints
The input satisfies the following constraints.
1 ≤ Y1 ≤ Y2 ≤ 1018
1 ≤ Mi ≤ 12
1 ≤ Di ≤ 31 (Mi = 1, 3, 5, 7, 8, 10, 12)
1 ≤ Di ≤ 30 (Mi = 4, 6, 9, 11)
1 ≤ Di ≤ 28 (Mi = 2 and Yi is not a leap year)
1 ≤ Di ≤ 29 (Mi = 2 and Yi is a leap year)
Y1, M1, D1 is a date that is at least 0 days before Y2, M2, D2
Output
Output the number of Friday the 13ths that exist between Y1, M1, D1 and Y2, M2, D2 on one line.
Sample Input1
2015 3 13 2015 3 13
Sample Output1
1
Sample Input2
2015 2 14 2015 3 15
Sample Output2
1
Sample Input3
1234 5 6 789012345678901234 5 6
Sample Output3
1357101234567708000

Extracted Specification

Six integers Y1, M1, D1, Y2, M2, D2 separated by a space are given in one line.

1 ≤ Y1 ≤ Y2 ≤ 10^18
1 ≤ Mi ≤ 12
1 ≤ Di ≤ 31 (Mi = 1, 3, 5, 7, 8, 10, 12)
1 ≤ Di ≤ 30 (Mi = 4, 6, 9, 11)
1 ≤ Di ≤ 28 (Mi = 2 and Yi is not a leap year)
1 ≤ Di ≤ 29 (Mi = 2 and Yi is a leap year)
Y1, M1, D1 is a date that is at least 0 days before Y2, M2, D2

### Example Input:

```
2015 3 13 2015 3 13
```

### Function Signature:
Write a function f(inputs) that takes in the input. 
def f(inputs: List[Tuple[int, int, int, int, int, int]]): 
    ''' 
    inputs: a list of tuples, where each tuple contains six integers
    '''

Test Case Generator

Sure, I can help you create a test case generator for the "Friday the 13th" problem. Below is a Python function that will generate test cases while adhering to the given constraints:

```python
import random
import datetime

def is_valid_date(year, month, day):
    try:
        datetime.date(year, month, day)
        return True
    except ValueError:
        return False

def generate_date_range():
    # Generate start date
    Y1 = random.randint(1, 2022) # Keeping the upper bound reasonable for testing purposes
    M1 = random.randint(1, 12)
    
    if M1 in {1, 3, 5, 7, 8, 10, 12}:
        D1 = random.randint(1, 31)
    elif M1 in {4, 6, 9, 11}:
        D1 = random.randint(1, 30)
    elif M1 == 2:
        if (Y1 % 4 == 0 and Y1 % 100 != 0) or (Y1 % 400 == 0):
            D1 = random.randint(1, 29)
        else:
            D1 = random.randint(1, 28)
    
    start_date = datetime.date(Y1, M1, D1)
    
    # Generate end date
    max_year = random.randint(Y1, 2022)
    Y2 = random.randint(Y1, max_year)
    M2 = random.randint(1, 12)
    
    if M2 in {1, 3, 5, 7, 8, 10, 12}:
        D2 = random.randint(1, 31)
    elif M2 in {4, 6, 9, 11}:
        D2 = random.randint(1, 30)
    elif M2 == 2:
        if (Y2 % 4 == 0 and Y2 % 100 != 0) or (Y2 % 400 == 0):
            D2 = random.randint(1, 29)
        else:
            D2 = random.randint(1, 28)
    
    end_date = datetime.date(Y2, M2, D2)
    
    # Ensure the end date is not before the start date
    if start_date > end_date:
        start_date, end_date = end_date, start_date
    
    return start_date.year, start_date.month, start_date.day, end_date.year, end_date.month, end_date.day

def tcgen(num_cases=10):
    test_cases = []
    for _ in range(num_cases):
        Y1, M1, D1, Y2, M2, D2 = generate_date_range()
        test_cases.append(f"{Y1} {M1} {D1} {Y2} {M2} {D2}")
    return test_cases

# Example usage of the test case generator
for test_case in tcgen():
    print(test_case)
```

### Explanation:
1. **is_valid_date Function**: This helper function checks if a given date is valid. It uses the `datetime.date` constructor to verify the date.
  
2. **generate_date_range Function**: This function generates a valid start date and a valid end date while ensuring that the end date is not before the start date.
   - **Selecting Y1, M1, D1**: Randomly selects a year (`Y1`), month (`M1`), and day (`D1`) while considering the number of days in each month and checking for leap years.
   - **Selecting Y2, M2, D2**: Similarly selects a valid end year (`Y2`), month (`M2`), and day (`D2`).
   - Ensures that the end date is not before the start date. If it is, it swaps the start and end dates.

3. **tcgen Function**: This function generates multiple test cases by calling `generate_date_range` multiple times. The number of test cases can be specified by the `num_cases` parameter.

This generator will create a variety of valid date ranges for the problem, ensuring comprehensive test coverage.

Extract Arguments

def extract_arguments(fh):
    Y1, M1, D1, Y2, M2, D2 = map(int, fh.readline().strip().split())
    return Y1, M1, D1, Y2, M2, D2