May 04, 2017 • 2 min read

- ruby

This week I wrote a small algorithm in Ruby to convert binary numbers into decimal numbers. Here’s the problem description, from Exercism:

Convert a binary number, represented as a string (e.g. ‘101010’), to its decimal equivalent using first principles. Implement binary to decimal conversion. Given a binary input string, your program should produce a decimal output. The program should handle invalid inputs.

```
class Binary
def self.to_decimal(binary)
raise ArgumentError if binary.match?(/[^01]/)
binary.reverse.chars.map.with_index do |digit, index|
digit.to_i * 2**index
end.sum
end
end
```

And the interface:

```
> Binary.to_decimal('101010')
=> 42
```

What’s going on here? Examining each line:

- We make a class
`Binary`

, a container for our code. - We define a class method. I prefer functional when object instantiation isn’t beneficial.
- Guard clause! Raise an
`ArgumentError`

if the string does not match the binary format. - Space; let that code breathe .
- Reverse the string and split into characters, then map over each with index included.
- Take each digit, starting with the rightmost because the power grows with each position. Convert it into a number, and multiply that number by two to the power of its enumerable index. In simpler terms, convert each digit to its individual decimal value.
- Sum the result.

I like that my solution matches for `ArgumentError`

positively, covering a
range of bad inputs not specified by the Exercism test cases. I like that it
reverses the string so that `index`

can be used as the incrementing exponent.
And, I like that it uses `.map`

to return a result without an accumulator
variable.

I may have golfed this down a little too much. In general, I think mathematical functions can get away with terser syntax than ordinary functions, because the principles are easy to learn about with a quick Google search.

If this was a real-world Ruby problem, I’d use `to_i`

:

```
> '101010'.to_i(2)
=> 42
```

And go back to binary with `to_s`

:

```
> 42.to_s(2)
=> '101010'
```

Thanks Exercism for this fun challenge, and thanks for reading! Here’s the permalink to my solution:

Blog of Jake Worth.