Fixnum#to_a


#1

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.

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

Thoughts?

Viele Grü�e,
Levin


#2

Levin A. removed_email_address@domain.invalid 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 #=> ???

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. :wink:

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”.)


#3

On 2/4/06, Christian N. removed_email_address@domain.invalid wrote:

Levin A. removed_email_address@domain.invalid 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 significant
digit is at index 0:

12345.encode(10) #=> [5,4,3,2,1]

It should be twos-complement for negative numbers, of course. :wink:

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


#4

Christian N. removed_email_address@domain.invalid 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,


#5

On 2/4/06, Christian N. removed_email_address@domain.invalid wrote:

Christian N. removed_email_address@domain.invalid 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 created
array 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


#6

Happy hacking indeed!

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

Regards,
-Harold