On Fri, Mar 09, 2007 at 04:50:08PM +0900, Josselin wrote:
> Could I write it in just 1 line ?
> 
> find the first value greater than d, in a list (special one :  each 
> value is the double of the previous...)
> then give me the index of this value (with special case ...)
> 
>      i = 
> ([0.5,1.0,2.0,4.0,8.0,16.0,32.0,64.0,128.0,256.0,512.0,1024.0,2048.0].select 
> {|v| v if v >= d }).first
> 
>      zl = d <0.5  ? 0 : 
> [0.5,1.0,2.0,4.0,8.0,16.0,32.0,64.0,128.0,256.0,512.0,1024.0,2048.0].index(i)

a = [0.5,1.0,2.0,4.0,8.0,16.0,32.0,64.0,128.0,256.0,512.0,1024.0,2048.0]
d = 7.0

# version 1: matches your verbal specification
zl = a.each_with_index { |v,i| break i if v > d }

# version 2: matches your sample code's behaviour
zl = a.each_with_index { |v,i| break i if v >= d }

However this gives different behaviour to your code in the event that d is
greater than the last element in the array (yours returns nil, mine returns
the whole array). Maybe this is OK; you can always stick a 1.0/0.0
(infinity) at the end of the array. Or:

zl = nil; a.each_with_index { |v,i| break zl = i if v >= d }

But in this particular case you also could use your power-of-two property
and not construct or search an array at all:

zl = d < 0.5 ? 0 : (d*2).to_i.to_s(2).length

B.