Problem p01040 - Generation 1

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

An integer Y1 (1 ≤ Y1 ≤ 10^18).
An integer M1 (1 ≤ M1 ≤ 12).
An integer D1 (1 ≤ D1 ≤ 31).
An integer Y2 (1 ≤ Y2 ≤ 10^18).
An integer M2 (1 ≤ M2 ≤ 12).
An integer D2 (1 ≤ D2 ≤ 31).

### Example Input:

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

### Function Signature:
Write a function f(Y1, M1, D1, Y2, M2, D2) that takes in the input.
def f(Y1: int, M1: int, D1: int, Y2: int, M2: int, D2: int):
    '''
    Y1: an integer
    M1: an integer
    D1: an integer
    Y2: an integer
    M2: an integer
    D2: an integer
    '''

Test Case Generator

Sure, I can help you write a test case generator for the "Friday the 13th" problem. The generator will produce random values for \(Y1\), \(M1\), \(D1\), \(Y2\), \(M2\), and \(D2\) within the given constraints. Here's how we can accomplish this in Python:

```python
import random
from datetime import datetime, timedelta

def is_leap_year(year):
    """Determine if a given year is a leap year."""
    return (year % 4 == 0 and year % 100 != 0) or (year % 400 == 0)

def generate_random_date(year):
    """Generate a random valid date within a given year."""
    month = random.randint(1, 12)
    
    # Determine the maximum day for the selected month
    if month == 2:
        if is_leap_year(year):
            day = random.randint(1, 29)
        else:
            day = random.randint(1, 28)
    elif month in {4, 6, 9, 11}:
        day = random.randint(1, 30)
    else:
        day = random.randint(1, 31)
    
    return year, month, day

def tcgen():
    # Randomly choose Y1 and Y2 such that 1 ≤ Y1 ≤ Y2 ≤ 10^18
    Y1 = random.randint(1, 10**4)  # Using a smaller upper limit for practical reasons
    Y2 = random.randint(Y1, 10**4)
    
    # Generate random valid dates for Y1 and Y2
    Y1, M1, D1 = generate_random_date(Y1)
    Y2, M2, D2 = generate_random_date(Y2)
    
    # Ensure that the generated date range is valid
    start_date = datetime(Y1, M1, D1)
    end_date = datetime(Y2, M2, D2)
    
    if start_date > end_date:
        start_date, end_date = end_date, start_date
    
    Y1, M1, D1 = start_date.year, start_date.month, start_date.day
    Y2, M2, D2 = end_date.year, end_date.month, end_date.day
    
    return f"{Y1} {M1} {D1} {Y2} {M2} {D2}"

# Example usage
print(tcgen())
```

This script takes into account the constraints given for the dates and ensures that the generated date range is valid. The range for years is limited to a smaller upper limit for practical reasons to avoid extremely large numbers, but you can adjust this as needed.

### Explanation:

1. **Leap Year Calculation**: The `is_leap_year` function determines if a given year is a leap year.
2. **Random Date Generation**: The `generate_random_date` function generates a random valid date within a given year, considering month-specific days.
3. **Test Case Generation (`tcgen`)**:
    - It generates random values for the years \(Y1\) and \(Y2\) ensuring \(Y1 \leq Y2\).
    - It uses the `generate_random_date` function to generate valid dates for the years.
    - It ensures the start date is not after the end date by comparing and swapping if necessary.

The `tcgen` function returns a valid test case as a single string, formatted as required by the problem statement.

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