Module:Exponential search: Difference between revisions

From Vigyanwiki
Template>Mr. Stradivarius
(don't check testFunc(1) twice every time)
Template>Mr. Stradivarius
(move the init checkType a little later so that we don't execute it for empty arrays)
Line 29: Line 29:
return function (testFunc, init)
return function (testFunc, init)
checkType('Exponential search', 1, testFunc, 'function')
checkType('Exponential search', 1, testFunc, 'function')
checkType('Exponential search', 2, initNum, 'number', true)
if not testFunc(1) then
if not testFunc(1) then
return nil
return nil
end
end
checkType('Exponential search', 2, initNum, 'number', true)
if init and (init < 1 or init ~= floor(init) or init == math.huge) then
if init and (init < 1 or init ~= floor(init) or init == math.huge) then
error(string.format(
error(string.format(

Revision as of 18:42, 26 February 2015

Documentation for this module may be created at Module:Exponential search/doc

-- This module provides a generic exponential search algorithm.

local checkType = require('libraryUtil').checkType
local floor = math.floor

local function midPoint(lower, upper)
	return floor(lower + (upper - lower) / 2)
end

local function search(testFunc, i, lower, upper)
	if testFunc(i) then
		if i + 1 == upper then
			return i
		end
		lower = i
		if upper then
			i = midPoint(lower, upper)
		else
			i = i * 2
		end
		return search(testFunc, i, lower, upper)
	else
		upper = i
		i = midPoint(lower, upper)
		return search(testFunc, i, lower, upper)
	end
end

return function (testFunc, init)
	checkType('Exponential search', 1, testFunc, 'function')
	if not testFunc(1) then
		return nil
	end
	checkType('Exponential search', 2, initNum, 'number', true)
	if init and (init < 1 or init ~= floor(init) or init == math.huge) then
		error(string.format(
			"invalid init value '%s' detected in argument #2 to " ..
			"'Exponential search' (init values must be a positive integer)",
			tostring(init)
		), 2)
	end
	init = init or 2
	return search(testFunc, init, 1, nil)
end