[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.ruby

Fixnum#to_a

Levin Alexander

2/4/2006 9:00:00 AM

Hi,I'd like to propose Fixnum#to_a: class Fixnum def to_a(base=10,min_length=0) self.to_s(base).rjust(min_length).split(//).map { |c| c.to_i(base) } end end 12345.to_a #=> [1,2,3,4,5] 42.to_a(2) #=> [1,0,1,0,1,0] 23.to_a(4,5) #=> [0,0,1,1,3] -10.to_a #=> ???This relies on to_s and therefore does not work with a base > 36. Idon't know how this should word for negative numbers.Maybe the default base should be 2 to be consistent with Fixnum#[]Thoughts?Viele Grüße,Levin
5 Answers

Christian Neukirchen

2/4/2006 1:28:00 PM

0

Levin Alexander <levin@grundeis.net> writes:

> Hi,
>
> I'd like to propose Fixnum#to_a:
>
> class Fixnum
> def to_a(base=10,min_length=0)
> self.to_s(base).rjust(min_length).split(//).map { |c| c.to_i(base) }
> end
> end
>
> 12345.to_a #=> [1,2,3,4,5]
> 42.to_a(2) #=> [1,0,1,0,1,0]
> 23.to_a(4,5) #=> [0,0,1,1,3]
> -10.to_a #=> ???
>
> This relies on to_s and therefore does not work with a base > 36. I
> don't know how this should word for negative numbers.

It should be twos-complement for negative numbers, of course. ;-)

> Maybe the default base should be 2 to be consistent with Fixnum#[]
>
> Thoughts?

IMO a useful method, *but*: Don't call it #to_a. to_a has certain
duck-typing aspects, and this usage is too rare to be triggered a lot
(just think of a = 42; b = [*a]).

Also, you may want to extend it to be like APL's "encode" (tack), so you
can do stuff like:

1776.encode(8) # => [1, 0, 2, 2] (octal)
105246.encode(0, 1760, 3, 12) # => [1, 1163, 1, 6]
# [miles, yards, feet, inches]

Then, we'd also need an "decode":

[14, 12, 20, 51].decode(0, 24, 60, 60) # => 1254057
# [days, hours, minutes, seconds]

(The examples were taken from "APL\360 Primer, Student Text, IBM, 1969".)

> Viele Grüße,
> Levin
--
Christian Neukirchen <chneukirchen@gmail.com> http://chneuk...


Levin Alexander

2/4/2006 2:44:00 PM

0

On 2/4/06, Christian Neukirchen <chneukirchen@gmail.com> wrote:> Levin Alexander <levin@grundeis.net> writes:>> > 12345.to_a #=> [1,2,3,4,5]> > 42.to_a(2) #=> [1,0,1,0,1,0]> > 23.to_a(4,5) #=> [0,0,1,1,3]> > -10.to_a #=> ???The order should probably be reversed, so that the least significantdigit is at index 0: 12345.encode(10) #=> [5,4,3,2,1]> It should be twos-complement for negative numbers, of course. ;-)But this would need to create an infinite array: -2.encode(2) #=> [0,1,1,1,1,1,1,1,1,1,...]> > Maybe the default base should be 2 to be consistent with Fixnum#[]> >> > Thoughts?>> IMO a useful method, *but*: Don't call it #to_a. to_a has certain> duck-typing aspects, and this usage is too rare to be triggered a lot> (just think of a = 42; b = [*a]).Good point.> Also, you may want to extend it to be like APL's "encode" (tack), so you> can do stuff like:>> 1776.encode(8) # => [1, 0, 2, 2] (octal)> 105246.encode(0, 1760, 3, 12) # => [1, 1163, 1, 6]> # [miles, yards, feet, inches]This is probably more useful than the min_length parameter.> Then, we'd also need an "decode":>> [14, 12, 20, 51].decode(0, 24, 60, 60) # => 1254057> # [days, hours, minutes, seconds]>> (The examples were taken from "APL\360 Primer, Student Text, IBM, 1969".)Viele Grüße,Levin

Christian Neukirchen

2/4/2006 3:17:00 PM

0

Christian Neukirchen <chneukirchen@gmail.com> writes:

> Also, you may want to extend it to be like APL's "encode" (tack), so you
> can do stuff like:

For fun, an implementation of encode/decode.


class Integer
def encode(restbase, *bases)
mybases = bases.dup
result = []
n = self

while base = mybases.pop || restbase
break if n < base
break if base.zero?
result << n % base
n = n / base
end

result << n

if (missing = bases.size - result.size + 1) > 0
result.concat [0] * missing
end

result.reverse!
end
end

class Array
def decode(restbase, *bases)
bases = bases.dup
result = 0
factor = 1

self.reverse_each { |a|
base = bases.pop || restbase
result += a * factor
factor *= base
}

result
end
end

p 01776.encode(8) # => [1, 0, 2, 2] (octal -> decimal)
p [1, 7, 7, 6].decode(8) # => 1022

p 105246.encode(0, 1760, 3, 12) # => [1, 1163, 1, 6]
# [miles, yards, feet, inches]

p [14, 12, 20, 57].decode(0, 24, 60, 60) # => 1254057
# [days, hours, minutes, seconds]

duration = 324477
p "Runtime: %d days %02d:%02d:%02d" % duration.encode(0, 24, 60, 60)


Happy hacking,
--
Christian Neukirchen <chneukirchen@gmail.com> http://chneuk...


Harold Hausman

2/4/2006 6:36:00 PM

0

Happy hacking indeed!

Your code made playing with this problem a lot more fun:
http://mathschallenge.net/index.php?section=project&ref=problem...

Regards,
-Harold

On 2/4/06, Christian Neukirchen <chneukirchen@gmail.com> wrote:
> Christian Neukirchen <chneukirchen@gmail.com> writes:
>
> > Also, you may want to extend it to be like APL's "encode" (tack), so you
> > can do stuff like:
>
> For fun, an implementation of encode/decode.
>
>
> class Integer
> def encode(restbase, *bases)
> mybases = bases.dup
> result = []
> n = self
>
> while base = mybases.pop || restbase
> break if n < base
> break if base.zero?
> result << n % base
> n = n / base
> end
>
> result << n
>
> if (missing = bases.size - result.size + 1) > 0
> result.concat [0] * missing
> end
>
> result.reverse!
> end
> end
>
> class Array
> def decode(restbase, *bases)
> bases = bases.dup
> result = 0
> factor = 1
>
> self.reverse_each { |a|
> base = bases.pop || restbase
> result += a * factor
> factor *= base
> }
>
> result
> end
> end
>
> p 01776.encode(8) # => [1, 0, 2, 2] (octal -> decimal)
> p [1, 7, 7, 6].decode(8) # => 1022
>
> p 105246.encode(0, 1760, 3, 12) # => [1, 1163, 1, 6]
> # [miles, yards, feet, inches]
>
> p [14, 12, 20, 57].decode(0, 24, 60, 60) # => 1254057
> # [days, hours, minutes, seconds]
>
> duration = 324477
> p "Runtime: %d days %02d:%02d:%02d" % duration.encode(0, 24, 60, 60)
>
>
> Happy hacking,
> --
> Christian Neukirchen <chneukirchen@gmail.com> http://chneuk...
>
>


Levin Alexander

2/4/2006 6:43:00 PM

0

On 2/4/06, Christian Neukirchen <chneukirchen@gmail.com> wrote:> Christian Neukirchen <chneukirchen@gmail.com> writes:>> > Also, you may want to extend it to be like APL's "encode" (tack), so you> > can do stuff like:>> For fun, an implementation of encode/decode.I played with your code a bit more, reversed the order of the createdarray and added some test cases. What I have now is attached.IMHO, something like that would be nice to have in the standard library.Grüße,Levin