 shmibs's solution

to Binary in the Crystal Track

Published at Nov 18 2018 · 0 comments
Instructions
Test suite
Solution

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.

Note

• Implement the conversion yourself. Do not use something else to perform the conversion for you.

Decimal is a base-10 system.

A number 23 in base 10 notation can be understood as a linear combination of powers of 10:

• The rightmost digit gets multiplied by 10^0 = 1
• The next number gets multiplied by 10^1 = 10
• ...
• The nth number gets multiplied by 10^(n-1).
• All these values are summed.

So: 23 => 2*10^1 + 3*10^0 => 2*10 + 3*1 = 23 base 10

Binary is similar, but uses powers of 2 rather than powers of 10.

So: 101 => 1*2^2 + 0*2^1 + 1*2^0 => 1*4 + 0*2 + 1*1 => 4 + 1 => 5 base 10.

Setup

Follow the setup instructions for Crystal here:

http://exercism.io/languages/crystal

More help installing can be found here:

http://crystal-lang.org/docs/installation/index.html

Making the Test Suit Pass

Execute the tests with:

\$ crystal spec

In each test suite all but the first test have been skipped.

Once you get a test passing, you can unskip the next one by changing pending to it.

Source

All of Computer Science http://www.wolframalpha.com/input/?i=binary&a=*C.binary-_*MathWorld-

Submitting Incomplete Solutions

It's possible to submit an incomplete solution so you can see how others have completed the exercise.

binary_spec.cr

require "spec"
require "../src/*"

describe "Binary" do
it "binary 0 is decimal 0" do
Binary.to_decimal("0").should eq(0)
end

pending "binary 1 is decimal 1" do
Binary.to_decimal("1").should eq(1)
end

pending "binary 10 is decimal 2" do
Binary.to_decimal("10").should eq(2)
end

pending "binary 11 is decimal 3" do
Binary.to_decimal("11").should eq(3)
end

pending "binary 100 is decimal 4" do
Binary.to_decimal("100").should eq(4)
end

pending "binary 1001 is decimal 9" do
Binary.to_decimal("1001").should eq(9)
end

pending "binary 11010 is decimal 26" do
Binary.to_decimal("11010").should eq(26)
end

pending "binary 10001101000 is decimal 1128" do
Binary.to_decimal("10001101000").should eq(1128)
end

pending "binary ignores leading zeros" do
Binary.to_decimal("000011111").should eq(31)
end

pending "2 is not a valid binary digit" do
expect_raises(ArgumentError) do
Binary.to_decimal("2")
end
end

pending "a number containing a non-binary digit is invalid" do
expect_raises(ArgumentError) do
Binary.to_decimal("01201")
end
end

pending "a number with trailing non-binary characters is invalid" do
expect_raises(ArgumentError) do
Binary.to_decimal("10nope")
end
end

pending "a number with leading non-binary characters is invalid" do
expect_raises(ArgumentError) do
Binary.to_decimal("nope10")
end
end

pending "a number with internal non-binary characters is invalid" do
expect_raises(ArgumentError) do
Binary.to_decimal("10nope10")
end
end

pending "a number and a word whitespace separated is invalid" do
expect_raises(ArgumentError) do
Binary.to_decimal("001 nope")
end
end
end
require "big"

module Binary
extend self

def to_decimal(si : String) : BigInt
si.each_char.reduce(BigInt.new(0)) { |b, c|
case c
when '1'
(b << 1) + 1
when '0'
b << 1
else
raise ArgumentError.new
end
}
end

end