Module:Exponential search: Difference between revisions

From Tardis Wiki, the free Doctor Who reference
(create a generic binary search module, modified from Module:Highest archive number)
 
m (14 revisions imported)
 
(15 intermediate revisions by 3 users not shown)
Line 1: Line 1:
-- This module provides a generic binary search algorithm.
-- This module provides a generic exponential search algorithm.


local checkType = require('libraryUtil').checkType
local checkType = require('libraryUtil').checkType
Line 8: Line 8:
end
end


local function binarySearch(testFunc, i, lower, upper)
local function search(testFunc, i, lower, upper)
if testFunc(i) then
if testFunc(i) then
if i + 1 == upper then
if i + 1 == upper then
Line 19: Line 19:
i = i * 2
i = i * 2
end
end
return binarySearch(testFunc, i, lower, upper)
return search(testFunc, i, lower, upper)
else
else
upper = i
upper = i
lower = lower or 0
i = midPoint(lower, upper)
i = midPoint(lower, upper)
return binarySearch(testFunc, i, lower, upper)
return search(testFunc, i, lower, upper)
end
end
end
end


return function (testFunc, init)
return function (testFunc, init)
checkType('Binary search', 1, testFunc, 'function')
checkType('Exponential search', 1, testFunc, 'function')
checkType('Binary search', 2, initNum, 'number', true)
checkType('Exponential search', 2, init, 'number', true)
init = init or 1
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 value must be a positive integer)",
tostring(init)
), 2)
end
init = init or 2
if not testFunc(1) then
if not testFunc(1) then
return nil
return nil
end
end
return binarySearch(testFunc, init)
return search(testFunc, init, 1, nil)
end
end

Latest revision as of 17:41, 8 February 2023

Taken from Wikipedia's Module:Exponential search for use in Module:TableTools.


-- 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')
	checkType('Exponential search', 2, init, '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 value must be a positive integer)",
			tostring(init)
		), 2)
	end
	init = init or 2
	if not testFunc(1) then
		return nil
	end
	return search(testFunc, init, 1, nil)
end