Math: sum and faculty

D

Daniel Schierbeck

I hereby propose two additions to Ruby. Please come with some comments
before I file an RCR.


Range#sum
=========

Usage
-----

(lower_limit..upper_limit).sum { |i| expression }


Implementation
--------------

class Range
def sum
raise ArgumentError unless block_given?

result = 0.0
each { |i| result += yield(i) }

result
end
end


Notes
-----

Could also be implemented as Math#sum



Integer#faculty
===============

Usage
-----

n.faculty # => n * (n - 1) * (n - 2) ... 1


Implementation
--------------

class Integer
def faculty
self == 0 ? 1 : self * (self - 1).faculty
end
end




Cheers,
Daniel
 
H

HaPK

Daniel said:
Range#sum
=========

This could be done with Enumerable#inject. Your implementation assumes
that range is for values of Float class.
Integer#faculty
===============

Implementation
--------------

class Integer
def faculty
self == 0 ? 1 : self * (self - 1).faculty
end
end
(1..self).inject(1) { |result, x| result*x }

would be more compact.

Am I missing something, but why "faculty" ? Why not factorial ?
 
R

Robert Klemme

This should go into Enumerable if at all.
This could be done with Enumerable#inject.
Exactly.

Your implementation assumes
that range is for values of Float class.

Even more so as this restriction does not apply when using inject:

# the sum of all members
enum.inject {|a,b| a + b}

Although, if you want to apply some expression to the value even with
inject you are going to need some starting value unless you do the mapping
beforehand:

# all work
enum.inject(0) {|s,a| s + expr(a)}
enum.inject(0.0) {|s,a| s + expr(a)}
enum.map {|a| expr(a)}.inject {|a,b| a + b}
(1..self).inject(1) { |result, x| result*x }

would be more compact.

You can even do
=> 3628800

Hint: if there is no argument to #inject the first pair in the block is
fed the first and second element.
Am I missing something, but why "faculty" ? Why not factorial ?

Maybe because of http://akas.imdb.com/title/tt0133751 ? :))

To sum up, #sum seems too specialized. #inject is there and does the job
quite nicely - and easily.

Kind regards

robert
 
M

Martin DeMello

Robert Klemme said:
To sum up, #sum seems too specialized. #inject is there and does the job
quite nicely - and easily.

Actually, something in between would be quite nice in terms of code
aesthetics. I'm thinking of the specialised but very common case of a
binary accumulator and a unary function, thus (calling it 'accumulate'
for want of a better name):

sum = enum.accumulate(0, :+) {|x| f(x)}
collect = enum.accumulate([], :<<) {|x| f(x)}

and if you leave off the block, it simply applies f(x) = x. It avoids
cluttering the block with the accumulator the way inject does.

martin
 
R

Robert Klemme

Martin said:
Actually, something in between would be quite nice in terms of code
aesthetics. I'm thinking of the specialised but very common case of a
binary accumulator and a unary function, thus (calling it 'accumulate'
for want of a better name):

sum = enum.accumulate(0, :+) {|x| f(x)}

The difference isn't really that big, is it?
sum = enum.inject(0) {|s,x| s + f(x)}
collect = enum.accumulate([], :<<) {|x| f(x)}

I prefer
collect = enum.map {|x| f(x)}
collect = enum.collect {|x| f(x)}
and if you leave off the block, it simply applies f(x) = x. It avoids
cluttering the block with the accumulator the way inject does.

Personally I don't find the "s +" to be cluttering the block. At least
not enough to justify adding this to Enumerable. My 0.02EUR...

Kind regards

robert
 
G

Greg Graham

Martin DeMello wrote:
Personally I don't find the "s +" to be cluttering the block. At least
not enough to justify adding this to Enumerable. My 0.02EUR...

The cool thing about Ruby is that if you don't like the clutter, you
can easily add the method to Enumerable for your own programs.

Greg
 
C

Christophe Grandsire

HaPK said:
Am I missing something, but why "faculty" ? Why not factorial ?

It's just a (not so much used in my experience) synonym for "factorial"
AFAIK. Incidently (and coincidently :) ), I first saw this word used as
a synonym of factorial a few days ago only, in the Haskell98 report. The
little I've seen it when googling seems to indicate that its use is
limited to programming. The term "factorial" is by far the most used.
--
Christophe Grandsire.

http://rainbow.conlang.free.fr

You need a straight mind to invent a twisted conlang.
 
S

Sean O'Halpin

sum =3D enum.accumulate(0, :+) {|x| f(x)}

How about

module Enumerable

def accumulate(initial, method, &block)
if not block_given?
block =3D proc {|x| x}
end
inject(initial) {|accumulator, value|
#
# apply block to input value
#
accumulator.send(method, block.call(value))
}
end

end

It's worth getting to know inject however.

Sean
 
M

Martin DeMello

Sean O'Halpin said:
How about

module Enumerable

def accumulate(initial, method, &block)

It's worth getting to know inject however.A

Definitely. OTOH, it's also worth stepping back every so often and
seeing if you can "pretty up" your code.

(Incidentally, a fun exercise to get familiar with inject is to try
writing all of Enumerable in terms of inject rather than each.)

martin
 
C

Christophe Grandsire

Christian said:
=20
The real reason is probably that both "factorial" (maths) and
"faculty" (university) mean "Fakult=E4t" in German... :)
=20

Must be! :) However, I found this use in at least one page about Java,=20
and another one (although I don't remember which language it was about,=20
and I can't find it right now), and they didn't strike me as having been=20
written by Germans...
--=20
Christophe Grandsire.

http://rainbow.conlang.free.fr

You need a straight mind to invent a twisted conlang.
 
D

Dominik Bathon

Must be! :) However, I found this use in at least one page about Java, = =20
and another one (although I don't remember which language it was about,= =20
and I can't find it right now), and they didn't strike me as having bee= n =20
written by Germans...

It seems to be similar in Danish (fakultet), Dutch (fakulteit) and Swedis=
h =20
(fakultet) (from =20
http://www.websters-online-dictionary.org/definition/factorial). And I =20
think Daniel actually is from Denmark...
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Similar Threads


Members online

Forum statistics

Threads
473,777
Messages
2,569,604
Members
45,234
Latest member
SkyeWeems

Latest Threads

Top