Базовый курс. Решение ДЗ №3
Представляем решение третьего домашнего задания.
К сожалению, у Вас недостаточно прав для просмотра этой записи. Если Вы еще не залогинены на сайте — залогиньтесь. Если Вы оплачивали курс, у Вас активирован токен доступа, Вы залогинены, но Вы видите эту запись — напишите нам на e-mail поддержки.
Мне не совсем понятен алгоритм определения количества рабочих дней в году, почему вы проверяете необработанные дни только с начала года, ведь неполные недели могут быть как в начале так и конце года?
Существует следующий тезис, и я с ним согласен, что если есть возможность решить задачу двумя способами причем первый из них более сложный для понимания, но более быстрый, а второй, наоборот более понятный, но медленнее первого, то выбрать следует второй из них после вычислительные возможности современных ПК практически нивелируют разницу.
Решил проверить этот тезис на этом примере.
Пусть первый алгоритм (условно назовем его “быстрый”) это ваш алгоритм, а второй (“медленный”) это полностью понятный алгоритм с перебором всех дней года.
Для замера быстродействия этих алгоритмов использовались возможности 1С замер производительности, каждый из алгоритмов запускался по 10 раз.
Результаты получились следующими:
1. “быстрый” алгоритм среднее время исполнения по результатам 10 запусков 0,000120 сек.
2. “медленный” – 0,0001242.
Если выразить разницу в процентах “быстрый” алгоритм выполняется быстрее “медленного” на 3,78%.
Поэтому высказывание уважаемого OL цитата: “Решение намного выигрывает по сравнению с перебором всех дней года” не соответствует действительности и в данном случае я бы выбрал “медленный” алгоритм как более понятный.
Разумеется все вышесказанное IMHO. Интересно услышать мнение коллег по этому поводу.
>ведь неполные недели могут быть как в начале так и конце года?
Могут быть. А разве есть разница? :)
Попробую объяснить.
В общем случае можно утверждать, что в любом году (даже на Альфа Центавра) есть Х целых недель.
Далее, зная, количество дней в году D, можно определить разницу Y = D – Х*7. Y это и есть количество дней в неполной неделе.
Можно достоверно сказать, что в Х неделях 2*Х выходных (сб и вс).
Все что нам осталось сделать это определить количество суббот и воскресений в Y днях. Y мы можем отсчитывать как от начала года, так и от его конца.
Это совершенно не важно. Согласны? Ведь в оставшихся днях мы точно знаем – содержится Х целых недель.
Что касается замера производительности, то интересный результат.
Для меня даже неожиданный. Если разница действительно такая незначительная, то лучше выбирать перебор дней.
И, возможно, ключемым в моем решении то, что Х недель это не обязательно недели с понедельника по воскресенье.
А, например, со среды до вторника, ведь все равно выходных будет Х*2.
Выскажу свое мнение. Согласна, что в условиях цейтнота скорее всего не стала бы анализировать структуру года и просто перебрала бы дни в цикле. С другой стороны и в реальной жизни бывают задачи, которые без выявления в исходных данных какой-нибудь скрытой закономерности не решаются. А когда и потренироваться в изобретательности как не при обучении :)
Кроме изучения новых материалов, цель наших курсов – “размять” мозги, показать не стандартные решения и оптимальные пути :)
Возможно решение выигрывает без перебора, но что-то не так. У меня закрадавается подозрение, что не учтены дни, которые в последней неделе года? Например, 31 декабря понедельник… В двух словах, если можно, отпишитесь, спс.
И еще проверил результаты по своему решению – с перебором, 2015 и 2019 года – у Евгения 259 дней, у меня – 258. Считал вручную по календарю 2015 – таки 258 должно быть.
Довольно таки странно.
Решил проверить, написал алгоритм перебора, выдает результат 259 дней.
Вот такой код:
Года.Добавить(2015);
Года.Добавить(2019);
Для Каждого ЭлементГод Из Года Цикл
Год = ЭлементГод.Значение;
НачалоГода = НачалоГода(Дата(Год,1,1));
КонецГода = КонецГода(Дата(Год,1,1));
Января1 = Дата(Год,1,1);
Февраля23 = Дата(Год,2,23);
Марта8 = Дата(Год,3,8);
Праздники = Новый СписокЗначений;
Праздники.Добавить(Января1);
Праздники.Добавить(Февраля23);
Праздники.Добавить(Марта8);
ТекДата = НачалоГода;
РабочихДней = 0;
Пока ТекДата<=КонецГода Цикл
Если ДеньНедели(ТекДата)<=5 Тогда
Если Праздники.НайтиПоЗначению(ТекДата) = Неопределено Тогда
РабочихДней = РабочихДней+1;
КонецЕсли;
КонецЕсли;
ТекДата = ТекДата + 24*3600;
КонецЦикла;
Сообщить(Строка(Год)+" - "+РабочихДней);
КонецЦикла;
Прошу прощения, Евгений, это я невнимательно праздники ввел. 8 марта представил как 0803 вместо 0308, соответственно подсчет шел с учетом 2 августа. После исправления все совпало, виноват…
Ок :)
Небольшое замечание :-)
когда Вы говорите про “Длительность года в секундах”, то Вы говорите что это:
ДлительностьГодаВСекундах = Дата(2010,12,31) – Дата(2010,1,1)
Но если говорить более точно, то это
ДлительностьГодаВСекундах = Дата(2011,1,1) – Дата(2010,1,1)
Т.к. В Вашей формуле Вы потеряли собственно день.
согласны?
Все верно говорите.
Но, насколько я помню, это значение не используется в дальнейшем. Правильно?
а все я понял. дз № 3 изменили.
Да, верно.
Сделали более логично – структура в 4-ом ДЗ.
Решение намного выигрывает по сравнению с перебором всех дней года
Согласен, интересное решение.
Part 04 ?
Разве она должна быть?
Структуры нет.