Valid date from three integers in any order

0
Sign in

You are given three integers a, b and c. Their order is unknown: any one of them may be the year, the month or the day. This covers formats such as yyyy-MM-dd, MM-dd-yyyy and dd-MM-yyyy.

Implement:

def can_form_date(a: int, b: int, c: int) -> bool: ...
def all_valid_dates(a: int, b: int, c: int) -> list[tuple[int, int, int]]: ...
  • can_form_date returns True if at least one assignment of the three numbers to (year, month, day) is a real calendar date.
  • all_valid_dates returns every distinct valid (year, month, day), sorted chronologically.

A date is valid when:

  • 1 <= year <= 9999
  • 1 <= month <= 12
  • 1 <= day <= the number of days in that month of that year. February has 29 days in a leap year and 28 otherwise.
  • A leap year is divisible by 4, except century years, which must also be divisible by 400 (2000 is a leap year, 1900 is not).

Inputs may be zero, negative or larger than 9999. Such values are never valid in any role.

Example 1

Input:  a = 30, b = 1987, c = 7
can_form_date   -> True
all_valid_dates -> [(1987, 7, 30)]

Only year 1987, month 7, day 30 works. 30 and 1987 can't be months.

Example 2

Input:  a = 2, b = 1900, c = 29
can_form_date   -> False

February 29, 1900 does not exist, because 1900 is not a leap year. No other assignment has a month between 1 and 12 with a valid day and year.

Example 3

Input:  a = 6, b = 6, c = 2021
all_valid_dates -> [(2021, 6, 6)]

Two permutations give the same date, and it is listed once.

GoogleCodingEasy

Sign in to see the worked answer

The full answer, chapter by chapter, with what interviewers expect at each level. Free with an account: one full answer per company.