I am very new to Python and have been going through multiple tutorials to get better.
I have straggled with one difficult problem and found a solution. But it feels, works very newbie like. I think that I have tailored it to answer the specific question.
So the question is:
SUMMER OF ’69: Return the sum of the numbers in the array, except ignore sections of numbers starting with a 6 and extending to the next 9 (every 6 will be followed by at least one 9). Return 0 for no numbers.
summer_69([1, 3, 5]) --> 9 summer_69([4, 5, 6, 7, 8, 9]) --> 9 summer_69([2, 1, 6, 9, 11]) --> 14
My code to solve this is:
def summer_69(arr): list1 = arr summ = int() for i in range(0, len(arr)): if 6 in list1: listOfRange = range(list1.index(6), list1.index(9) + 1) for index in listOfRange: print(listOfRange) arr[index] = 0 if 6 != arr[i]: summ += arr[i] else: continue else: summ += arr[i] return summ
It is a very basic problem and I am very alerted that I have struggled with something like this already.
Advertisement
Answer
Short O(n) solution using an iterator and the in
operator to search for (and thereby skip to) the 9 following each 6:
def summer_69(lst): it = iter(lst) return sum(x for x in it if x != 6 or 9 not in it)
Less dense version:
def summer_69(lst): it = iter(lst) total = 0 for x in it: if x == 6: 9 in it else: total += x return total
Correctness check (random test cases) and benchmark (with [1] * 5000 + [6, 9] * 2500
) along with the accepted answer’s solution (which takes O(n2)):
30 out of 30 tests correct 303045 us 303714 us 304335 us 306007 us 309986 us summer_69_Accepted 444 us 446 us 464 us 478 us 527 us summer_69_Kelly1 442 us 448 us 453 us 465 us 500 us summer_69_Kelly2
Code (Try it online!):
from timeit import repeat def summer_69_Accepted(lst): copyoflist = lst[:] # makes shallow copy of list while True: if 6 not in copyoflist: return sum(copyoflist) indexof6 = copyoflist.index(6) indexof9 = copyoflist.index(9, indexof6+1) # begin search for 9 after 6 del copyoflist[indexof6:indexof9+1] def summer_69_Kelly1(lst): it = iter(lst) return sum(x for x in it if x != 6 or 9 not in it) def summer_69_Kelly2(lst): it = iter(lst) total = 0 for x in it: if x == 6: 9 in it else: total += x return total funcs = summer_69_Accepted, summer_69_Kelly1, summer_69_Kelly2 from random import randrange, choices def testcase(): def others(): return choices([0, 1, 2, 3, 4, 5, 7, 8], k=randrange(10)) lst = others() for _ in range(10): lst += [6, *others(), 9, *others()] return lst tests = correct = 0 for _ in range(10): lst = testcase() expect = funcs[0](lst.copy()) for func in funcs: result = func(lst.copy()) correct += result == expect tests += 1 print(correct, 'out of', tests, 'tests correct') print() lst = [1] * 5000 + [6, 9] * 2500 for func in funcs: times = repeat(lambda: func(lst), number=1) print(*('%6d us ' % (t * 1e6) for t in sorted(times)), func.__name__)