Упомянутый процесс написания компилятора coffeescript на coffeescript является стандартным подходом при написании компиляторов. См. раскрутка компилятора.
Про Node.js на coffee — что-то странное. Он всё-таки на JS и C++, а кофе в нём нет. Хотя кто-то предлагал.
Ну расскажите мне, как умножив на какую-либо константу половину раза, Вы сможете вычислить корень из переменной (корни из констант, очевидно, не нужны — это те же константы).
Предположим, что мы как-то придумали возведение в степень. Скомбинировали тысячу различных извращений (включая ряды Тейлора, Маклорена, Лорана — кого пожелаете) и получили его (а точнее — её, чудесно-волшебную матрицу, возводящую элементы любого вектора в некоторую степень, допустим, 3). Т.е. мы получили для вектора v (пусть он будет таким: [ a b 1 ]) матрицу M, такую, что v * M = [ a³ … … ]. Тогда имеем для произвольного λ: λ[ a b 1 ] * M = [ λa λb λ ] * M = [ (λa)³ … … ]
с другой стороны λ[ a b 1 ] * M = λ ([ a b 1 ] * M) = λ [ a³ … … ] = [ λa³ … … ]
Таким образом, λa³ = (λa)³, a = 0 (возводить нули в степень скучно) => λ = λ³, но у нас-то λ любое!
Очевидно, что если бы такая матрица M существовала, но она должна была бы зависеть от текущих переменных, т.е. являться функцией вектора M(v). А это ломает всё, что мы здесь придумали — цепочку вычислений
v = v * M1v
v = v * M2v
…
v = v * Mnv
(для упрощения скобки у вызовов функции опущены) Мы уже не сможем «свернуть» так же просто, как в статье. Разве что
v = v * M1v * M2(v * M1v) * M3(v * M1v * M2(v * M1v)) * … * Mn(v * M1v * M2(v * M1v) * … * Mn-1(…))
однако вычислять это в таком виде — очевидно, феерическая глупость.
— querySelectorAll'у требуется обвязка в виде конвертации результатов из коллекции в массив.
— Для выбора прямых наследников узла по селектору нужно либо итерировать childNodes (возможно, избавляясь от текстовых узлов), либо как-то извращаться с querySelectorAll (как именно — не очевидно на первый взгляд).
— node.querySelectorAll — слишком длинно (да, в консоли есть автокомплит, но он не всегда работает).
На стадии прототипирования Когда всё, что требуется — несколько строк разметки статистики о топике, важно быстро получить рабочее решение, а не тратить сотни человекочасов, планируя и реализуя гибкую и масштабируемую архитектуру.
P.S. Все рассуждения были проведены в рамках моего решения.
P.P.S. Резюмируя всё вышесказанное, напомню ещё раз (или проясню, если это не очевидно), что инструменты я выбирал, стараясь максимизировать скорость написания скрипта. Ни о какой мнимой задаче последующей доработки скрипта речи, разумеется, не было.
Как по мне, так изобретать свой велосипед, когда доступа заботливо подключенная разработчиками Хабра мощная библиотека — вот что странно.
Впрочем, ежели Вам так нравится велосипедостроение с последующих хождением по граблям…
Аж на 71 символ длиннее, чем если использовать jQuery :-)
А ещё это не освобождает от необходимости конвертирования childNodes в массив тем же образом (хотя, быть может, хватило бы node.querySelector('>div.message'), но это тоже длинно, да и требует проверки)
Выпилить оттуда jQuery не составит никакого труда. Я использовал его лишь потому, что писать document.querySelectorAll, а потом делать из коллекции массив слишком утомительно.
А я использовал JS. Писать на чём-либо вне браузера мне сразу расхотелось, ибо нужен приличный парсер, а в браузере уже всё готово — есть DOM (да ещё и jQuery на хабре используется).
Поэтому по-быстрому был написан скрипт, генерирующий статистику.
При желании это можно оформить в виде какого-нибудь букмарклета, только основательно подпилив — производительностью скрипт не блещет, так что его следует либо оптимизировать, либо модифицировать так, чтобы он не блокировал JS поток (Вряд ли тут помогут воркеры, т.к. вся нагрузка, на мой взгляд, идёт из взаимодействия с DOM, так что первый вариант, пожалуй, перспективнее).
Библия олпимпиадника — это Алгоритмы. Построение и анализ Кормена (Лейзерстона, Ривеста и Штайна). Типовых задач тут нет (хотя есть различные упражнения), но все основные алгоритмы описаны. Многие алгоритмы описаны здесь, да и на хабре частенько встречаются интересные статьи.
Ну и главное — практика. codeforces, topcoder, есть множество сайтов с архивами задач (timus, например)
Про Node.js на coffee — что-то странное. Он всё-таки на JS и C++, а кофе в нём нет. Хотя кто-то предлагал.
Предположим, что мы как-то придумали возведение в степень. Скомбинировали тысячу различных извращений (включая ряды Тейлора, Маклорена, Лорана — кого пожелаете) и получили его (а точнее — её, чудесно-волшебную матрицу, возводящую элементы любого вектора в некоторую степень, допустим, 3). Т.е. мы получили для вектора v (пусть он будет таким: [ a b 1 ]) матрицу M, такую, что v * M = [ a³ … … ]. Тогда имеем для произвольного λ:
λ[ a b 1 ] * M = [ λa λb λ ] * M = [ (λa)³ … … ]
с другой стороны
λ[ a b 1 ] * M = λ ([ a b 1 ] * M) = λ [ a³ … … ] = [ λa³ … … ]
Таким образом, λa³ = (λa)³, a = 0 (возводить нули в степень скучно) => λ = λ³, но у нас-то λ любое!
Очевидно, что если бы такая матрица M существовала, но она должна была бы зависеть от текущих переменных, т.е. являться функцией вектора M(v). А это ломает всё, что мы здесь придумали — цепочку вычислений
v = v * M1v
v = v * M2v
…
v = v * Mnv
(для упрощения скобки у вызовов функции опущены) Мы уже не сможем «свернуть» так же просто, как в статье. Разве что
v = v * M1v * M2(v * M1v) * M3(v * M1v * M2(v * M1v)) * … * Mn(v * M1v * M2(v * M1v) * … * Mn-1(…))
однако вычислять это в таком виде — очевидно, феерическая глупость.
— Для выбора прямых наследников узла по селектору нужно либо итерировать childNodes (возможно, избавляясь от текстовых узлов), либо как-то извращаться с querySelectorAll (как именно — не очевидно на первый взгляд).
— node.querySelectorAll — слишком длинно (да, в консоли есть автокомплит, но он не всегда работает).
На стадии прототипированияКогда всё, что требуется — несколько строк разметки статистики о топике, важно быстро получить рабочее решение, а не тратить сотни человекочасов, планируя и реализуя гибкую и масштабируемую архитектуру.P.S. Все рассуждения были проведены в рамках моего решения.
P.P.S. Резюмируя всё вышесказанное, напомню ещё раз (или проясню, если это не очевидно), что инструменты я выбирал, стараясь максимизировать скорость написания скрипта. Ни о какой мнимой задаче последующей доработки скрипта речи, разумеется, не было.
Вот поэтому лучше переиспользовать уже существующий код — меньше кода = меньше ошибок.
Впрочем, ежели Вам так нравится велосипедостроение с последующих хождением по граблям…
А ещё это не освобождает от необходимости конвертирования childNodes в массив тем же образом (хотя, быть может, хватило бы node.querySelector('>div.message'), но это тоже длинно, да и требует проверки)
P.S. Лучше тогда уж как-то так Что длиннее уже на 94 символа :-)
Поэтому по-быстрому был написан скрипт, генерирующий статистику.
При желании это можно оформить в виде какого-нибудь букмарклета, только основательно подпилив — производительностью скрипт не блещет, так что его следует либо оптимизировать, либо модифицировать так, чтобы он не блокировал JS поток (Вряд ли тут помогут воркеры, т.к. вся нагрузка, на мой взгляд, идёт из взаимодействия с DOM, так что первый вариант, пожалуй, перспективнее).
Ну и главное — практика. codeforces, topcoder, есть множество сайтов с архивами задач (timus, например)