Отправляет email-рассылки с помощью сервиса Sendsay
  Все выпуски  

RusFAQ.ru: Программирование на языке Pascal


РАССЫЛКИ ПОРТАЛА RUSFAQ.RU

/ КОМПЬЮТЕРЫ И ПО / Языки программирования / Pascal

Выпуск № 143
от 16.03.2006, 20:05

Администратор:Калашников О.А.
В рассылке:Подписчиков: 158, Экспертов: 45
В номере:Вопросов: 1, Ответов: 1


Вопрос № 37275: Здравствуйте, уважаемые эксперты! В одном учебнике по программированию на Паскале (Рапаков Г.Г., Ржеуцкая С.Ю. Программирование на языке Pascal) встретилась интересная задача - составить программу, определяющую день недели известной даты по совре...

Вопрос № 37.275
Здравствуйте, уважаемые эксперты!
В одном учебнике по программированию на Паскале (Рапаков Г.Г., Ржеуцкая С.Ю. Программирование на языке Pascal) встретилась интересная задача - составить программу, определяющую день недели известной даты по современному европейскому календарю и приводится такой листинг:

var d,m,y:integer; n:longint;
begin
writeln('введите день, месяц, год даты (например: 3 12 1964)');
readln(d,m,y);
if (m>=2) then m:=m+1
else
begin
m:=m+13; y:=y-1;
end;
n:=trunc(365.25*y)+trunc(30.6*m)+d-621050;
n:=n-trunc(n/7)*7+1;
case n of
1: write('понедельник');
2: write('вторник');
3: write('среда');
4: write('четверг');
5: write('пятница');
6: write('суббота');
7: write('воскресенье');
end;
writeln;
end.

Я набирала в Pascal, программа работает. Но алгоритм решения для меня остается абсолютно непонятным. Особенно неясно, откуда берется число 621050. Если нетрудно, пожалуйста, не могли бы вы объяснить эту программу? Я понимаю, наверное, это классическая, элементарная и всем известная задача... но я не волшебник, я только учусь :)

Заранее огромное спасибо,
Helga
Отправлен: 11.03.2006, 19:37
Вопрос задала: Sphinx2005 (статус: Посетитель)
Всего ответов: 1
Мини-форум вопроса >>> (сообщений: 1)

Отвечает: Полховский Александр Владимирович
Здравствуйте, Sphinx2005!
Я там на мини-форуме чуток напутал. Оказалось всё ещё сложнее. Ну, поехали.
Во-первых, 01.01.0001 г. - Понедельник, а не Воскресенье, как я раньше сказал.
Во-вторых, 29-й день Февраля появляется в каждом четвёртом году (0004, 0008...) за исключением каждого сотого года (0100, 0200...), при этом в каждом четырёхсотом году он все же появляется (0400, 0800, 1200, 1600, 2000...).
Таким образом, при подсчёте количества минувших с 01.01.0001 дней необходимо учитывать исчезновение в каждом сотом году 29-го дня Февраля, кроме каждых четырёхсотых.
Вот распределение количества дней в году (Феврале) в зависимости от года: (в приложении, а то читать не удобно).
Надеюсь, понятно.
Ну а дальше, как и ранее, банальные пересчёт с учётом всех этих условий: (3 edit'a для числа, месяца и года, ещё 1 (пятый) для вывода результата; ну это Вы сами разберётесь, думаю)

procedure TForm1.Button3Click(Sender: TObject);
var
n, ny, d, m, y:longint;
begin
d:=strtoint(edit1.Text);//в формате DD (01, 02, 03...)
m:=strtoint(edit2.Text);//в формате MM (01, 02, 03...)
y:=strtoint(edit3.Text);//в формате YYYY (0001, 0002, 2003...)
ny:=y;
n:=trunc(365.25*ny)-365+ny div 400-ny div 100;//-365 за счёт того, что первый год был не 0000; каждые 100 лет убирают 29 Февраля, кроме каждого четырёхсотого года
if (m<=2)and(y mod 4=0)//если год високосный, но ещё не прошёл Февраль, то 29-й день не добавился (если должен был)
then n:=n-1-ord(ny mod 400=0)+ord(ny mod 100=0); //и ещё не отнялся (если должен был) день за 400 лет и не прибавился за 100 лет
//далее заменяем рассчёт поочерёдной проверко, так понятнее, откуда количество дней выплывает
//полностью прошёл месяц - добавили его количество дней
if m>1
then n:=n+31;//если позже Января
if m>2
then n:=n+28;//если позже Февраля (29-й день уже прибавился за счёт 365,25 дней в году)
if m>3
then n:=n+31;//если позже Марта
if m>4
then n:=n+30;//если позже Апреля
if m>5
then n:=n+31;//если позже Мая
if m>6
then n:=n+30;//если позже Июня
if m>7
then n:=n+31;//если позже Июля
if m>8
then n:=n+31;//если позже Августа
if m>9
then n:=n+30;//если позже Сентября
if m>10
then n:=n+31;//если позже Октября
if m>11
then n:=n+30;//если позже Ноября
n:=n+d-1;//прибавляем количество дней, прошедших за текущий месяц, отнимаем начальное первое число отсчёта (01.01.0001)
n:=(n)mod(7)+1; //убираем целое число прошедших недель, и анализируем остаток; +1 так как mod даст от 0 до 6, а нам надо от 1 до 7
case n of
1: Edit5.Text:='понедельник';
2: Edit5.Text:='вторник';
3: Edit5.Text:='среда';
4: Edit5.Text:='четверг';
5: Edit5.Text:='пятница';
6: Edit5.Text:='суббота';
7: Edit5.Text:='воскресенье';
end;
end;

Приложение:

---------
Спасём нашу хрупкую планету !

Ответ отправил: Полховский Александр Владимирович (статус: Студент)
Ответ отправлен: 12.03.2006, 16:31


Отправить вопрос экспертам этой рассылки

Приложение (если необходимо):

* Код программы, выдержки из закона и т.п. дополнение к вопросу.
Эта информация будет отображена в аналогичном окне как есть.

Обратите внимание!
Вопрос будет отправлен всем экспертам данной рассылки!

Для того, чтобы отправить вопрос выбранным экспертам этой рассылки или
экспертам другой рассылки портала RusFAQ.ru, зайдите непосредственно на RusFAQ.ru.


Форма НЕ работает в почтовых программах The BAT! и MS Outlook (кроме версии 2003+)!
Чтобы отправить вопрос, откройте это письмо в браузере или зайдите на сайт RusFAQ.ru.


© 2001-2006, Портал RusFAQ.ru, Россия, Москва.
Идея, дизайн, программирование: Калашников О.А.
Email: adm@rusfaq.ru, Тел.: +7 (926) 535-23-31
Авторские права | Реклама на портале
Версия системы: 4.19 от 14.03.2006
Яндекс Rambler's Top100

В избранное