Определение биоритмов
{Программа для определения физической, эмоциональной и интеллектуальной активности человека. Вводится дата рождения и текущая дата. Программа вычисляет и выводит на экран общее количество дней, часов, минут и секунд, разделяющих обе даты, а также прогнозирует на месяц вперед даты, соответствующие максимуму и минимуму биоритмов. Описание программы см. п. 2. 7. 2.}
const
Size_of_Month: array [1..12] of Byte =
(31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31);
var
d0, d,{Дни рождения и текущий}
m0, m,{Месяцы рождения и текущий}
y0, y,{Годы рождения и текущий}
dmin,{Наименее благоприятный день}
dmax,{Наиболее благоприятный день}
days: Integer;{Количество дней от рождения}
{--------------------------}
Procedure InputDates(var d0,m0,y0,d,m,y : Integer);
{Вводит дату рождения и текущую дату. Контролирует правильность дат и их непротиворечивость(текущая дата должна быть позже даты рождения)}
var
correctly: Boolean; {Признак правильного ввода}
{-------------------}
Procedure InpDate(text: String; var d,m,y: Integer);
{Выводит приглашение TEXT, вводит дату в формате ДД ММ ГГГГ и проверяет ее правильность}
const
YMIN =1800; {Минимальный правильный год}
YMAX =2000; {Максимальный правильный год}
begin {InpDate}
repeat
Write(text);
ReadLn(d,m,y);
correctly := (y >= YMIN) and (Y <= YMAX) and (m >= 1)
and (m <= 12) and (d > 0);
if correctly then
if (m = 2) and (d = 29) and (y mod 4=0)
then
{Ничего не делать: это 29 февраля високосного года!}
else
correctly := d <= Size_of_Month[m];
if not correctly then
WriteLn('Ошибка в дате!')
until correctly
end; {InpDate}
{----------------}
begin {InputDates}
repeat
InpDate('Введите дату рождения в формате ДД ММ ГГГГ:',d0,m0,y0);
InpDate(' Введите текущую дату: ', d, m, у);
{Проверяем непротиворечивость дат:}
correctly := у > у0;
if not correctly and (y = y0) then
begin
correctly := m > m0;
if not correctly and (m = m0) then
correctly := d >= d0
end
until correctly
end; {InputDates}
{-----------------}
Procedure Get_number s_of_days (d0,m0, y0,d,m, у : Integer; var days: Integer);
{Определение полного количества дней, прошедших от одной даты до другой }
{-------------------}
Procedure Variant2 ;
{Подсчет количества дней в месяцах, разделяющих обе даты }
var
mm : Integer;
begin {Variant2}
mm : = m0 ;
while mm < m do
begin
days := days + Size_of_Month[mm] ;
if (mm = 2) and (y0 mod 4=0) then
inc(days) ;
inc (mm)
end
end; {Variant2}
{---------------}
Procedure Variant3 ;
{Подсчет количества дней в месяцах и годах, разделяющих обе даты}
var
mm, yy : Integer;
begin {variant3}
mm := m0 + 1;
while mm <= 12 do {Учитываем остаток года рождения:}
begin
days := days+Size_of_Month[mm] ;
if (mm = 2) and (yO mod 4=0) then
inc (days) ;
inc (mm)
end;
yy := y0 + 1;
while yy < у do {Прибавляем разницу лет:}
begin
days := days + 365;
if yy mod 4=0 then
inc (days) ;
inc (yy)
end;
mm : = 1 ;
while mm < m do {Прибавляем начало текущего года:}
begin
days := days + Size_of_Month[mm] ;
if (y mod 4=0) and (mm = 2) then
inc (days) ;
inc (mm)
end
end; {Variant3}
{--------------------}
begin {Get_numbers_of_days}
if (y = y0) and (m = m0) then {Даты отличаются только днями:}
days := d - d0
else {Даты отличаются не только днями: }
begin
days := d + Size_of_Month[m0] - d0;
{Учитываем количество дней в текущем месяце и количество дней до конца месяца рождения}
if (y0 mod 4=0) and (m0 = 2) then
inc (days) ; {Учитываем високосный год}
if у = y0 then
Variant2 {Разница в месяцах одного и того же года}
else
Variant3 {Даты отличаются годами}
end
end; {Get_numbers_of_days}
{-------------------}
Procedure FindMaxMin(var dmin, dmax: Integer; days: Integer) ;
{Поиск критических дней}
const
TF = 2*3.1416/23.6884; {Период физической активности}
ТЕ = 2*3.1416/28.4261; {Период эмоциональной активности}
TI = 2*3.1416/33.1638; {Период интеллектуальной активности}
INTERVAL = 30;{Интервал прогноза}
var
min,{Накапливает минимум биоритмов}
max,{Накапливает максимум биоритмов}
x : Real;{Текущее значение биоритмов}
i : Integer;
begin {FindMaxMin}
max := sin(days*TF)+sin(days*TE)+sin(days*TI);
min := max; {Начальное значение минимума и максимума равно значению биоритмов для текущего дня}
dmin := days;
dmax := days ;
for i := 0 to INTERVAL do
begin
x := sin((days+i)*TF) + sin((days+i)*TE) +
sin((days+i)*TI);
if x > max then
begin
max := x;
dmax := days + i
end
else
if x < min then
begin
min := x;
dmin := days + i
end
end;
end; {FindMaxMin}
{----------------}
Procedure WriteDates (dmin, dmax, days : Integer);
{Определение и вывод дат критических дней. Вывод дополнительной информации о количестве прожитых дней, часов, минут и секунд }
{-------------}
Procedure WriteDatettext: String; dd: Integer);
{Определение даты для дня DD от момента рождения. В глобальных переменных d, m и у имеется текущая дата, в переменной DAYS - количество дней, прошедших от момента рождения до текущей даты. Выводится сообщение TEXT и найденная дата в формате ДД-МЕС-ГГГГ}
const
Names_of_Monthes : array [1..12] of String [3] = ( ' янв ' , ' фев ' , ' мар ' , ' апр ' , ' мая '' июн ',
' июл ' , ' авг ' , ' сен ' , ' окт ' , ' ноя ',' дек ' ) ;
var
d0,m0,y0,ddd : Integer;
begin {WriteDate}
d0 := d;
m0 := m;
y0 := y;
ddd := days;
while ddd<>dd do
begin
inc(d0); {Наращиваем число}
if (y0 mod 4 <> 0) and (d0 > Size_of_Month [m0] ) or
(y0 mod 4=0) and (d0=30) then
begin{Корректируем месяц}
d0 := 1;
inc(m0);
if m0 = 13 then{Корректируем год}
begin
m0 := 1;
inc(y0)
end
end;
inc(ddd)
end;
WriteLn(text,d0, ' - ' , Names_of_Monthes [m0] , ' - ' ,y0)
end; {WriteDate}
{------------------}
var
LongDays: Longlnt; {"Длинная" целая переменная для часов, минут и секунд }
begin {WriteDates}
LongDays := days;
WriteLn ( ' Пропшо : ', LongDays,' дней, ' , longDays*24,
' часов, ',LongDays*24*60,'минут,',LongDays*24*60*60,'секунд');
WriteDate (' Наименее благоприятный день: ',dmin);
WriteDate ( 'Наиболее благоприятный день: ',dmax)
end ; { WriteDates}
{------------------}
begin {Главная программа}
InputDates (d0,m0,y0,d, m, у) ;
Get_numbers_of_days (d0,m0,y0,d,m,y,days) ;
FindMaxMin (dmin, dmax, days) ;
WriteDates (dmin, dmax, days)
end .