CodingBat sum67: why is this solution wrong?

Question:

I’m working on the following codingbat problem:

Return the sum of the numbers in the array, except ignore sections of numbers starting with a 6 and extending to the next 7 (every 6 will be followed by at least one 7). Return 0 for no numbers.

sum67([1, 2, 2]) → 5
sum67([1, 2, 2, 6, 99, 99, 7]) → 5
sum67([1, 1, 6, 7, 2]) → 4

My solution is:

def sum67(nums):
    sum = 0 
    throwaway = 0
    for i in range(len(nums)):
        if throwaway == 0:
            if nums[i] == 6:
                throwaway = 1
        elif throwaway == 1 and i > 0 and nums[i-1] == 7:
            throwaway = 0
        if throwaway == 0:
            sum += nums[i]
    return sum

I totally know this is not the best solution, but I’m just curious to know why this is wrong. Could you please explain me why this is wrong and in which particular case it gives a wrong result?

Asked By: Wilco

||

Answers:

Well, your program has a bug. Check the results of the following:

print sum67([1,2,5])
print sum67([1,2,6,5,7])
print sum67([1,2,6,5,7,6,7])

This will print:

8
3
16 <-- wrong

If a 7 is followed by a 6 immediately, you will add the 6 and all following numbers. I’m not sure if more than one range of 6 … 7 is allowed in the input, but if it is, you have to fix your algorithm.

This simple implementation does return correct numbers:

def sum67(nums):
    state=0
    s=0
    for n in nums:
        if state == 0:
            if n == 6:
                state=1
            else:
                s+=n
        else:
            if n == 7:
                state=0
    return s

Besides, if you don’t need to use an index for some obscure reasons, you can directly iterate over the elements of a list ( for element in list: ... ).

Answered By: hochl

Here’s my solution to that problem. As answered already, the issue is when a 6 occurs immediately after a 7. I solved this in a slightly different way, so I thought I’d post it.

def sum67(nums):
  total = 0
  i=0  
  while i < len(nums):
    if nums[i] == 6:
      while nums[i] != 7:
        i+=1
      i+=1
    if i<len(nums) and nums[i]!=6:  
      total+=nums[i]
      i+=1
  return total
Answered By: TheNeophyte
public int sum67(int[] nums) {
 int sum=0;
  for(int i=0; i<nums.length ; i++)



{
          if(nums[i]==6)
               for(int k=i+1 ; k<nums.length ; k++ )
                  {if(nums[k]==7)
                                {i=k; break;}
                  }   
           else if(nums[i]==6) 
              sum=sum+nums[i];
          else
              sum=sum+nums[i];


  }
  return sum;
}
Answered By: TEERATH KUMAR

Below is my solution for your reference:

def sum67(nums):
flag=False
sum=0

for num in nums:
    if(num==6):                  #Turn the flag on if the number is 6
        flag=True
        continue
    if(num==7 and flag is True): #Turn the flag Off when 7 is seen after 6
        flag=False
        continue
    if(flag is False):           #Keep on adding the nums otherwise
       sum+=num
return sum
Answered By: Anirudh

My solution:

def sum67(nums):
    result = 0
    flag = True
    for num in nums:
        if num == 6:
            flag = False
        if flag:
            result += num
        if num == 7:
            flag = True
    return result
Answered By: K. Menyah

I know this isn’t the best solution, but thought to share :

def detect67(nums):
  count = nums.count(6)
  pos6 = 0
  pos7 = 0
  sum1 = []
  for i in range (len(nums)):
    sum1.append(nums[i])  
    # if I do just sum1 = nums, they use SAME memory locations.
  #print ("Count=",count)
  for i in range (count):
    pos6 = sum1.index(6)
    pos7 = sum1.index(7)
  if pos7<pos6:
    sum1[pos7] = 0
    pos7 = sum1.index(7)

    del nums[pos6:pos7+1]
    del sum1[pos6:pos7+1]
    count = nums.count(6)
    if count == 0:
      return (nums)

  

  return (nums)


def sum67(nums):

 detect67(nums)
 sums=0
 if nums == []:
   return 0
 for i in range (len(nums)):
   sums+=nums[i]
 return sums
Answered By: Arun

This is my edit of @TheNeophyte code. I liked that solution because that’s how I’d likely approach the problem. The only edit really was taking out the

if i<len(nums) and nums[i]!=6:

and just putting an elif statement without saying

i<len(nums)

since it’s not needed again after the first while loop.

My edit below VVV

def sum67(anArray):
    arrTotal = 0
    n =0
    while n < len(anArray):
        if anArray[n] == 6:
            while anArray[n] != 7:
                n+=1
            n+=1
        elif anArray[n] != 6:
            arrTotal += anArray[n]
            n+=1
    return arrTotal
Answered By: michael harris

here’s my 6 liner answer. Hope this helps

def summer_67(arr):
    s = 0
    for x in arr:
        if x not in range(6,7+1):
            s = s + x
    return s

Answered By: Ryan Darren Morales

Well, you could use nested loops..

def sum67(nums):
    s=0
    flag=1
    for n in nums:
        while flag:
            if n!=6:
                s+=n
                break
            else:
                flag=0
        while not flag:
            if n!=9:
                break
            else:
                flag=1
    return s          
Answered By: Pyrosill

Just to add, if the last element is a 7 you don’t need to iterate through every element. The question states ” ignore sections of numbers starting with a 6 and extending to the next 7 (every 6 will be followed by at least one 7)”. Once you find a 6 you can simply check if the last element is a 7 and if so simply break out and return the sum; otherwise, you can continue to go through the remaining elements. This is helpful when working with a larger number of elements in an array.
ex. [1, 2, 2, 6, 99, 99, 2, 99, 99, 2, 99, 99, 2, 99, 99, 7]

My solution:

def sum67(arr):
    sum = 0
    tmp = 0
    for n in arr:
        if n == 6:
            tmp = 6
            continue
        if tmp == 6:
            if n == 7:
                tmp = 0
                continue
            elif arr[-1] == 7:
                break
            else:
                continue
        sum += n
    return sum
Answered By: user7548672

My solution for this I Know this is quite readable but not the best code:

def sum67(nums):
  offcount = False
  sum = 0 
  for i in range(len(nums)):
    if offcount == False:
      if nums[i] == 6:
        offcount = True
      else:
        sum = sum + nums[i]
    else:
      if nums[i] == 7 :
        offcount = False
  return sum

I hope this helps:)

def sum67(nums):
    result = 0
    inside = False
    for i in range(len(nums)):
        if not inside and nums[i] != 6:
            result += nums[i]
        if nums[i] == 6:
            inside = True
        if nums[i] == 7:
            inside = False
    return result
Answered By: Madhan
def sum67(nums):
  sum = 0
  sumbrake = False

  for i in nums:
    if i != 6 and sumbrake == False:
      sum += i
    else:
      sumbrake = True

    if i == 7:
      sumbrake= False

  return sum
Answered By: SayedRakib
def sum67(nums):

    while nums.count(6) >= 1:
        list = (nums[0:nums.index(6)]) + (nums[nums.index(7)+1:len(nums)])
        nums = list
    return sum(nums)
Answered By: V VISHNUJYOTHI
def sum67(arr):
    for n in range (0, len(arr)):
        if arr[n] == 6:
            Sum1 = sum(arr[0:n])
            print ("Before 6 Sum Numbers:", Sum1)
    for k in range (0, len(arr)):
        if arr[k] ==7:
            Sum2 = sum(arr[(k)+1:])
            print ("After 7 Sum Numbers:", Sum2)
    if 6 and 7 in arr:
        print("Last Result")
        return (Sum1+Sum2)
    else:
        print("Last Result")
        return sum(arr)
Answered By: Saidv2007

simplified code without while and for loop :

    def summer_69(arr):
        pos6 = 0;
        pos9 = 0;
        newArr = [];
        if 6 in arr:
            pos6 = arr.index(6);
        if 9 in arr: 
            pos9 = arr.index(9);
        if 6 in arr and 9 in arr : 
            newArr =  arr[0:pos6] + arr[pos9+1:len(arr)];
        else:
            newArr = arr;
    return sum(newArr);
    pass
Answered By: Ranjan Mishra

Maybe a more Pythonian approach?

def sum67(arr):
    if (6 in arr):
        i1 = arr.index(6)
        i2 = arr[i1:].index(7)
        res = sum(arr[0:i1]+arr[i1+i2+1:])
    else:
        res = sum(arr)
    return res
Answered By: Visiedo

Here is my 13 line answer, which uses List index positions to exclude values enclosed by every [6..7] pair.

Technique: Return the sum of array elements upon subtracting the (sum of) excluded elements.

def sum67(nums):
  idx_list=[]  
  for i in range(len(nums)):
    if nums[i]==6:
      c_6 = i    # index pos of 6
      j = c_6+1   # counter to find index position of 7
      while nums[j]!=7:   # stop search when 7 spotted in list
        j+=1
      c_7 = j    # index pos of 7
      idx_list += list(range(c_6,c_7+1))  # list of index position(s) of elements to be excluded

  idx_main = list(set(idx_list))   # set() removes repeated index positions captured while looping
  del_val = [nums[i] for i in idx_main]
  return sum(nums)-sum(del_val)
Answered By: Sumax
def sum67(nums):
    sum=0
    sum6=0
    for n in nums:
        sum+=n
    if nums.count(6) >= 1:
       a=nums.index(6)
       b=nums.index(7)+1
       nums67=nums[a:b]    
       for i in nums67:
           sum6 += i 
    return sum - sum6 
Answered By: Amin

This may not the best solution , but its simple and gave correct output all cases

def sum67(nums):
  sum = 0
  i = 0
  while( i < len(nums)):
    if nums[i] == 6:
       while(nums[i] != 7):
         i += 1
    else:
      sum += nums[i]
    i += 1
  return sum
Answered By: Harshithkumar

Just a short and efficient (O(n) time, O(1) space) alternative, using an iterator:

def sum67(nums):
    it = iter(nums)
    return sum(x for x in it if x != 6 or 7 not in it)

This mainly sums the values. But whenever a 6 is encountered, the 7 not in it consumes all values until the next 7 (and it’s false, so none of the values from that 6 to that 7 make it into the sum).

Answered By: Kelly Bundy
def sum67(nums):
    c=0
    state=True
    for i in nums:
        if state:
            if i==6:
                state=False
            else:
                c+=i

        else:
            if i==7:
                state=True
    return c
Answered By: Megha Shyam
def sum_69(arr):
    x=arr.index(6)
    y=arr.index(9)
    if 6  not in arr:
        return sum(arr)
    else:
        sum1=arr[:x]
        sum2=arr[y+1:]
        sum3=sum1+sum2
        return sum(sum3)
Answered By: Tejaswini_Nettem

may be this will help you:

def sum_67(arr):
    while 6 in arr:
        del arr[arr.index(6):arr.index(7)+1]
    return sum(arr)
Answered By: Banajit Rajbongshi
def sum67(nums):
  
  cnt = 0
  ignore = False
  for num in nums:
    if not ignore and num == 6:
      ignore = True
    
    if not ignore:
      cnt = cnt + num

    if ignore and num == 7:
      ignore = False
  
  return cnt
Answered By: Deep

My approach was to build a new list which consisted only of valid segments ie segments that did not start with a 6 and end with a 7 for that corresponding 6. Then I simply computed the sum of the elements of that new list. Worked perfect in the codingbat exercise platform

def sum67(nums):
    lst =[]  #holds result after discarding invalid segments
    while 6 in nums:   # Continue until no more 6's found in nums segment
        #Find the first 6
        idx6 = nums.index(6)

        #Build list upto but excluding the first 6
        lst += nums[:idx6]
        
        
        #Find the next 7
        idx7 = nums[idx6:].index(7)  # this would be relative to nums[idx6:]
        
        #slice
        idx = idx6+idx7           # absolute position of 7 w.r.t nums
        nums = nums[idx+1:]       # slice from the position of the 7 to end
    lst += nums                   # takes care of any leftovers after the last 7
    return sum(lst)          

Can be condensed to fewer lines of code but I wanted to maintain readability of code. I am wondering if there is a recursive way to solve this. Working on it.

Thanks everyone for your great alternate solutions

Answered By: AoxmxoA

Here is the shortest solution I have seen for this question:

def sum67(nums):
  while 6 in nums: 
    del nums[nums.index(6):nums.index(7,nums.index(6))+1]
  return sum(nums)
Answered By: macroT

In my solution, I activate and deactivate with a boolean when a 6 starts and a 7 ends. While in the "active == True" state, the code still functions normally except now there’s a "temp_count". If the array reaches a 7, the "temp_count" will be subtracted from "count".

def sum67(nums):
  count = 0
  temp_count = 0
  active = False
  
  for i in range(len(nums)):
    count += nums[i]
    
    if nums[i] == 6:
      active = True
      
    if nums[i] == 7 and active == True:
      active = False
      count = count - temp_count - 7
      temp_count = 0
      
    if nums[i] == 6 or active == True:
      temp_count += nums[i]
      
  return count
Answered By: Sebastien Grondin

The following code works well too.

def sum67(nums):
    total1 = 0
    total2 = 0

    for y in range(0, len(nums)):
        if nums[y] == 6:
            total1 = nums[0:y]

        if nums[y] == 7:
            total2 = nums[y + 1:]

    total = total1 + total2
    return sum(total)
Answered By: d0ntr13

def sum67(nums):
while 6 in nums:
x = nums[nums.index(6):nums.index(7)+1]
for i in x:
nums.remove(i)
return(sum(nums))

Answered By: Hamdy Gomaa
Categories: questions Tags:
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.