function cal(y,m) {
const t = v => ~~ v;
const l = y%4;
const r = [];
let c=(t(23*m/9)+(m<3?y--:y-2)+5+t(y/4)-t(y/100)+t(y/400))%7;
const e = 29+(62648012+16*!l>>m*2&3);
for(let d =1, w = 0; d < e; ++d){
if(!r[w]) {
r[w] = [,,,,,,,];
}
r[w][c]=d;
c = ++c%7;
w += !c;
}
return r;
}
Следуя вашим советам, убрал побитовые сдвиги, расставил отступы и сделал осмысленные имена.
Да, теперь решение стало на 100% не читаемым. За длинными именами переменных теряется смысл простых формул. Представьте, если бы математики вместо x и i использовали бы counter и incrementor. Читабельны бы были формулы? - Ну, формулы бы были однозначно длиннее. Теоретически, это придавало бы автору важности, но не среди математиков.
А теперь, о сравнительных характеристиках кода.
Я уже заметил. что код стал не читаемым для людей. К сожалению, он также стал более затратно-исполнимым для webkit (полагаю, и для других движков тоже). Видите ли, мой код написан с точки зрения ФП приблизительно идеально (без побочных эффектов), а в последнем решении присутствует аж три замыкания. Я честн попробовал оптимизировать код тремя инструментами: WebPack, Babel, Google Closure Compiler. Что я могу сказать про расхваленный вами WebPack. WebPack не только не оптимизировал ни одного замыкания, он просто наплодил в два раза больше новых замыканий. От чего мне стало даже грустно за WebPack. Но факт остаётся фактом, он справляется хорошо лишь с одной задачей - убирать пробелы там, где они явно лишние. Оптимизатор JavaScript игнорирует код с замыканиями. Безусловно, такой код будет работать в десятки раз медленнее, при этом забирая в десятки раз больше ресурсов. Мой же код будет работать также быстро, как будто я его написал на чистом си.
Что касается читаемости кода. Вы знаете, я немного слукавил когда отметил что underscore имеет операции "побитовые сдвиги" в своём коде. Позже выяснилось, что они там были, но в комментариях. Так как я запускал поиск используя ack по всему репозиторию, я заметил это не сразу. Похоже, действительно, боженька не всех одарил математикой. Но, лично для меня, например, код
m >> n * 2
куда понятнее, чемMath.trunc ( m / Math.pow ( 2, n * 2 ) )
. Аналогично этому, если бы, например, я не знал таблицу умножения и категорически избегал таких операций какm = x * y
, реализуя циклом . Вы смеётесь, а такое я встречаю постоянно. Там тоже самое: простая формула в одну операцию с логарифмом заменена целой программой разными циклами. У кого-то вызывает сложности безопасный арктангенсMath.atan2()
[ссылку добавлю чуть позже]. Что тут сказать?! И среди программистов порой случаются гуманитарии.Вечером опубликую сравнительные тесты производительности, параметры оптимизаций WebPack, Babel и GCC. Будет занятно детально проанализировать огромную разницу в производительности.