Иллюстрированный самоучитель по Turbo Pascal

Биоритмы

Давно известно, что творческая и физическая активность человека не остается постоянной, циклически меняется, причем периодичность ее изменения приблизительно согласуется с периодом вращения Луны вокруг Земли. Существует теория, согласно которой физическая, эмоциональная и интеллектуальная активность человека подчиняется соответствующим биоритмам. Каждый биоритм представляет собой синусоиду со строго постоянным периодом, причем для каждого биоритма существует свой период. В отдельные дни все три биоритма человека могут достигнуть своего максимума и тогда человек испытывает подъем творческих и физических сил, в такие дни у него все спорится, он легко решает проблемы, которые в другое время ему решить гораздо сложнее. Точно также существуют и "черные" дни, соответствующие спаду всех трех биоритмов.

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

Алгоритм программы можно укрупнено записать следующим образом:

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

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

Procedure InputDates(var d0,m0,y0,d,m,y: Integer);
{Вводит дату рождения и текущую дату. Контролирует правильность дат и их
непротиворечивость (текущая дата должна быть позже даты рождения) }
begin {InputDates}
end; {InputDates}
{……………………..}
Procedure Get_count_pf_days (dO,mO,yO,d,m,y: Integer;
var days: Integer);
{Определяет полное количество дней, прошедших от одной даты до другой}
begin {Get_count_of_days}
end; {Get_count_of_days}
{--------------------------}
Procedure FindMaxMin (var dmin,dmax: Integer; days: Integer);
{Ищет критические дни}
begin {FindMaxMin}
end; {FindMaxMin}
{--------------------------}
Procedure WriteDates (dmin, dmax, days: Integer);
{Определяет критические даты по количеству дней, прошедших от
момента рождения, и выдает эти даты на экран}
begin {WriteDates}
end; {WriteDates}
{--------------------------}
var
d0,d, {Дни рождения и текущий}
m0,m, {Месяцы рождения и текущий}
у0,у, {Годы рождения и текущий}
dmin, {Наименее благоприятный день}
dmax, {Наиболее благоприятный день}
days: Integer; {Количество дней от рождения}
begin {Главная программа}
Input-Dates (d0,m0,y0,d,m,y);
Get_numbers_of_days (d0,m0,y0,d,m,y,days);
FindMaxMin (dmin, dmax, days);
WriteDates (dmin, dmax, days)
end.

Начинаем детализацию программы. Прежде всего подумаем, как по двум датам вычислить разделяющее их количество дней? Если вспомнить, что следует учитывать неодинаковое количество дней по месяцам года, а также 29 февраля для високосных лет, то ответ на этот вопрос окажется не таким уж простым. Предлагаемый алгоритм подсчета количества дней заключается в вычислении количества дней от даты рождения до конца месяца, а затем и года рождения, количества дней, от начала текущего года до текущего месяца и текущей даты, а также – в подсчете количества полных лет, разделяющих обе даты.

Количество лет затем легко пересчитывается в количество дней с учетом длины года (365 дней для обычных и 366 дней для високосных лет). Это очень прямолинейный алгоритм, но, откровенно говоря, мне не пришло в голову ничего другого. Возможно, существует более изящный способ подсчета и Вы его знаете, тогда программная реализация будет другой.

Если Вы заметили ошибку, выделите, пожалуйста, необходимый текст и нажмите CTRL + Enter, чтобы сообщить об этом редактору.