-1

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?

  • This 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. – Patrick Artner Oct 01 '21 at 14:03
  • 2
    You are not adding 1 to the sum but to the index of 9 in order to include the 9 itself in the omitted range. – user2390182 Oct 01 '21 at 14:03
  • Does this answer your question? [Understanding slice notation](https://stackoverflow.com/questions/509211/understanding-slice-notation) – It_is_Chris Oct 01 '21 at 14:04
  • Make a simple loop : `for num in arr:` - test if `num == 6` if so do not add. set `saw_6 = True` - then loop further until you see a 9 _without adding. set `saw_6 = False` . Repeat until done. – Patrick Artner Oct 01 '21 at 14:05

5 Answers5

1

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.

user2390182
  • 72,016
  • 6
  • 67
  • 89
0

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.

Patrick Artner
  • 50,409
  • 9
  • 43
  • 69
0

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.

joprocorp
  • 176
  • 10
0

(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
Jussi Nurminen
  • 2,257
  • 1
  • 9
  • 16
0

The +1 in the second part of the subscript is there to include the 9 in the sum.

The solution you found won't work for several reasons:

  1. Logic: The expression 6 and 9 in arr does not express the condition appropriately (although it will be True if there is a 9 in the list and will work in spite of being wrong)
  2. Syntax: There is a missing closing bracket in the subscript or arr[...
  3. Completeness: The solution only accounts for one pair of 6-9 and would fail if there are multiple such pairs in the list

Here is a more basic approach that you should be able to

def summer_69(arr):
    result = 0                 # resulting sum
    addIt  = 1                 # current state of inclusion
    for n in arr:              # go through values of the list
        if n == 6: addIt = 0   # stop adding on a 6
        result += n * addIt    # add values (if adding)
        if n == 9: addIt = 1   # resume adding after a 9
    return result              # return the filtered sum
Alain T.
  • 40,517
  • 4
  • 31
  • 51