Даты

В этом листке вам нужно будет решать задачи, связанные с датами и временем, поэтому прежде всего нужно понять, как хранить даты и время в программе. Конечно, лучше всего для типа данных “Дата” создать класс.

class Date:

У объектов этого класса будет три поля: Day, Month, Year.

Подумайте, какие операции можно выполнять с датами. Например, можно преобразовывать даты в строки для удобного вывода или, наоборот, преобразовывать строки в даты. К датам можно прибавлять (вычитать) целые числа (например, прибавить число 1 — это получить следующую дату). Наконец, можно брать разность двух дат (это количество дней между ними).

Для преобразования номера месяца в строку лучше всего использовать константный список строк-названий:

MonthNames = ('', 'January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December')
Для вывода названия дней недели также лучше использовать список:
DayOfTheWeek = ('Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday')

А вот для преобразования строки-названия месяца в число лучше использовать словарь:

MonthNums = {'January': 1, 'February': 2, 'March': 3, ...}

Упражнения

A: День года

По заданному числу n от 1 до 365 определите, на какое число какого месяца приходится день невисокосного года с номером n. Программа получает на вход целое число n и должна вывести два числа: число месяца (от 1 до 31) и номер месяца (от 1 до 12), на которое приходится данный день.

Для определения номера дня в году лучше всего использовать константный массив количества дней в каждом месяце:

Months = (0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31)

Пример

Ввод Вывод
1
January 1
365
December 31

B: Обратная задача

Решите обратную предыдущей задачу: по записи названия месяца и дня определите номер дня в году.
Алгоритм решения задачи оформите в виде отдельной функции.

Пример

Ввод Вывод
January 1
1
December 31
365

C: Перевод формата даты - 1

Дата задана в формате dd.mm.yyyy. Выведите ее в формате "Month d, y", где Month - английское название месяца, d - номер дня в месяце, без лидирующих нулей, y - номер года без лидирующих нулей.

Считывание и преобразование даты оформляйте в виде отдельных методов класса.

Пример

Ввод Вывод
12.10.2008
October 12, 2008
01.01.0001
January 1, 1

D: Перевод формата даты - 2

Решите обратную задачу.

Считывание и преобразование даты оформляйте в виде отдельных методов класса.

Пример

Ввод Вывод
October 12, 2008
12.10.2008
January 1, 1
01.01.0001

E: Tomorrow

Дата задана в формате dd.mm.yyyy. Выведите дату, следующую за ней в том же формате. Учтите правило формирования високосных годов. Следует считать, что григорианский календарь действовал всегда.

Алгоритм решения задачи оформите в виде метода NextDate() класса

Пример

Ввод Вывод
12.10.2008
13.10.2008
31.12.2008
01.01.2009

F: Yesterday

Дата задана в формате dd.mm.yyyy. Выведите дату, предшестующую ей в том же формате. Учтите правило формирования високосных годов. Следует считать, что григорианский календарь действовал всегда.
Алгоритм решения задачи оформите в виде отдельного метода PrevDate() класса.

Пример

Ввод Вывод
13.10.2008
12.10.2008
01.01.2009
31.12.2008

G: Разница дат

Две даты заданы в формате dd.mm.yyyy, каждая дата - в новой строке. Определите количество дней между этими датами. Вторая дата больше первой.
Алгоритм решения задачи оформите в виде метода __sub__

Пример

Ввод Вывод
01.01.0001
02.01.0001
1
29.02.2004
01.03.2005
366

H: День недели

Дата задана в формате dd.mm.yyyy. Выведите название дня недели, на который приходится эта дата.
Алгоритм решения задачи оформите в виде отдельного метода.
Ввод Вывод
12.10.2008
Sunday
13.10.2008
Monday

I: День рождения

Задан день и месяц рождения в формате dd.mm. Задана текущая дата в формате dd.mm.yyyy. Определите, сколько дней осталось до дня рождения. Если сегодня - день рождения, то необходимо вывести 0.

Ввод Вывод
19.04
19.04.2002
0
05.05
19.04.2002
16
29.02
28.02.2001
1096

J: Разница дат - 2

Научитесь быстро вычислять разницу между двумя датами.

Программа получает на вход число N, не превосходящее 105. Далее идет 2N дат, записанных, как в задаче G.

Выведите N чисел: для каждой пары дат входного файла выведите их разность.

Ввод Вывод
2
01.01.0001
02.01.0001
29.02.2004
01.03.2005
1
366

Время

Для хранения времени удобно создать класс Time с полями hours, minutes, seconds.

Времена будут, как правило, задаваться в формате hh:mm:ss, где hh принимает значения от 00 до 23, mm и ss - значения от 00 до 59 или в формате hh:mm.

Упражнения

K: Количество секунд

Часы показывают время в формате hh:mm:ss. Определите количество секунд, которое прошло с начала суток.
Программа не должна содержать циклов для решения этой задачи.

Пример

Ввод Вывод
00:01:01
61

L: Таймер

Часы показывают время в формате hh:mm:ss. На этих часах запустили таймер, который прозвенит через n секунд. Определите время, которое будет на часах, когда прозвенит таймер. n может принимать значения от 0 до 109. Решение задачи не дожно содержать циклов. Постарайтесь также не использовать условную инструкцию.

Пример

Ввод Вывод
09:00:00
90
09:01:30
23:59:59
1
00:00:00

M: Разница времен

Профессор лег спать, когда на часах было время h1:m1:s1, а когда он проснулся было время h2:m2:s2. Определите, сколько времени спал профессор, если известно, что он проспал не более суток. Время выведите в формате hh:mm:ss.
Решение задачи не должно содержать циклы. Постарайтесь также не использовать условную инструкцию.

Пример

Ввод Вывод
14:00:00
21:10:30
07:10:30
22:00:00
07:00:00
09:00:00

N: Севшая батарейка

В часах села батарейка и они стали идти вдвое медленней. Когда на часах было  время h1:m1:s1, точное время было h2:m2:s2. Определите, точное время, когда часы в следующий раз покажут время h3:m3:s3.
Решение задачи не должно использовать циклы.

Пример

Ввод Вывод
12:34:00
10:34:00
12:35:01
10:36:02
12:34:00
10:00:00
02:34:00
14:00:00

O: Будильники

Будильник в сотовом телефоне можно настроить так, чтобы он звонил каждый день в одно и то же время, либо в указанное время в определенный день недели. Независимо можно настроить несколько будильников.

По информации о будильниках и текущему времени и дню недели определите, когда прозвонит очередной будильник.

В первой строке вводится текущий день недели (число от 1 до 7), затем через пробел, текущее время в формате HH:MM.

Во второй строке вводится одно натуральное число N, не превосходящее 100 – количество будильников.

В следующих N строках вводится описание N будильников в таком же формате. Значение дня недели, равное 0, означает, что будильник звонит каждый день.

Выведите номер дня недели и время, когда будильник зазвонит в следующий раз, в таком же формате.

Ввод Вывод
2 10:20
2
1 23:15
0 10:10
3 10:10
7 01:01
3
7 00:59
7 23:59
7 01:01
7 01:01

P: Таймер-2

Таймер - это часы, которые умеют подавать звуковой сигнал по прошествии некоторого периода времени. Напишите программу, которая определяет, когда должен быть подан звуковой сигнал.

Первая строка входных данных содержит текущее время в формате HH:MM:SS (с ведущими нулями). При этом оно удовлетворяет ограничениям: HH — от 00 до 23, MM и SS - от 00 до 59.

Вторая строка входных данных содержит интервал времени, который должен быть измерен. Интервал записывается в формате H:M:S (где H, M и S — от 0 до 109, без ведущих нулей). При этом если H=0 (или H=0 и M=0), то они могут быть опущены. Например, 100:60 может быть записано и как 101:0, 1:41:0, 0:100:60, 0:101:0 и т.д. Запись 42 — это то же самое, что 0:0:42, а 100:100:100 то же самое, что 101:41:40.

Выведите в формате HH:MM:SS время, во сколько прозвучит звуковой сигнал. При этом если сигнал прозвучит не в текущие сутки, то дальше должна следовать запись +<кол во> days. Например, если сигнал прозвучит на следующий день – то +1 days.

Ввод Вывод
01:01:01
48:0:0
01:01:01+2 days
01:01:01
58:119
02:01:00
23:59:59
1
00:00:00+1 days

Q: Кассы

На одном из московских вокзалов билеты продают N касс. Каждая касса работает без перерыва определенный промежуток времени по фиксированному расписанию (одному и тому же каждый день). Требуется определить, на протяжении какого времени в течение суток работают все кассы одновременно.

Программа получает на вход целое число N (0<N≤1000).

В каждой из следующих N строк записано время начало и время окончания работы кассы в формате HH:MM через пробел.

Время открытия означает, что в соответствующую ему минуту касса уже работает, а время закрытия что в соответствующую минуту касса уже не работает. Например, касса, открытая с 10:30 18:30 ежесуточно работает 480 минут.

Если время открытия совпадает с временем закрытия, то касса работает круглосуточно. Если первое время больше второго, то касса начинает работу до полуночи, а заканчивает на следующий день.

Требуется вывести одно число суммарное время за сутки (в минутах), на протяжении которого работают все N касс.

Ввод Вывод
3
01:00 23:00
12:00 12:00
22:00 02:00
120
2
09:30 14:00
14:15 21:00
0
2
14:00 18:00
10:00 14:01
1

R: Самый старший

Имеется список людей с указанием их фамилии, имени и даты рождения. Напишите эффективную по времени работы и по используемой памяти программу, которая будет определять самого старшего человека из этого списка и выводить его фамилию, имя и дату рождения, а если имеется несколько самых старших людей с одинаковой датой рождения, то определять их количество.

На вход программе в первой строке подается количество людей в списке N. В каждой из последующих N строк находится информация в следующем формате:

<Фамилия> <Имя> <Дата рождения>

где <Фамилия> – строка, состоящая не более, чем из 20 символов без пробелов, <Имя> – строка, состоящая не более, чем из 20 символов без пробелов, <Дата рождения> – строка, имеющая вид DD.MM.YYYY.

Программа должна вывести дату рождения самого старшего человека в списке, затем через пробел его фамилию и имя. Если таких людей, несколько, то вместо фамилии и имени выводится их количество.

Ввод Вывод
3
Ivan Petrov 01.05.1995
Petr Sergeev 29.04.1995
Sergey Ivanov 01.01.1996
29.04.1995 Petr Sergeev
3
Ivan Petrov 01.05.1995
Petr Sergeev 29.05.1995
Sergey Ivanov 01.05.1995
01.05.1995 2

S: Дни рождения

Имеется список сотрудников организации с указанием их фамилии, имени и даты рождения. Администрация ежедневно поздравляет всех сотрудников, родившихся в этот день. Напишите эффективную по времени работы и по используемой памяти программу, которая будет определять, в какой из дней года родилось больше всего сотрудников и выводить этот день (или несколько дней).

Формат входных данных аналогичен предыдущей задаче. Программа должна вывести список дат, в которые наибольшее число сотрудников отмечает дни рождения в формате DD.MM по возрастанию дат, каждая дата в отдельной строке.

Ввод Вывод
5
Ivan Petrov 01.05.1995
Petr Sergeev 29.04.1995
Sergey Romanov 01.01.1996
Roman Grigoriev 01.01.1995
Grigoriy Ivanov 01.05.1995
01.01
01.05

T: Ближайшие дни рождения

Имеется список сотрудников организации с указанием их фамилии, имени и даты рождения. Напишите эффективную по времени работы и по используемой памяти программу, которая будет определять фамилию и имя самого молодого сотрудника, празднующего свой день рождения в течение ближайших семи дней от текущей даты (включая текущую дату).

На вход программе в первой сроке подается текущая дата, заданная в формате DD.MM.YYYY.

Во второй строке подается количество людей в списке N. В каждой из последующих N строк находится информация о каждом сотруднике, как в задаче T.

Известно, что у всех сотрудников даты рождения различаются. Программа должна вывести фамилию и имя самого молодого сотрудника, празднующего день рождения в ближайшие 7 дней или сообщение No birthdays in next week, если никто из сотрудников не празднует день рождения в ближайшие 7 дней.

Ввод Вывод
25.11.2010
3
Ivan Petrov 01.12.1994
Petr Sergeev 25.11.1994
Sergey Romanov 02.12.1994
Ivan Petrov
25.11.2010
1
Sergey Romanov 02.12.1994
No birthdays in next week

X: Пятница, 13-е

Докажите, что 13-е число месяца чаще всего приходится на пятницу.
Напишите программу, которая выводит на экран 7 чисел: вероятности выпадения 13 числа каждого месяца на понедельник, вторник, среду, четверг, пятницу, субботу, воскресенье. Например, если бы данные вероятности были бы равны, то программа должна вывести следущий текст:
0.142857
0.142857
0.142857
0.142857
0.142857
0.142857
0.142857

Y: Кассы - 2

Решите задачу про кассы в следующих ограничениях: число касс до 10000, время задано с точностью до секунд в формате HH:MM:SS. Требуется определить, на протяжении какого времени (в секундах) в течение суток работают все кассы одновременно.

Ввод Вывод
3
01:00:00 23:00:00
12:00:00 12:00:00
22:00:00 02:00:00
7200
2
09:30:00 14:00:00
14:15:00 21:00:00
0
2
14:00:00 18:00:00
10:00:00 14:00:01
1

Z: Игра с датами

Играет два человека. Задается какая-то дата високосного года. Каждый игрок на своем ходу называет более позднюю дату, увеличивая на 1 или на 2 либо день в месяце, либо месяц, но не то и другое сразу. При этом результат должен оставаться корректной датой. Игрок, назвавший 31 декабря, проигрывает. Кто выигрывает при правильной игре: первый или второй.

Программа получает на вход дату в формате DD.MM и должна вывести одно число: номер выигрывающего игрока.

Ввод Вывод
30.12
2
29.12
1
29.11
2