I'm working on a codewars kata and stuck with 2 test cases that are failing.
The kata description is: Convert integers to binary as simple as that. You would be given an integer as a argument and you have to return its binary form. To get an idea about how to convert a decimal number into a binary number, visit here.
Notes: negative numbers should be handled as two's complement; assume all numbers are integers stored using 4 bytes (or 32 bits) in any language.
My code:
def to_binary(n)
temp_array = []
if n == 0
temp_array << 0
elsif n < 0
n = n % 256
while n > 0 do
temp_array << (n % 2)
n = (n / 2)
end
while temp_array.length < 32 do
temp_array << 1
end
else
while n > 0 do
temp_array << (n % 2)
n = (n / 2)
end
end
binary = temp_array.reverse.join
end
The test cases are:
Test Passed: Value == "10"
Test Passed: Value == "11"
Test Passed: Value == "100"
Test Passed: Value == "101"
Test Passed: Value == "111"
Test Passed: Value == "1010"
Test Passed: Value == "11111111111111111111111111111101"
Test Passed: Value == "0"
Test Passed: Value == "1111101000"
Test Passed: Value == "11111111111111111111111111110001"
Expected: "11111111111111111111110000011000", instead got: "11111111111111111111111111111000"
Expected: "11111111111100001011110111000001", instead got: "11111111111111111111111111000001"
Test Passed: Value == "11110100001000111111"
I suspect the tests that are failing are with negative integers because the first failing test's expected output is 11111111111111111111110000011000 which means that either the positive argument value was 4294966296 or it was negative. If I run to_binary(4294966296) I get the expected output.
I am not fond of this approach since I'm sure there's an even more clever and/or compact, Ruby-esque way of accomplishing it. But using your method of loading binary digits into an array, and then joining, what you have can be done in a little more straight-forward fashion:
def to_binary(n)
return "0" if n == 0
r = []
32.times do
if (n & (1 << 31)) != 0
r << 1
else
(r << 0) if r.size > 0
end
n <<= 1
end
r.join
end
Or, using @500_error's suggestion:
def to_binary(n)
if n >= 0
n.to_s(2)
else
31.downto(0).map { |b| n[b] }.join
end
end
The asymmetry to deal with negative versus non-negative is a little annoying, though. You could do something like:
def to_binary(n)
31.downto(0).map { |b| n[b] }.join.sub(/^0*/, "")
end
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With