{Программа для определения физической, эмоциональной и интеллектуальной активности человека. Вводится дата рождения и текущая дата. Программа вычисляет и выводит на экран общее количество дней, часов, минут и секунд, разделяющих обе даты, а также прогнозирует на месяц вперед даты, соответствующие максимуму и минимуму биоритмов. Описание программы см. п.2.7.2. книги 1} 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,y); {Проверяем непротиворечивость дат:} correctly := y > y0; 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_numbers_of_days(d0,m0,y0,d,m,y: 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 (y0 mod 4 = 0) then inc(days); inc(mm) end; yy := y0 + 1; while yy < y 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 y = 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; {Период физической активности} TE = 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 WriteDate(text: string; dd: integer); {Определение даты для дня DD от момента рождения. В глобальных переменных d, m и y имеется текущая дата, в переменной 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: LongInt; {"Длинная" целая переменная для часов, минут и секунд } 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,y); Get_numbers_of_days(d0,m0,y0,d,m,y,days); FindMaxMin(dmin,dmax,days); WriteDates(dmin,dmax,days) end.