Skip to content

Commit 22f658d

Browse files
authored
Merge pull request #228 from afurm/interpolation-search
Add interpolation search algorithm
2 parents 56a00cc + 51bbbde commit 22f658d

2 files changed

Lines changed: 70 additions & 0 deletions

File tree

searches/interpolation_search.rb

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
# Performs interpolation search on a sorted numeric array.
2+
# Returns the index of the target element or -1 when target is absent.
3+
# Raises ArgumentError if the input array is not sorted in ascending order.
4+
def interpolation_search(array, target)
5+
raise ArgumentError, 'Input must be an array' unless array.is_a?(Array)
6+
return -1 if array.empty?
7+
8+
unless array.each_cons(2).all? { |left, right| left <= right }
9+
raise ArgumentError, 'Array must be sorted in ascending order'
10+
end
11+
12+
left = 0
13+
right = array.length - 1
14+
15+
while left <= right && target >= array[left] && target <= array[right]
16+
return left if array[left] == target
17+
return right if array[right] == target
18+
19+
value_range = array[right] - array[left]
20+
if value_range.zero?
21+
return -1
22+
end
23+
24+
position = left + ((target - array[left]) * (right - left) / value_range)
25+
return -1 if position < left || position > right
26+
27+
current = array[position]
28+
29+
if current == target
30+
return position
31+
elsif current < target
32+
left = position + 1
33+
else
34+
right = position - 1
35+
end
36+
end
37+
38+
-1
39+
end
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
require 'minitest/autorun'
2+
require_relative './interpolation_search'
3+
4+
class TestInterpolationSearch < Minitest::Test
5+
def test_finds_existing_element
6+
array = [2, 4, 6, 8, 10, 12, 14]
7+
assert_equal 3, interpolation_search(array, 8)
8+
end
9+
10+
def test_returns_negative_one_for_missing_element
11+
array = [10, 20, 30, 40, 50]
12+
assert_equal(-1, interpolation_search(array, 35))
13+
end
14+
15+
def test_handles_empty_array
16+
assert_equal(-1, interpolation_search([], 7))
17+
end
18+
19+
def test_handles_uniform_values
20+
array = [5, 5, 5, 5]
21+
assert_equal 0, interpolation_search(array, 5)
22+
assert_equal(-1, interpolation_search(array, 4))
23+
end
24+
25+
def test_raises_when_array_not_sorted
26+
array = [3, 1, 2]
27+
assert_raises ArgumentError do
28+
interpolation_search(array, 1)
29+
end
30+
end
31+
end

0 commit comments

Comments
 (0)