If28. Дан номер года (положительное целое число). Определить количество дней в этом году, учитывая, что обычный год насчитывает 365 дней, а високосный — 366 дней. Високосным считается год, делящийся на 4, за исключением тех годов, которые делятся на 100 и не делятся на 400 (например, годы 300, 1300 и 1900 не являются високосными, а 1200 и 2000 — являются).
Решение:
1 2 3 4 5 6 7 8 9 10 11 12 13 |
program if28; var Y: Integer; begin Write('Введите год: '); Readln (Y); if (y mod 100)=0 then if (y mod 400)=0 then Writeln ('366') else Writeln ('365') else if (y mod 4)=0 then Writeln ('366') else Writeln ('365'); end. |
Решение 2:
1 2 3 4 5 6 7 8 9 10 |
var A: integer; begin Write('Введите год: '); Readln (Y); if (Y mod 4 = 0) and ((Y mod 100 <> 0) or (Y mod 400 = 0)) then writeln('366') else writeln('365'); end. |
Другие задачи из раздела If можно посмотреть здесь.
А так не проще?
К сожалению так сложнее. 🙂
Переведём предложение на язык логики:
«Високосным считается год, делящийся на 4, за исключением тех годов, которые делятся на 100 и не делятся на 400 (например, годы 300, 1300 и 1900 не являются високосными, а 1200 и 2000 — являются).»
Вот здесь рекомендация к автору учебника :). То что можно вынести в отдельное предложение, лучше вынести в отдельное предложение, а то это не читабельно. Хотя может быть автор учебника этого и добивался, поэтому первая итерация убрать всё что в скобках.
«Високосным считается год, делящийся на 4, за исключением тех годов, которые делятся на 100 и не делятся на 400.»
Теперь переводим на язык математической логики, перевод я буду писать в фигурных скобках.
год = A
«Високосным считается год {true = }, делящийся на 4 { (A mod 4 = 0)}, за исключением тех годов { and not( }, которые делятся на 100 { (a mod 100 = 0) } и {and} не { not( } делятся на 400 {(A mod 400 = 0)} . {предложение закончилось поэтому закрываем скобки все скобки их две ) )}.
В итоге у нас получилось:
true = (A mod 4 = 0) and not( (A mod 100 = 0) and not(( A mod 400 =0)))
получилось в конце слишком много скобок убираем лишнии для красоты…
true = (A mod 4 = 0) and not( (A mod 100 = 0) and not(A mod 400 =0))
теперь по закону общей инверсии так же известный как закон Моргана, раскрываем вот это : «not( (A mod 100 = 0) and not(A mod 400 =0))»
true = (A mod 4 = 0) and ( not (A mod 100 = 0) or not(not(A mod 400 =0)))
по закону двойного отрицания убираем два not
true = (A mod 4 = 0) and ( not (A mod 100 = 0) or (A mod 400 =0))
здесь я думаю можно и остановиться, так как следующие шаги только усложнят и без того сложную формулу .
ну и запишем всё это в код:
ну и теперь про вычислительные мощности…. 🙂
в моём предыдущем решении
для получения результата я всегда! делаю два целочисленных деления. (if это по сути go to и не так значим по моему скромному мнению).
В получившемся решении… мы отдаём всё в руки компилятора, если он умный то вычислений будет от 1 до 3 в зависимости от значений. Если не очень, то всегда 3.
Вывод… данное решение имеет место быть. Но оно сложное для понимания и не факт, что мы получим хоть какой то выигрыш в вычислительном процессе.
Но спасибо, что обратили внимания, при решении данной задачи я поленился вычислять второе решение. А так целая статья получилась, может кому будет интересно. 🙂