If there is a test, where a delta needs to be added to a particular value, the delta can be tested in this sequence: 1, 2, 3, … 15, 16.
But to test with finer and finer granularity, delta can be this sequence: 1, 16, 8, 4, 12, … (that is, we try 1, and 16, which are two extreme cases, and then we try 8, which is a middle number, and then 4, which is middle of 1 and 8, and then 12, which is middle of 8 and 16).
How can this sequence be generated elegantly without duplicates?
Right now I have this in Ruby 1.9.3:
$deltas = []
def getMidPoint(a, b)
return if (a - b).abs <= 1
midPoint = ((a + b) / 2).to_i
puts "a = #{a}, b = #{b}, midPoint = #{midPoint}"
$deltas << midPoint
getMidPoint(a, midPoint)
getMidPoint(midPoint, b)
end
$deltas << 1
$deltas << 16
getMidPoint(1, 16)
p $deltas
but the result is:
[1, 16, 8, 4, 2, 3, 6, 5, 7, 12, 10, 9, 11, 14, 13, 15]
I can actually add a “level” to the number (stored as a tuple): so for 8, it is level 2, and for 12, it is also level 2 (the level is the recursion level), and then at the end, I can collect the numbers with level 1, and then level 2, etc, to get the final array, and it should work, but is there a better solution?
The problem with your algorithm is that it will runthrough the entire “left side” before going to the “right side”, because the
getMidPoint(a, midPoint)will cause many recursions beforegetMidPoint(midPoint, b)executes.One possible solution is to use a queue. Enqueue the calls instead of calling both functions directly and always call the first element in the queue.
So in the first step you would output 8 and have the queue <1,8>, <8,16> and you would call <1,8>, outputing 4. Next you would have <8,16><1,4><4,8> and you would call <8,16> and output 12 and have the queue <1,4><4,8><8,12><12,16> and so on.
I think it is a better approximation to your needs.