# one way to write a factorial function

100 views

### prhlava

Nov 23, 2008, 4:08:48 PM11/23/08
to Clojure

Hello folks,

While learning, it occured to me that factorial function can be
written as:

(defn factorial [n]
(apply * (for [x (range 1 (+ n 1))] x)))

I know that it has big argument list for large numbers, but it seems
to scale nicely (at least in clojure).

I am sure this was discussed to death in lisp groups - have searched
the net and did not find this version...

kind regards,

### prhlava

Nov 23, 2008, 5:46:38 PM11/23/08
to Clojure

Wow, the apply version above is faster (but not much) than the version
on:

http://clojure.org/special_forms

the "apply" version run 8.55 [minutes]
the special_forms version run 9.50 [minutes]

(this was for n=100000 on and old P3)

Beginners luck I suppose...

PS: Displaying the number takes a long time, I had run (time
(factorial 100000)) in both cases, which prints the time before
displaying the result...

### Randall R Schulz

Nov 23, 2008, 6:05:33 PM11/23/08
On Sunday 23 November 2008 14:46, prhlava wrote:
> Wow, the apply version above is faster (but not much) than the
> version on:

Usually a 10% running time reduction is nothing to sneeze at. (I
interpreted your notation as decimal minutes. If it's minutes and
seconds, then speed-up is about 10.7%).

> http://clojure.org/special_forms
>
> the "apply" version run 8.55 [minutes]
> the special_forms version run 9.50 [minutes]
>
> (this was for n=100000 on and old P3)
>
> Beginners luck I suppose...

Sure. And I could do anything Jackson Pollock did...

>
> PS: Displaying the number takes a long time, I had run (time
> (factorial 100000)) in both cases, which prints the time before
> displaying the result...

Randall Schulz

### Craig Andera

Nov 23, 2008, 8:00:26 PM11/23/08
Clever!

Help me understand why this isn't written

(defn factorial [n]
(apply * (range 1 (+ n 1)))

instead. That is, I don't get the purpose of the for statement.

### Stuart Sierra

Nov 23, 2008, 10:59:55 PM11/23/08
to Clojure
That "for" should be equivalent to just "range" by itself. It can be
even shorter:

(defn factorial [n]
(apply * (range 2 (inc n))))

You can replace "apply" with "reduce" and it's just as fast, at least
for n up to 10,000. I don't have the patience to wait for 100,000.

-Stuart Sierra

On Nov 23, 8:00 pm, "Craig Andera" <craig.and...@gmail.com> wrote:
> Clever!
>
> Help me understand why this isn't written
>
> (defn factorial [n]
>   (apply * (range 1 (+ n 1)))
>
> instead. That is, I don't get the purpose of the for statement.
>

### prhlava

Nov 24, 2008, 6:04:23 AM11/24/08
to Clojure
> Help me understand why this isn't written
>
> (defn factorial [n]
>   (apply * (range 1 (+ n 1)))
>
> instead. That is, I don't get the purpose of the for statement.

Neither do I now ;-),

nice,