Here's a working implementation in Ruby using built-in binary conversion. I've commented it enough that I don't think additional verbiage is required for explanation. Notice that ordering of the binary strings is not necessary for this to work.
ary = ["1", "010", "100", "110", "11"] # Works with or without leading zeros
n_plus_1 = ary.size + 1
result = n_plus_1 * (n_plus_1 + 1) / 2 # Total if all values were present
# Convert each string in ary to int using base 2, and deduct from the total
ary.each { |str| result -= str.to_i(2) }
# The remainder is the missing value
puts "Missing value is #{result} (binary #{result.to_s(2)})"
Both that and the code below produce the following output:
Missing value is 5 (binary 101)
If you want to avoid built-in conversion, here it is with a recursive converter which should be straightforward to translate to other languages. Note that Ruby method arguments given a default value don't need to be provided explicitly in the method call:
def str_to_i(char_ary, power = 1, radix = 2)
return 0 if char_ary.size == 0 # Base case
bit = char_ary.pop.to_i # Remove last character in array and convert to int
return bit * power + str_to_i(char_ary, power * radix, radix)
end
ary = ["1", "010", "100", "110", "11"] # Works with or without leading zeros
n_plus_1 = ary.size + 1
result = n_plus_1 * (n_plus_1 + 1) / 2 # Total if all values were present
# Convert each string to array of chars, then to int, and deduct from total
ary.each { |str| result -= str_to_i(str.chars) }
# The remainder is the missing value
puts "Missing value is #{result} (binary #{result.to_s(2)})"
This also fulfills your use of the recursion tag.
If you want to do the full Monty on recursion:
def str_to_i(char_ary, power = 1, radix = 2)
return 0 if char_ary.size == 0 # Base case
bit = char_ary.pop.to_i # Remove last character in array and convert to int
return bit * power + str_to_i(char_ary, power * radix, radix)
end
# Assuming String -> Integer can be considered O(1):
# T(n) = 2 * T(n/2) + O(1) => O(n)
# Stack size is O(log n), which should avoid stack overflow, where splitting
# array into subsets of 1 an n-1 would exceed recursive stack limits even for
# relatively small arrays (more than a few hundred).
def sum_array(ary, first = 0, last = ary.size - 1)
# return ary[first].to_i(2) if last == first # using built-in conversion
return str_to_i(ary[first].chars) if last == first # avoiding built-in
mid = first + (last - first) / 2
return sum_array(ary, first, mid) + sum_array(ary, mid + 1, last)
end
ary = ["1", "010", "100", "110", "11"] # Works with or without leading zeros
n_plus_1 = ary.size + 1
result = n_plus_1 * (n_plus_1 + 1) / 2 - sum_array(ary)
# The remainder is the missing value
puts "Missing value is #{result} (binary #{result.to_s(2)})"