Здравствуйте, BulatZiganshin, Вы писали:
BZ>Здравствуйте, Андрей Коростелев, Вы писали:
АК>>Кайф получается в языках с tail recursion
BZ>не получится, поскольку формула n*f(n-1) не tail-рекурсивна
А что мешает сделать так?
inline unsigned factorial(unsigned n, unsigned a = 1)
{ return n ? factorial(n - 1, a * n) : a; }
Здравствуйте, R.K., Вы писали:
RK>Здравствуйте, BulatZiganshin, Вы писали:
BZ>>Здравствуйте, Андрей Коростелев, Вы писали:
АК>>>Кайф получается в языках с tail recursion
BZ>>не получится, поскольку формула n*f(n-1) не tail-рекурсивна
RK>А что мешает сделать так? RK>
inline unsigned factorial(unsigned n, unsigned a = 1)
RK>{ return n ? factorial(n - 1, a * n) : a; }
это работает. однако я бы не сказал, что это понятней императивного
a=1
for i in 1..n
a=a*i
вот не tail-recursive вариант — он ясней императивного:
fac 0 = 1
fac n = n * fac(n-1)
Здравствуйте, Igor Sukhov, Вы писали:
IS>Здравствуйте, nikov, Вы писали:
N>>Я бы был осторожен с такими предположениями. Стив МакКоннелл, например, пишет что он уволил бы сотрудника, который бы стал вычислять факториал с помощью рекурсии.
IS>Если Стив действительно такое написал — то помоему он идиот. Или просто позвиздеть любит (т.е. не уволил бы даже еслибы бы кто-то из его работников стал вычислять ф-л рекурсией).
Прежде, чем называть его идиотом, подумайте, в архитектурной перспективе к чему может привести такой стиль программирования. К тому же следует понимать, что такое гипербола в литературе. Если я Вам говорю, что убью всякого, кто наступит мне на мозоль, это не значит, что у меня кортик в заднем кармане брюк и я — хладнокровный убийца.
Здравствуйте, bkat, Вы писали:
B>Здравствуйте, kaselli, Вы писали:
K>>А можно поподробнее? ) K>>Не совсем понимаю, чем хэшированная таблица может помочь вычислению факториала и предотвратить выход за пределы числа
B>Все просто. Например вот так:
А если мне нужен факториал 100, 1000, 100000 и я работаю с длинными числами?
Здравствуйте, NotImplemented, Вы писали:
NI>Здравствуйте, Sergey, Вы писали: S>>Дано: enum { N = x }; x — целочисленный литерал. Требуется объявить массив целых чисел размера N! Язык решения — C++. NI>
NI>template<int N>
NI>struct factorial
NI>{
NI> static const int value = N*factorial<N-1>::value;
NI>};
NI>template<>
NI>struct factorial<0>
NI>{
NI> static const int value = 1;
NI>};
NI>int main()
NI>{
NI> int array[factorial<6>::value];
NI>}
NI>
Ну надо-же написать такую х...ень когда можно
const int factorialTable[ ] = {1, 1, 2, 6, 24, 120, 720, 5040, 40320,
362880, 3628800, 39916800, 479001600};
int main()
{
int array[ factorialTable[6] ];
}
Во первых, размер массивов в стеке многими компиляторами вычисляется в run-time и нет необходимости использовать константу, размер массива обязательно должен быть известен только для global/static/const массивов, которые располагаются в секциях типа bss/cinit.
Во вторых, Вы продемонстирировали виртуозное владение шаблонами, но это выльется в тупое { N=6*5*4*3*2*1; }, только компилер может одуреть реккурсивной инстанциации шаблона. Если 6 известно на этапе компиляции, то можно сразу подставить константу 720.
Очень многие программеры любят демонстирировать технику владения языком в ущерб простоте и понятности. Я видел код гениальный по навороченности, причем настолько гениальный, что сам автор не понимал как он работает. Товарища уволили.
Здравствуйте, FractalizeR, Вы писали:
IS>>Если Стив действительно такое написал — то помоему он идиот. Или просто позвиздеть любит (т.е. не уволил бы даже еслибы бы кто-то из его работников стал вычислять ф-л рекурсией). FR>Прежде, чем называть его идиотом, подумайте, в архитектурной перспективе к чему может привести такой стиль программирования.
какой такой стиль?
что такое "архитектурная перспектива"?
OMFG — написание тривиальной функиции в 10 строк (10 минут на написание и 20 минут на тестирование) как-то влияет на архитектуру в целом? не было такого и не будет.
большинство проблем архитектуры произрастают из двух простых (но от этого не менее печальных) причин:
1. Люди приставленные архитектурить не понимают что и как делать.
2. Люди приставленные присматривать за первыми не видят что первые не понимают что и как делать.
FR>К тому же следует понимать, что такое гипербола в литературе. Если я Вам говорю, что убью всякого, кто наступит мне на мозоль, это не значит, что у меня кортик в заднем кармане брюк и я — хладнокровный убийца.
ну ладно, убедил — идиот это пожалуй не очень точно, точно будет "трепло".
Здравствуйте, Mika Soukhov, Вы писали:
MS>А смысл тогда из-за этих 21-ой итерации делать оптимизацию? Неужели будет переполнения стека? Насколько я помню код функции факториала, там от силы несколько байт стека.
Смысла нет писать код "вычисляющий" факториал. Код содержащий массив из 21 числа и возращающий число по индексу резко проще написать и проверить.
IS>какой такой стиль? IS>что такое "архитектурная перспектива"? IS>OMFG — написание тривиальной функиции в 10 строк (10 минут на написание и 20 минут на тестирование) как-то влияет на архитектуру в целом? не было такого и не будет.
Грубо говоря рекурсия это плохо потому что сложно, есть алгоритмы в которых с рекурсией становится проще, в остальных случаях если её можно избегать лучше избегать из-за сложности понимания.
Не все понимают рекурсию, при развитии кода возможно появление рекурсии в рекурсии, циклической рекурсии и т.п.
IS>большинство проблем архитектуры произрастают из двух простых (но от этого не менее печальных) причин:
IS>1. Люди приставленные архитектурить не понимают что и как делать. IS>2. Люди приставленные присматривать за первыми не видят что первые не понимают что и как делать.
Отличные идеи чтобы сваливать проблемы на плечи архитекторов и менеджеров. Почему баги — неправильная архитектура, архитектор некомпетентен. Почему я не успеваю в срок — неправильное планирование, менеджер некомпетентен. Да они вообще в программировании не понимают!
Здравствуйте, freelancer_spb, Вы писали:
_>Грубо говоря рекурсия это плохо потому что сложно
Грубо говоря, не надо забывать о том, что меньше половины разработчиков вообще понимает что такое рекурсия и как следствие усложнение кода ведет к дополнительным затратам при его поддержке. Если проект пишется не одиночкой, то использование навороченных библиотек поведение которых понимают единицы должно быть запрещено, то же относится и к рекурсиям.
_>Отличные идеи чтобы сваливать проблемы на плечи архитекторов и менеджеров.
А разве это не так? очень верно было сказано.
_>Почему баги — неправильная архитектура, архитектор некомпетентен.
Баги — нет. Трудно поддерживаемая, глючащая на ровном месте система — да.
_> Почему я не успеваю в срок — неправильное планирование, менеджер некомпетентен.
А кто еще виноват? Видимо фаза луны помещала менеджеру учесть все риски и составить корректный план работ?
_>Да они вообще в программировании не понимают!
IS>>какой такой стиль? IS>>что такое "архитектурная перспектива"? IS>>OMFG — написание тривиальной функиции в 10 строк (10 минут на написание и 20 минут на тестирование) как-то влияет на архитектуру в целом? не было такого и не будет.
_>Грубо говоря рекурсия это плохо потому что сложно, есть алгоритмы в которых с рекурсией становится проще, в остальных случаях если её можно избегать лучше избегать из-за сложности понимания. _>Не все понимают рекурсию, при развитии кода возможно появление рекурсии в рекурсии, циклической рекурсии и т.п.
вообще-то я говорил про конкретный случай, который можно кратко описать как "тот кто грозится увольнять за реализацию факториала через рекурсию, просто звиздит". т.е. развовор шел о ф-и в 10 строк на 10 минут написания.
говорить "в общем" я не хочу и поэтому не буду. разве что добавлю — что есть куча достаточно тривиальных задач которые даже я (как человек к-й программирует наверно получше чем 90% здесь присувтвующих) не знаю как решить не-рекусивно. а как рекурсивно — знаю сходу. т.е. ставя запрет на рекурсию — чего мы добиваемся — чтобы озадаченные разработчики потерли голову час-два-день, потом все-таки пошли к человеку который им бы такую ф-ю нарисовал — и что у них от этого больше понимания стало? не-а.
IS>>большинство проблем архитектуры произрастают из двух простых (но от этого не менее печальных) причин:
IS>>1. Люди приставленные архитектурить не понимают что и как делать. IS>>2. Люди приставленные присматривать за первыми не видят что первые не понимают что и как делать.
_>Отличные идеи чтобы сваливать проблемы на плечи архитекторов и менеджеров. Почему баги — неправильная архитектура, архитектор некомпетентен. Почему я не успеваю в срок — неправильное планирование, менеджер некомпетентен. Да они вообще в программировании не понимают!
это не идеи — это как я видел и вижу ситуации изнутри.
притом смотрю я одновременно и с позиции разраба и архитекта.
Здравствуйте, Кэр, Вы писали:
Кэр>Здравствуйте, Mika Soukhov, Вы писали:
MS>>А смысл тогда из-за этих 21-ой итерации делать оптимизацию? Неужели будет переполнения стека? Насколько я помню код функции факториала, там от силы несколько байт стека.
Кэр>Смысла нет писать код "вычисляющий" факториал. Код содержащий массив из 21 числа и возращающий число по индексу резко проще написать и проверить.
Проверять вычисления факториала? Хорошо, люди бывают разные. И если кто-то не уверен (кстати, а не такие ли люди кандидаты номер один на увольнение?), что он сможет написать такой код без ошибок, то всегда есть интернет + CopyPaste.
FR>>Прежде, чем называть его идиотом, подумайте, в архитектурной перспективе к чему может привести такой стиль программирования.
IS>какой такой стиль? IS>что такое "архитектурная перспектива"? IS>OMFG — написание тривиальной функиции в 10 строк (10 минут на написание и 20 минут на тестирование) как-то влияет на архитектуру в целом? не было такого и не будет.
Во-первых, незачем нервничать и плеваться злыми аббревиатурами. Во-вторых, если провести аналогию — если в детстве вы некрасиво писали простую букву А, то это совсем никак не повлияет на вашу каллиграфию при написании более сложных текстов, когда вы станете взрослым? Дисциплина и архитектура начинаются с малого. Никто не учится строить здания с проектирования вращающихся небоскребов, не так ли? Если человек одноэтажный дом будет проектировать криво, с ненужными сложностями, его небоскреб рухнет 100%.
Здравствуйте, kaselli, Вы писали:
K>Драсьте всем! K>Вошел тут малость в ступор.... K>Есть такая общеизвестная задачка — решение факториала. Вроде как любят ее задавать на собеседованиях. K>Скажите мне плз, в чем кайф?
Есть кайф... Вот как можно вычислить факториал на Haskell. Я люблю этот язык ))
— explicit type recursion with functors and catamorphisms
newtype Mu f = In (f (Mu f))
unIn (In x) = x
cata phi = phi . fmap (cata phi) . unIn
— base functor and data type for natural numbers,
— using locally-defined «eliminators»
data N c = Z | S c
instance Functor N where
fmap g Z = Z
fmap g (S x) = S (g x)
type Nat = Mu N
zero = In Z
suck n = In (S n)
add m = cata phi where
phi Z = m
phi (S f) = suck f
mult m = cata phi where
phi Z = zero
phi (S f) = add m f
— explicit products and their functorial action
data Prod e c = Pair c e
outl (Pair x y) = x
outr (Pair x y) = y
fork f g x = Pair (f x) (g x)
instance Functor (Prod e) where
fmap g = fork (g . outl) outr
— comonads, the categorical «opposite» of monads
class Functor n => Comonad n where
extr :: n a -> a
dupl :: n a -> n (n a)
instance Comonad (Prod e) where
extr = outl
dupl = fork id outr
gcata :: (Functor f, Comonad n) =>
(forall a. f (n a) -> n (f a))
-> (f (n c) -> c) -> Mu f -> c
gcata dist phi = extr . cata (fmap phi . dist . fmap dupl)
zygo chi = gcata (fork (fmap outl) (chi . fmap outr))
para :: Functor f => (f (Prod (Mu f) c) -> c) -> Mu f -> c
para = zygo In
fac = para phi where
phi Z = suck zero
phi (S (Pair f n)) = mult f (suck n)
int = cata phi where
phi Z = 0
phi (S f) = 1 + f
instance Show (Mu N) where
show = show . int