-1

I'm trying to do a recursive program in Python which returns the first index of a list which is equals to it's value, for example: [0, 1, 5, 6] returns 0. But when I pass the last list it returns 1, and I don't know why.

Code:

def index(list):
    """Returns the first index of the list where list[i] == i"""
    return __auxindex(list, 0, len(list) - 1)


def __auxindex(list, start, end):
    if start < end:
        half = (start + end) // 2
        if list[half] == half:
            return half
        elif list[half] > half:
            return __auxindex(list, start, half)
        else:
            return __auxindex(list, half + 1, end)
    else:
        return start

list = input('Values (, ): ').split(', ')
list = [int(i) for i in list]
print(index(list))

EDIT: I forgot that the list has to be ordered. So this code works.

Marco Canora
  • 335
  • 2
  • 15
  • Does it *always* do this, or only for certain inputs? If the latter, which ones? In either case, what should it return? – Scott Hunter Apr 17 '16 at 10:37
  • It does sometimes, the first time when I pass [0, 1, 5, 6] it returns 0, but when I do again returns 1 – Marco Canora Apr 17 '16 at 10:39
  • 1
    Don't use list as a variable name,also what if no element it at a matching index? Also I get 1 for `[0, 1, 5, 6]` not 0 – Padraic Cunningham Apr 17 '16 at 10:42
  • When recursive functions don't do what you want it's helpful to add a print call or two to ensure that the args at each recursive call are what you expect them to be. See [here](http://stackoverflow.com/a/36645766/4014959) for a simple example I wrote the other day. – PM 2Ring Apr 17 '16 at 10:45
  • 2
    However, I really can't see the point of using recursion here. You want the first `i` such that `lst[i]==i`, so a simple linear search is the natural solution. – PM 2Ring Apr 17 '16 at 10:50

1 Answers1

3

You started your index at the halfway point. Since you used floor division, that would be at index 1. Well, your list at index 1 is 1, so that's a match and it returns half, 1. What you need to do instead is start at the beginning and work to the end. Something like this:

def index(number_list, start=0):
    if start >= len(number_list):
        return -1
    elif number_list[start] == start:
        return start
    else:
        return index(number_list, start+1)
zondo
  • 19,901
  • 8
  • 44
  • 83
  • True, but the OP needs a recursive solution. I _suspect_ you were down-voted because your solution is not recursive. – PM 2Ring Apr 17 '16 at 10:42
  • I'm confused, the recursion in Python works like in Java? – Marco Canora Apr 17 '16 at 10:42
  • @MarcoCanora: I'm sorry. I didn't notice *recursive*. You should still start at the beginning and work to the end, though. I have edited. – zondo Apr 17 '16 at 10:44
  • 1
    But the point of the OP is that I have to use Divide and Conquer – Marco Canora Apr 17 '16 at 10:48
  • 1
    @MarcoCanora: If you want the *first* occurrence, you need to start at the beginning. If you start at the middle and find a match, you will return the match and it isn't necessarily the first one. – zondo Apr 17 '16 at 10:49
  • Oh sorry, I know why it doesn't works, I forgot that the list has to be ordered – Marco Canora Apr 17 '16 at 10:51
  • 1
    @MarcoCanora: Even if the list is ordered what zondo said about finding a match in the middle still applies. – PM 2Ring Apr 17 '16 at 10:52
  • @MarcoCanora: " the recursion in Python works like in Java? " Pretty much. Recursion is recursion. Python has a pre-set recursion limit (which can be manually adjusted) so you don't blow the stack on deep recursions. Neither language implements [tco](http://stackoverflow.com/q/310974/4014959). – PM 2Ring Apr 17 '16 at 10:59
  • Yes, but in his solution doesn't approach that the list is sorted. For this list for example [-2, 0, 2, 4] my trace is this: [-2, 0, 2, 4] -> [2, 4] -> [2]. And in his algorith: [-2, 0, 2, 4] -> [0, 2, 4] - [2, 4] -> [2]. I dived the problem in two for each recursive call. – Marco Canora Apr 17 '16 at 11:00
  • 1
    @MarcoCanora : If the list is guaranteed to be sorted then you can bail out early as soon as `number_list[start] > start`, since that condition will also be true for every subsequent item in the list. BTW, I forgot to mention in my previous comment: to get or set the recursion limit you use `sys.getrecursionlimit` and `sys.setrecursionlimit`. – PM 2Ring Apr 17 '16 at 11:05