# Fixnum#to\_a

**URL:** <https://www.ruby-forum.com/t/fixnum-to-a/100986>\
**Category:** Ruby\
**Created:** [February 4, 2006, 10:00am UTC](https://www.ruby-forum.com/t/fixnum-to-a/100986 "2006-02-04T10:00:51Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![Levin\_A](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/l/eada6e/32.png) [@Levin\_A](https://www.ruby-forum.com/u/Levin_A)\
**Post date:** [February 4, 2006, 10:00am UTC](https://www.ruby-forum.com/t/fixnum-to-a/100986/1 "2006-02-04T10:00:51Z")

</div>

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

---

<div class="post-metadata">

**Author:** ![Levin\_A](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/l/eada6e/32.png) [@Levin\_A](https://www.ruby-forum.com/u/Levin_A)\
**Post date:** [February 4, 2006, 2:29pm UTC](https://www.ruby-forum.com/t/fixnum-to-a/100986/2 "2006-02-04T14:29:32Z")

</div>

Levin A. [removed\_email\_address@domain.invalid](mailto: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. 😉

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

---

<div class="post-metadata">

**Author:** ![Levin\_A](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/l/eada6e/32.png) [@Levin\_A](https://www.ruby-forum.com/u/Levin_A)\
**Post date:** [February 4, 2006, 3:45pm UTC](https://www.ruby-forum.com/t/fixnum-to-a/100986/3 "2006-02-04T15:45:19Z")

</div>

On 2/4/06, Christian N. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> Levin A. [removed\_email\_address@domain.invalid](mailto: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. 😉

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

---

<div class="post-metadata">

**Author:** ![Levin\_A](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/l/eada6e/32.png) [@Levin\_A](https://www.ruby-forum.com/u/Levin_A)\
**Post date:** [February 4, 2006, 4:18pm UTC](https://www.ruby-forum.com/t/fixnum-to-a/100986/4 "2006-02-04T16:18:44Z")

</div>

Christian N. [removed\_email\_address@domain.invalid](mailto: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,

---

<div class="post-metadata">

**Author:** ![Levin\_A](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/l/eada6e/32.png) [@Levin\_A](https://www.ruby-forum.com/u/Levin_A)\
**Post date:** [February 4, 2006, 7:43pm UTC](https://www.ruby-forum.com/t/fixnum-to-a/100986/5 "2006-02-04T19:43:52Z")

</div>

On 2/4/06, Christian N. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> Christian N. [removed\_email\_address@domain.invalid](mailto: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

---

<div class="post-metadata">

**Author:** ![Levin\_A](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/l/eada6e/32.png) [@Levin\_A](https://www.ruby-forum.com/u/Levin_A)\
**Post date:** [February 4, 2006, 7:37pm UTC](https://www.ruby-forum.com/t/fixnum-to-a/100986/6 "2006-02-04T19:37:47Z")

</div>

Happy hacking indeed!

Your code made playing with this problem a lot more fun:

> **[mathschallenge.net](https://mathschallenge.net/index.php?section=project&ref=problems&id=4)**
>
> A website dedicated to the puzzling world of mathematics.

Regards,  
-Harold
