Range max

If i try this
puts (1..10).max
it runs fine.
If i try this
puts (1..100000000).max
It is extremely slow. Instead of using straight math max= 100000000-1
it uses some king of interator to find out the value of max.
What is the catch here?

···

--
Posted via http://www.ruby-forum.com/.

I'm afraid that's the way the Enumerable mixin works.

There is an old saying: if hitting yourself on the head with hammer hurts, just stop. I think that applies in this case.

Regards, Morton

···

On Oct 11, 2007, at 9:30 PM, Marek Kasperkiewicz wrote:

If i try this
puts (1..10).max
it runs fine.
If i try this
puts (1..100000000).max
It is extremely slow. Instead of using straight math max= 100000000-1
it uses some king of interator to find out the value of max.
What is the catch here?

Well, one advantage of (1..N).max compared to your 'straight math'
method is the former provides the correct answer and the latter does
not. :slight_smile:

However, for efficiency, if for some reason you don't want to simply
use max = N, you'll find max = (1..N).end is much faster than max =
(1..N).max since it doesn't look at each element in the range.

The Enumerable#max method is generalized to also work for cases such
as max = [1,10,100,10,1].max

···

On Oct 11, 9:30 pm, Marek Kasperkiewicz <m.kasperkiew...@gmail.com> wrote:

If i try this
puts (1..10).max
it runs fine.
If i try this
puts (1..100000000).max
It is extremely slow. Instead of using straight math max= 100000000-1
it uses some king of interator to find out the value of max.
What is the catch here?

Marek Kasperkiewicz wrote:

If i try this
puts (1..10).max
it runs fine.
If i try this
puts (1..100000000).max
It is extremely slow. Instead of using straight math max= 100000000-1
it uses some king of interator to find out the value of max.
What is the catch here?

text

Attachments:
http://www.ruby-forum.com/attachment/642/funny.txt

···

--
Posted via http://www.ruby-forum.com/\.

Marek Kasperkiewicz wrote:

If i try this
puts (1..10).max
it runs fine.
If i try this
puts (1..100000000).max
It is extremely slow. Instead of using straight math max= 100000000-1
it uses some king of interator to find out the value of max.
What is the catch here?

sfsfa

···

--
Posted via http://www.ruby-forum.com/\.

Morton Goldberg wrote:

···

On Oct 11, 2007, at 9:30 PM, Marek Kasperkiewicz wrote:

If i try this
puts (1..10).max
it runs fine.
If i try this
puts (1..100000000).max
It is extremely slow. Instead of using straight math max= 100000000-1
it uses some king of interator to find out the value of max.
What is the catch here?

I'm afraid that's the way the Enumerable mixin works.

There is an old saying: if hitting yourself on the head with hammer
hurts, just stop. I think that applies in this case.

Regards, Morton

thanks Morton,
I thought ruby supposed to be better than Perl and Python combined, but
I can see that's not the case yet.
--
Posted via http://www.ruby-forum.com/\.

I was thinking Range#last, but that has the same problem as Range#end
(probably one is an alias for the other).

(1..10).last (or end) => 10
(1..10).max => 10

(1...10).last (or end) => 10
(1...10).max => 9

What you want is something like

class Range
  def quick_max
    last - (exclude_end? ? 1 : 0)
  end
end

Of course, if you're not using Fixnums, this is wrong. Maybe if
classes defined prec (instead of only succ), this could be easy.

···

On Oct 11, 9:55 pm, Brian Adkins <lojicdot...@gmail.com> wrote:

On Oct 11, 9:30 pm, Marek Kasperkiewicz <m.kasperkiew...@gmail.com> > wrote:

> If i try this
> puts (1..10).max
> it runs fine.
> If i try this
> puts (1..100000000).max
> It is extremely slow. Instead of using straight math max= 100000000-1
> it uses some king of interator to find out the value of max.
> What is the catch here?

Well, one advantage of (1..N).max compared to your 'straight math'
method is the former provides the correct answer and the latter does
not. :slight_smile:

However, for efficiency, if for some reason you don't want to simply
use max = N, you'll find max = (1..N).end is much faster than max =
(1..N).max since it doesn't look at each element in the range.

The Enumerable#max method is generalized to also work for cases such
as max = [1,10,100,10,1].max

--
-yossef

Marek Kasperkiewicz wrote:

Morton Goldberg wrote:

If i try this
puts (1..10).max
it runs fine.
If i try this
puts (1..100000000).max
It is extremely slow. Instead of using straight math max= 100000000-1
it uses some king of interator to find out the value of max.
What is the catch here?

I'm afraid that's the way the Enumerable mixin works.
...

thanks Morton,
I thought ruby supposed to be better than Perl and Python combined, but
I can see that's not the case yet.

You think this has anything to do with the quality of the language?...

mortee

···

On Oct 11, 2007, at 9:30 PM, Marek Kasperkiewicz wrote:

Congratulations, you found the Achilles heel of Ruby! We try to keep
it a secret, but the dreaded (1..N).max issue will undoubtedly keep
Ruby from realizing its true potential. From what I can tell from your
postings, I'd say you'll probably prefer Perl over Python - best
wishes.

···

On Oct 11, 11:11 pm, Marek Kasperkiewicz <m.kasperkiew...@gmail.com> wrote:

thanks Morton,
I thought ruby supposed to be better than Perl and Python combined, but
I can see that's not the case yet.

cfp:~ > cat a.rb
class Lang < String
   class ::NilClass
     def succ() Lang('perl') end
   end

   def succ
     Lang(
       case self
         when /perl/i then 'python'
         when /python/i then 'ruby'
         else super
       end
     )
   end

   def <=> other
     case other
       when /ruby/i then match('ruby') ? 0 : -1
       else super
     end
   end
end
def Lang(*a, &b) Lang.new(*a, &b) end

language = nil

list = and 3.times{ list << list.last.succ }

p list

p list.max, list.reverse.max, list.sort_by{ rand }.max

cfp:~ > ruby a.rb
["perl", "python", "ruby"]
"ruby"

a @ http://codeforpeople.com/

···

On Oct 11, 2007, at 9:11 PM, Marek Kasperkiewicz wrote:

thanks Morton,
I thought ruby supposed to be better than Perl and Python combined, but
I can see that's not the case yet.

--
we can deny everything, except that we have the possibility of being better. simply reflect on that.
h.h. the 14th dalai lama

I believe not. #max *has* to use <=> for a proper result. Although it
might be common that <=> and #succ represent the same ordering this is
not required. Actually there is a pretty straightforward example:

irb(main):001:0> ("a".."aa").last
=> "aa"
irb(main):002:0> ("a".."aa").max
=> "z"
irb(main):003:0> puts ("a".."aa").to_a
a
b
c
d
e
f
g
h
i
j
k
l
m
n
o
p
q
r
s
t
u
v
w
x
y
z
aa
=> nil

There is no optimization that works for all and I guess that's the
reason why Matz did not bother to provide Range#max and Enumerable#max
is used instead. And this has necessarily O(n). After all: if you
are smart enough to use Ruby then you are probably also smart enough
to not use #max on an integer range. :slight_smile:

Kind regards

robert

···

2007/10/12, Yossef Mendelssohn <ymendel@pobox.com>:

On Oct 11, 9:55 pm, Brian Adkins <lojicdot...@gmail.com> wrote:
> On Oct 11, 9:30 pm, Marek Kasperkiewicz <m.kasperkiew...@gmail.com> > > wrote:
>
> > If i try this
> > puts (1..10).max
> > it runs fine.
> > If i try this
> > puts (1..100000000).max
> > It is extremely slow. Instead of using straight math max= 100000000-1
> > it uses some king of interator to find out the value of max.
> > What is the catch here?
>
> Well, one advantage of (1..N).max compared to your 'straight math'
> method is the former provides the correct answer and the latter does
> not. :slight_smile:
>
> However, for efficiency, if for some reason you don't want to simply
> use max = N, you'll find max = (1..N).end is much faster than max =
> (1..N).max since it doesn't look at each element in the range.
>
> The Enumerable#max method is generalized to also work for cases such
> as max = [1,10,100,10,1].max

I was thinking Range#last, but that has the same problem as Range#end
(probably one is an alias for the other).

(1..10).last (or end) => 10
(1..10).max => 10

(1...10).last (or end) => 10
(1...10).max => 9

What you want is something like

class Range
  def quick_max
    last - (exclude_end? ? 1 : 0)
  end
end

Of course, if you're not using Fixnums, this is wrong. Maybe if
classes defined prec (instead of only succ), this could be easy.

Actually, what you want is simply N. It's a nonsensical request from a
troll. Using max, end, last, etc. to find the end of the range is
ridiculous since you must know the end of the range to define the
range!

···

On Oct 12, 8:56 am, Yossef Mendelssohn <ymen...@pobox.com> wrote:

On Oct 11, 9:55 pm, Brian Adkins <lojicdot...@gmail.com> wrote:
I was thinking Range#last, but that has the same problem as Range#end
(probably one is an alias for the other).

(1..10).last (or end) => 10
(1..10).max => 10

(1...10).last (or end) => 10
(1...10).max => 9

What you want is something like

ara.t.howard wrote:

class Lang < String
  class ::NilClass
    def succ() Lang('perl') end
  end

  def succ
    Lang(
      case self
        when /perl/i then 'python'
        when /python/i then 'ruby'
        else super
      end
    )
  end

...
> end
> def Lang(*a, &b) Lang.new(*a, &b) end

nil.succ.succ.succ.succ
=> "rubz"

Is this the new name for ruby 2.0, instead of rite?

Well, I have to say it kinda rubz off on you after a while.

···

--
       vjoel : Joel VanderWerf : path berkeley edu : 510 665 3407

Brian Adkins wrote:

I was thinking Range#last, but that has the same problem as Range#end
(probably one is an alias for the other).

(1..10).last (or end) => 10
(1..10).max => 10

(1...10).last (or end) => 10
(1...10).max => 9

What you want is something like

Actually, what you want is simply N. It's a nonsensical request from a
troll. Using max, end, last, etc. to find the end of the range is
ridiculous since you must know the end of the range to define the
range!

Ehhh... it's actually quite probable that the OP was indeed just insult
- however, you all seem to assume that the same person provides both the
range and wants to know its max.

If e.g. you write a method, which accepts various types of arguments,
then you can't know in advance if it'll be a range, array or something
else. So you have to use #max - and then one might expect that a range
(however big the span is) can compute it in constant time.

So the OP had *some* validity, while this still doesn't have anything to
do with the quality of the language itself. Just one spot where the it
might possibly be enhanced a bit.

mortee

···

On Oct 12, 8:56 am, Yossef Mendelssohn <ymen...@pobox.com> wrote:

On Oct 11, 9:55 pm, Brian Adkins <lojicdot...@gmail.com> wrote:

that is not true. any object can be used in a range in ruby. it only must respond to #succ. it's quite possible to declare classes that worked like so

class TimeOfDay
end

noon_today = TimeOfDay 12, :today
noon_morrow = TimeOfDay 12, :tomorrow

noon_to_noon = noon_today ... noon_tomorrow

p noon_to_noon.max #=> TimeOfDay< @hour=24, @minute=0, @second=0 >

in other words to construct a cycle or other sequence using a range. and, more simply

-1 .. -4

while quite valid, requires some thought as to which end is the maximum. with pure numbers you'd say -1 (the first) but, if those were like so

Depth(-1) .. Depth(-4)

that the Depth class semantics may dictate that Depth(-4) is in fact the max.

regards.

a @ http://codeforpeople.com/

···

On Oct 12, 2007, at 9:40 AM, Brian Adkins wrote:

Actually, what you want is simply N. It's a nonsensical request from a
troll. Using max, end, last, etc. to find the end of the range is
ridiculous since you must know the end of the range to define the
range!

--
it is not enough to be compassionate. you must act.
h.h. the 14th dalai lama

shhh. don't tell!

a @ http://codeforpeople.com/

···

On Oct 11, 2007, at 10:37 PM, Joel VanderWerf wrote:

Is this the new name for ruby 2.0, instead of rite?

--
we can deny everything, except that we have the possibility of being better. simply reflect on that.
h.h. the 14th dalai lama

I think you're assuming we're assuming :slight_smile: Rather than put words into
the OP's mouth with respect to the scope of the range problem he's
allegedly trying to solve, I was referring specifically to an integer
range problem only - can't speak for everyone though.

With respect to an integer range, a combination of Range#end and
Range#exclude_end?

···

On Oct 12, 12:42 pm, mortee <mortee.li...@kavemalna.hu> wrote:

Brian Adkins wrote:
> Actually, what you want is simply N. It's a nonsensical request from a
> troll. Using max, end, last, etc. to find the end of the range is
> ridiculous since you must know the end of the range to define the
> range!

Ehhh... it's actually quite probable that the OP was indeed just insult
- however, you all seem to assume that the same person provides both the
range and wants to know its max.

I'm not unfamiliar with the domain of the Range class. Let's not get
ridiculous here; I was referring specifically to integer ranges.
Nothing unambiguates like code, eh? :slight_smile:

class Range
  def max_int
    raise 'invalid range' if self.end < self.begin
    self.end - (self.exclude_end? ? 1 : 0)
  end
end

···

On Oct 12, 1:25 pm, "ara.t.howard" <ara.t.how...@gmail.com> wrote:

On Oct 12, 2007, at 9:40 AM, Brian Adkins wrote:
> Actually, what you want is simply N. It's a nonsensical request from a
> troll. Using max, end, last, etc. to find the end of the range is
> ridiculous since you must know the end of the range to define the
> range!

that is not true. any object can be used in a range in ruby. it
only must respond to #succ. it's quite possible to declare classes
that worked like so

Actually as discussed not long ago, this is actually too strong a
pre-condition for an object to be used in a range. It's true that you
need succ if you want to enumerate the range, but for ranges used for,
say an inclusion test, the start and end values only need to be
comparable.

I.e. (2.5..3.14) is a perfectly valid range for such purposes.

···

On 10/12/07, ara.t.howard <ara.t.howard@gmail.com> wrote:

On Oct 12, 2007, at 9:40 AM, Brian Adkins wrote:

> any object can be used in a range in ruby. it
only must respond to #succ.

--
Rick DeNatale

My blog on Ruby
http://talklikeaduck.denhaven2.com/

0 ... 1

we know that max != 0, so

max = 0.9?
max = 0.99?
max = 0.999?
max = 0.9999?

a @ http://codeforpeople.com/

···

On Oct 12, 2007, at 7:45 PM, Brian Adkins wrote:

With respect to an integer range, a combination of Range#end and
Range#exclude_end?

--
share your knowledge. it's a way to achieve immortality.
h.h. the 14th dalai lama