Module:Exponential search
- Адыгабзэ
- Afrikaans
- अंगिका
- العربية
- অসমীয়া
- Asturianu
- Авар
- تۆرکجه
- Basa Bali
- বাংলা
- Basa Banyumasan
- Беларуская
- भोजपुरी
- Bosanski
- Буряад
- Cebuano
- Chavacano de Zamboanga
- Corsu
- الدارجة
- Español
- فارسی
- Gaeilge
- ગુજરાતી
- गोंयची कोंकणी / Gõychi Konknni
- 한국어
- Hausa
- Հայերեն
- हिन्दी
- Hornjoserbsce
- Ilokano
- Bahasa Indonesia
- Jawa
- ಕನ್ನಡ
- Kurdî
- Кыргызча
- Latina
- Lietuvių
- Lingua Franca Nova
- Magyar
- मैथिली
- Македонски
- Malagasy
- മലയാളം
- Bahasa Melayu
- Монгол
- မြန်မာဘာသာ
- Na Vosa Vakaviti
- नेपाली
- 日本語
- Norsk nynorsk
- ଓଡ଼ିଆ
- ਪੰਜਾਬੀ
- ပအိုဝ်ႏဘာႏသာႏ
- ភាសាខ្មែរ
- Português
- Română
- Русский
- Scots
- සිංහල
- Simple English
- سنڌي
- Slovenščina
- کوردی
- Српски / srpski
- Srpskohrvatski / српскохрватски
- Suomi
- Tagalog
- தமிழ்
- တႆး
- తెలుగు
- ไทย
- Türkçe
- Українська
- Vèneto
- Tiếng Việt
- Yorùbá
- 粵語
- 中文
- Batak Mandailing
- Jaku Iban
- Kumoring
- Руски
- ᥖᥭᥰ ᥖᥬᥲ ᥑᥨᥒᥰ
To avoid major disruption and server load, any changes should be tested in the module's /sandbox or /testcases subpages, or in your own module sandbox. The tested changes can be added to this page in a single edit. Consider discussing changes on the talk page before implementing them.
This module provides a generic exponential search algorithm. This kind of search can be useful when you want to find a key in some kind of sorted array, and you want to do it by checking as few array elements as possible. This could include situations like:
- Finding the highest archive number in a set of archives without checking whether they all exist.
- Finding the number of positional arguments in frame.args without having to expand the wikitext for each of them.
You shouldn't use this module if any of the following apply:
- You can use the Lua length operator to find what you need.
- Your array has any gaps in it. (In other words, any of the items before the final item is
nil, e.g.{'foo','bar',nil,'baz'}.) If you try and use this module on a sparse array, you might get an erroneous value. - Your array has fewer than about 10 items. It's possible to use this module for those arrays, but you will access most of the array elements anyway (perhaps some of them twice), and your code will be more complicated than if you just used a for loop.
Usage
First, load the module.
localexpSearch=require('Module:Exponential search')
You can then use the expSearch function with the following syntax:
expSearch(testFunc,init)
Parameters:
- testFunc - a test function for your array. This function should take a positive integer i as its first parameter. If the element corresponding to i is not in the array, then the function should return false or nil; and if it is in the array, then the function should return a truthy value (anything other than false or nil). (required)
- init - the initial value of i to check. For advanced users. (optional)
expSearch will return the highest value of i for which testFunc was truthy. If no values were truthy, the function will return nil.
Examples
Jimbo's talk archives
User talk:Jimbo Wales has archives at User talk:Jimbo Wales/Archive 1, User talk:Jimbo Wales/Archive 2, ... To find the highest archive number, you would use code like this:
localexpSearch=require('Module:Exponential search') localhighestArchive=expSearch(function(i) localarchive='User talk:Jimbo Wales/Archive '..i returnmw.title.new(archive).exists end)
Village pump archives
Wikipedia:Village pump (proposals) has old archives at Wikipedia:Village pump (proposals)/Archive A, Wikipedia:Village pump (proposals)/Archive B, etc. After they go through to Archive Z, the next archive is Archive AA. Although these archives aren't being updated anymore, as a demonstration we can find the highest one using this module; all we need is a function that converts from an integer to the corresponding archive name.
localexpSearch=require('Module:Exponential search') localfunctionintegerToAlpha(i) -- This function converts 1 to A, 2 to B, ... 26 to Z, 27 to AA, ... localret='' whilei>0do localrem=i%26 ifrem==0then rem=26 end localchar=string.char(rem+64)-- the "rem"th letter of the alphabet ret=char..ret i=(i-rem)/26 end returnret end localfunctionintegerToArchive(i) return'Wikipedia:Village pump (proposals)/Archive '..integerToAlpha(i) end localhighestInteger=expSearch(function(i) localarchive=integerToArchive(i) returnmw.title.new(archive).exists end) localhighestArchive=integerToArchive(highestInteger)
Editors can experiment in this module's sandbox (create | mirror) and testcases (edit | run) pages.
Subpages of this module.
-- This module provides a generic exponential search algorithm. require[[strict]] localcheckType=require('libraryUtil').checkType localfloor=math.floor localfunctionmidPoint(lower,upper) returnfloor(lower+(upper-lower)/2) end localfunctionsearch(testFunc,i,lower,upper) iftestFunc(i)then ifi+1==upperthen returni end lower=i ifupperthen i=midPoint(lower,upper) else i=i*2 end returnsearch(testFunc,i,lower,upper) else upper=i i=midPoint(lower,upper) returnsearch(testFunc,i,lower,upper) end end returnfunction(testFunc,init) checkType('Exponential search',1,testFunc,'function') checkType('Exponential search',2,init,'number',true) ifinitand(init<1orinit~=floor(init)orinit==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=initor2 ifnottestFunc(1)then returnnil end returnsearch(testFunc,init,1,nil) end