Question in factorial program

#+BEGIN_SRC ruby
def f(n)
  (1..n).inject(:*) || 1
end
#+END_SRC

Somebody said that is for factorial.
But i did fail to understand.

What does "inject(:*)" mean?

Any comments welcome!!!

···

--
^고맙습니다 _布德天下_ 감사합니다_^))//

You can think of it as injecting (inserting) "*" between the numbers in the
sequence 1, 2, ..., n so it ends up being:

1 * 2 * ... * n

or, to be more precise

(...((1 * 2) * 3) * ... * n)

Also, instead of using || you can call

(1..n).inject(1, :*)

Quoting Byung-Hee HWANG (황병희, 黃炳熙) (soyeomul@doraji.xyz):

#+BEGIN_SRC ruby
def f(n)
  (1..n).inject(:*) || 1
end
#+END_SRC

Somebody said that is for factorial.
But i did fail to understand.

What does "inject(:*)" mean?

Ruby comes with a nice help tool, called 'ri'.

Try to type

ri inject

You'll read a description of all existing method called 'inject.'
In the case of class Enumerable, something like this:

--8<----8<----8<----8<----8<----8<----8<----8<----8<----8<----8<----8<--
Combines all elements of enum by applying a binary operation,
specified by a block or a symbol that names a method or operator.
--8<----8<----8<----8<----8<----8<----8<----8<----8<----8<----8<----8<--

In practice, (1..n).inject(:*) is equivalent to

1*2*3*...*n

(which gives you the factorial of n...)

It is a nifty method, but I hardly ever use it in real time because it
obfuscates way too much.

Carlo

···

Subject: Question in factorial program
  Date: mer 26 lug 17 08:45:54 +0900

--
  * Se la Strada e la sua Virtu' non fossero state messe da parte,
* K * Carlo E. Prelz - fluido@fluido.as che bisogno ci sarebbe
  * di parlare tanto di amore e di rettitudine? (Chuang-Tzu)

You can think of it as injecting (inserting) "*" between the ...

                                   ^^^^^^^^^^^^^^^^
Cool point! Thank you so much!!!

···

--
^고맙습니다 _布德天下_ 감사합니다_^))//

"Carlo E. Prelz" <fluido@fluido.as> 께서 쓰시길,
《記事 全文 <20170726121459.GC7794@ramingo.fluido.as> 에서》:

In practice, (1..n).inject(:*) is equivalent to

1*2*3*...*n

Carlo you gave me cool example. Thanks, indeed.

···

--
^고맙습니다 _布德天下_ 감사합니다_^))//

By help Greg and Carlo, i wrote tiny code with "inject".

#+BEGIN_SRC ruby
def sum(n)
    (1..n).inject(:+) || 1
end
puts sum(100)
#+END_SRC

The answer is "5050".

The "inject" wins over the Gauss, i think.

···

--
^고맙습니다 _布德天下_ 감사합니다_^))//

If anyone's still playing along, #inject is also an alias for #reduce
-- you may have heard of "MapReduce", it's one half of that --
reducing an enumeration of values down to a single value, using a
repeated operation.

The long form looks a bit like this:

[1,3,5].reduce { |subtotal, e| subtotal + e }

# or with an initial subtotal:
[1,3,4].reduce(0) { |subtotal, e| subtotal + e }

(Similar effects can be achieved using #each_with_object)

To make it simpler, #reduce/#inject accepts a symbol as its final
parameter, which is basically used like this:

# [1,3,5].reduce(:+)  =>
[1,3,5].reduce { |memo, e| memo.__send__(:+, e) }

Further, there's Ruby's special `&foo` syntax that turns `foo` into a
Proc object using its #to_proc method

Symbol#to_proc returns a Proc that is basically:

proc { |first, *rest| first.__send__(this_sym, *rest) }

So you could also write the inject/reduce code as:

[1,3,5].reduce(&:+)

It's pretty neat. You can do dumb stuff like this:

class Integer
  def absplus o
    self.abs + o.abs
  end
end
[1,-3,5].reduce :absplus   # => 9

Cheers

···

--
  Matthew Kerwin
  http://matthew.kerwin.net.au/

This is wrong. I see at least two errors in this implementation.

Kind regards

robert

···

On Thu, Jul 27, 2017 at 2:31 AM, Byung-Hee HWANG (황병희, 黃炳熙) <soyeomul@doraji.xyz> wrote:

By help Greg and Carlo, i wrote tiny code with "inject".

#+BEGIN_SRC ruby
def sum(n)
    (1..n).inject(:+) || 1
end

--
[guy, jim, charlie].each {|him| remember.him do |as, often| as.you_can
- without end}
http://blog.rubybestpractices.com/

This is actually a pretty neat explanation. Thanks for taking the time.

···

Sent from mobile device - Pardon possible typos!

On Jul 26, 2017, at 11:12 PM, Matthew Kerwin <matthew@kerwin.net.au> wrote:

If anyone's still playing along, #inject is also an alias for #reduce
-- you may have heard of "MapReduce", it's one half of that --
reducing an enumeration of values down to a single value, using a
repeated operation.

The long form looks a bit like this:

[1,3,5].reduce { |subtotal, e| subtotal + e }

# or with an initial subtotal:
[1,3,4].reduce(0) { |subtotal, e| subtotal + e }

(Similar effects can be achieved using #each_with_object)

To make it simpler, #reduce/#inject accepts a symbol as its final
parameter, which is basically used like this:

# [1,3,5].reduce(:+)  =>
[1,3,5].reduce { |memo, e| memo.__send__(:+, e) }

Further, there's Ruby's special `&foo` syntax that turns `foo` into a
Proc object using its #to_proc method

Symbol#to_proc returns a Proc that is basically:

proc { |first, *rest| first.__send__(this_sym, *rest) }

So you could also write the inject/reduce code as:

[1,3,5].reduce(&:+)

It's pretty neat. You can do dumb stuff like this:

class Integer
 def absplus o
   self.abs + o.abs
 end
end
[1,-3,5].reduce :absplus   # => 9

Cheers
--
Matthew Kerwin
http://matthew.kerwin.net.au/

Unsubscribe: <mailto:ruby-talk-request@ruby-lang.org?subject=unsubscribe>
<http://lists.ruby-lang.org/cgi-bin/mailman/options/ruby-talk&gt;

Hi Matthew,

Matthew Kerwin <matthew@kerwin.net.au> 께서 쓰시길,
《記事 全文
<CACweHNCaQVeUMHxGB=X9cR5LiiiRqLT+8tx0kOuy2akxrYT+6Q@mail.gmail.com>
에서》:

If anyone's still playing along, #inject is also an alias for #reduce
-- you may have heard of "MapReduce", it's one half of that --
reducing an enumeration of values down to a single value, using a
repeated operation.

The long form looks a bit like this:

[1,3,5].reduce { |subtotal, e| subtotal + e }

# or with an initial subtotal:
[1,3,4].reduce(0) { |subtotal, e| subtotal + e }

(Similar effects can be achieved using #each_with_object)

To make it simpler, #reduce/#inject accepts a symbol as its final
parameter, which is basically used like this:

# [1,3,5].reduce(:+)  =>
[1,3,5].reduce { |memo, e| memo.__send__(:+, e) }

Further, there's Ruby's special `&foo` syntax that turns `foo` into a
Proc object using its #to_proc method

Symbol#to_proc returns a Proc that is basically:

proc { |first, *rest| first.__send__(this_sym, *rest) }

So you could also write the inject/reduce code as:

[1,3,5].reduce(&:+)

It's pretty neat. You can do dumb stuff like this:

class Integer
  def absplus o
    self.abs + o.abs
  end
end
[1,-3,5].reduce :absplus   # => 9

The codes looks Art, beautiful!!
Also i'm happy to hear about that, thanks!!!

···

--
^고맙습니다 _白衣從軍_ 감사합니다_^))//

def sum(n)
    (1..n).inject(:+) || 1
end

This is wrong. I see at least two errors in this implementation.

#+BEGIN_SRC sh
$ /usr/bin/ruby --version
ruby 1.8.7 (2011-06-30 patchlevel 352) [i686-linux]
#+END_SRC

My ruby has no problum, thanks!

···

--
^고맙습니다 _救濟蒼生_ 감사합니다_^))//

I think "wrong" is a strong word. Rather, it's easy to see cases
where it might fail our expectations of how we think it ought to
behave. If the rdoc says "For any positive integer this returns the
mathematical summation from 1 to n; for any non-positive integer it
returns 1. Any other value is implicitly cast to an integer or raises
an ArgumentError" then it's fine.

Cheers

···

On 2 August 2017 at 03:38, Robert Klemme <shortcutter@googlemail.com> wrote:

On Thu, Jul 27, 2017 at 2:31 AM, Byung-Hee HWANG (황병희, 黃炳熙) > <soyeomul@doraji.xyz> wrote:

By help Greg and Carlo, i wrote tiny code with "inject".

#+BEGIN_SRC ruby
def sum(n)
    (1..n).inject(:+) || 1
end

This is wrong. I see at least two errors in this implementation.

Kind regards

robert

--
  Matthew Kerwin
  http://matthew.kerwin.net.au/

Returning 1 as the sum of values between 1 and 0 or 0 and 0 is plain wrong according to current mathematical tradition. Of course, you can always tweak any documentation to exactly reflect what the method does. But I consider that cheating with such a fundamental flaw.
<<<

I see at least three errors in that statement.

Click here to view Company Information and Confidentiality Notice.<http://www.jameshall.co.uk/index.php/small-print/email-disclaimer&gt;

Returning 1 as the sum of values between 1 and 0 or 0 and 0 is plain
wrong according to current mathematical tradition. Of course, you can
always tweak any documentation to exactly reflect what the method
does. But I consider that cheating with such a fundamental flaw.

Kind regards

robert

···

On Wed, Aug 2, 2017 at 7:42 AM, Matthew Kerwin <matthew@kerwin.net.au> wrote:

On 2 August 2017 at 03:38, Robert Klemme <shortcutter@googlemail.com> wrote:

On Thu, Jul 27, 2017 at 2:31 AM, Byung-Hee HWANG (황병희, 黃炳熙) >> <soyeomul@doraji.xyz> wrote:

By help Greg and Carlo, i wrote tiny code with "inject".

#+BEGIN_SRC ruby
def sum(n)
    (1..n).inject(:+) || 1
end

This is wrong. I see at least two errors in this implementation.

I think "wrong" is a strong word. Rather, it's easy to see cases
where it might fail our expectations of how we think it ought to
behave. If the rdoc says "For any positive integer this returns the
mathematical summation from 1 to n; for any non-positive integer it
returns 1. Any other value is implicitly cast to an integer or raises
an ArgumentError" then it's fine.

--
[guy, jim, charlie].each {|him| remember.him do |as, often| as.you_can
- without end}
http://blog.rubybestpractices.com/

Returning 1 as the sum of values between 1 and 0 or 0 and 0 is plain
wrong according to current mathematical tradition. Of course, you can
always tweak any documentation to exactly reflect what the method
does. But I consider that cheating with such a fundamental flaw.

Kind regards

robert

I guess it depends on context. I've written plenty of context-specific code
that does quirky stuff on edge cases because the code around it behaves
better that way. I doubt anyone would publish this one-liner as a serious,
generally applicable mathematical tool.

(Also, it's a good thing nobody ever wrote `1.0 / 3.0` in code...)

Cheers

···

On 2 Aug. 2017 19:14, "Robert Klemme" <shortcutter@googlemail.com> wrote:

--
Matthew Kerwin