Home > Blockchain >  Sum numbers in array, but ignore interval
Sum numbers in array, but ignore interval

Time:10-01

I'm new here, but I hope I can get some help. The problem is this:

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

I saw an answer in the forum that seems simple:

def summer_69(arr):
    if 6 and 9 in arr:
        c=sum(arr[arr.index(6):arr.index(9) 1)
        return sum(arr)-c
    else:
        return sum(arr)

It works, but I didn't understand why do I have to add 1 to the index sum. Can someone clarify this to me?

CodePudding user response:

For a clearer and actually working implementation:

def summer_69(arr):
    result = 0
    omit = False
    for num in arr:
        if omit:
            if num == 9:
                omit = False
        elif num == 6:
            omit = True
        else:
            result  = num
    return result

If you are going to use slices, make sure to provide appropriate starting points for the index search:

def summer_69(arr):
    if 6 not in arr:
        return sum(arr)
    i6 = arr.index(6)
    i9 = arr.index(9, i6)  # the first 9 after the first 6 
    return sum(arr[:i6])   summer_69(arr[i9 1:])

Here, the recursion will handle subsequent sections.

CodePudding user response:

Array slicing is explained more in details here and defined in your usecase as subarray = array[start:end] for start-end slicing which specify that :

Note: The result includes the start index, but excludes the end index.

The summer_69 function must return the sum of the numbers of the array which are not in between 6 and 9 (including 6 and 9 themselves). If we were to set start as the index of 6 and end as the index of 9, then the index of 9 would be excluded which is not what we want to do.

And to include it, we have to add 1 to select the element just after 9.

CodePudding user response:

Your code does not WORK - if 6 and 9 in arr is ALWAYS true - your else part is never executed - so even if it produces some valid result, your code is invalid and contains errors.

Try your code with a list with

  • several 6 and 9`s
  • a 9 before a 6 9 pair

your code does not work for those:

def summer_69(arr):
    if 6 and 9 in arr:
        c = sum(arr[arr.index(6):arr.index(9) 1])
        return sum(arr) - c
    else:                              # never going to happen
        return sum(arr)                # never going to happen

assert summer_69([9, 5, 6, 7, 8, 9]) == 9

Output:

assert summer_69([9, 5, 6, 7, 8, 9]) == 9
AssertionError

And it is also not very efficient - as you iterate the array twice whereas you can solve it in one pass.


Similar but different to schwobaseggl's solution:

def summer_69(arr):
    s = 0                           # total sum
    between_6_and_9 = False         # are we between 6 and 9?
    for n in arr:                   # walk over all nums
        if n == 6:                  # now we are at/after 6
            between_6_and_9 = True
        elif between_6_and_9 and n == 9:       # now we are after 9
            between_6_and_9 = False
        elif between_6_and_9:       # currently ignoring numbers
            pass
        else:
            s  = n                  # add it

    return s

assert summer_69([1, 3, 5]) == 9
assert summer_69([4, 5, 6, 7, 8, 9]) == 9
assert summer_69([2, 1, 6, 9, 11]) == 14

=> no exceptions == all asserts pass.

CodePudding user response:

(I know I'm not answering the question, but cannot resist) How about a filter that accepts everything outside of 6-to-9 blocks?

def filter_69(l):
    acc = True
    for x in l:
        if x in [6, 9]:
            acc = x == 9
        elif acc:
            yield x

Usage:

sum(filter_69([2, 1, 6, 9, 11]))
14
  • Related