Reputation: 187
Recently I attended a Python coding challenge where I was asked to find the size of a list.
For example if the list is l = [100, 100, 100]
then it should return 3.
The list was termed as a virtual list with unknown number of elements.
There is a getElement()
function provided which takes the index as a parameter and returns the value 100 assuming that all the element of the list is 100.
def getElement(index):
###some exception logic for index out of range
return 100
So I was asked to write a function def findListSize()
which will return the size of the list with condition of only invoking the getElement()
function. The lower the number of calls to getElement()
the more bonus points will be awarded.
def findListSize():
array_size = 0
###logic here
return array_size
I was not able to proceed in a right direction to solve the problem. Can someone help me?
Upvotes: 0
Views: 1274
Reputation: 82949
If you can only use getElement
, then the naive solution would be to call getElement
in a loop with increasing indices and count how often it succeeds before it fails. But this might call getElement
very often (once for each element in the list).
size = 0
try:
while True:
getElement(size)
size += 1
except:
print("size is", size)
Alternatively, you could first call getElement
with exponentially increasing values (e.g. getElement(2)
, getElement(4)
, getElement(8)
, ...) to determine the magnitude of the list, and once you know a generous upper bound, use binary search to find the exact size.
upper = 2
try:
while True:
getElement(upper)
upper *= 2
except IndexError:
pass
lower = -1
while lower < upper:
middle = (lower + upper) // 2 + 1
try:
getElement(middle)
lower = middle
except IndexError:
upper = middle - 1
print("size is", lower + 1)
This way, I was able to find the size of a list with 51166 elements (upper bound of 65536) with just 33 calls to getElement
. (I guess you could also get rid of those try/except
if you are allowed to write a helper function that tries a certain index and then returns True
or False
instead of raising an exception.)
Upvotes: 4
Reputation: 527
I would try something like binary search (half-interval search) https://en.wikipedia.org/wiki/Binary_search_algorithm . Start witch some large number and see if it still return 100 or gives exception Out of range. Then increase the number or go to its 0.5* value and so on... read the wikipedia post to get notion of the algorithm. You should end up with lower complexity than in the case of complete search. But the implementation is up to you, it looks like a homework:)
Upvotes: 1