## Intro

This article walks through several solutions for a decimal to octal number convertor coding challenge written in ruby.

Note: These solutions can be generalized for converting decimal to any base less than 10 by adding a second function parameter and replacing all 8's with the given parameter.

## Solution 1: Standard Way

One simple way to convert bases is to repeatedly take the modulo of the input number and target base `num % 8`

then divide the input number by target base`num /= 8`

until the number is empty `while num > 0`

. Each modulo result is either added to an array or summed into a resultant number like in the example below.

```
def octal_convertor(num)
octal = 0
i = 1
while num > 0
octal += (num % 8) * i
num /= 8
i *= 10
end
return octal
end
```

This solution uses a variable `i = 1`

which grows by `i *= 10`

on each iteration. It is used to multiply `num % 8`

so it goes in the next whole number place in `octal += (num % 8) * i`

. You can think of it like slicing off base 8 digits from `num`

and slotting them into the next whole number place in `octal`

## Solution 2: Deterministic Iteration with Logarithm

The number of places(digits) in a whole number of any base(base 8 in this instance) can be calculated with `Math.log(num,8).floor + 1`

. This reveals how many digits need to be 'sliced' out with `num % 8`

, or rather the number of loop iterations required. So there is no need to check if `num > 0`

, we can just run a loop an exact number of times.

```
def octal_convertor(num)
octal = 0
(Math.log(num,8).floor + 1).times do |i|
octal += (num % 8) * 10**i
num /= 8
end
return octal
end
```

The `.times`

method accepts a block and passes iteration count to `|i|`

. So in addition to knowing the exact number of iterations in advance the 'i' variable in the previous solutions is provided by `.times`

. The `|i|`

increments from zero, so to slot the octal digits in the right place `(num % 8)`

is multiplied by `10**i`

.

## Solution 3: Number as an Array

This one-liner works much the same way as above but creates a new array with a length of the octal number (so there is a place for each oct digit). Similar to `.times`

`Array.new`

accepts a block where you can fill each value in the array with something, this block receives an index value `|i|`

.

```
def octal_convertor(num)
Array.new(Math.log(num,8).floor + 1) {|i| ((num / 8**i) % 8) * 10**i }.sum
end
```

`num`

is not mutably divided with `num /= 8`

, instead, using 'i' we calculate how many times it should have been divided `num / 8**i`

or rather which octal place value the current iteration is at. `10**i`

works exactly the same as previously mentioned. The array now contains all oct digits multiplied by `10**i`

, which provides the correct number of zeros added so when summed together they fit in the right place. `.sum`

adds all numbers in the array together returning the converted number.

## Conclusion

Calculating number digit lengths using logarithms provides a means to determine iteration count ahead of time and iterate over enumerable objects(arrays, numbers) instead of using while loops.

## Discussion (0)