Home > Back-end >  Find The Parity Outlier using dictionary {Python}
Find The Parity Outlier using dictionary {Python}

Time:07-23

during the Kata on Codewars called 'Find The Parity Outlier' I faced a problem, and have been trying to solve it using dictionary. I pass almost all tests except 4. Instruction for the Kata is:


You are given an array (which will have a length of at least 3, but could be very large) containing integers. The array is either entirely comprised of odd integers or entirely comprised of even integers except for a single integer N. Write a method that takes the array as an argument and returns this "outlier" N.


The function is:


def find_outlier(integers):
    d = dict()
    count = 0
    count1 = 0

            
    for i in range(len(integers)):
        if integers[i] % 2 != 0 :
            d['odd'] = integers[i]
        else:
            d['even'] = integers[i]
            
    for j in range(len(integers)):
        if integers[j] % 2 == 0:
            count  = 1
        else:
            count1  = 1
            if count > count1:
                return d['odd']
            return d['even']

Test Results:

  1. 2 should equal 1
  2. 36 should equal 17
  3. 36 should equal -123456789
  4. 0 should equal 1

So the question is? Why is it so? Can you help me to sort the problem out? Thanks a lot!

CodePudding user response:

I'm not sure what exactly you're referring to with that list of test results. In general though, your method with the dictionary seems like it might be overcomplicating things a bit as well. You shouldn't need to use a dict, and you shouldn't need two for loops either. Here's an alternative solution to this problem using only list comprehension.

def find_outlier(arr):
    # input should be an array-like of integers (and length >= 3) with either only one odd element OR only one even element
    odd_mask = [n%2 != 0 for n in arr] # boolean array with True in the location(s) where the elements are odd
    even_mask = [n%2 == 0 for n in arr] # boolean array with True in the location(s) where the elements are even

    N_odd = sum(odd_mask) # number of odd elements in the input
    N_even = sum(even_mask) # number of even elements in the input

    if N_even == 1: # if even is the 'outlier'...
        return arr[even_mask.index(True)] # return the element of the input array at the index we determined we had an even
    elif N_odd == 1: # if odd is the 'outlier'...
        return arr[odd_mask.index(True)] # return the element of the input array at the index we determined we had an odd
    else: # something has gone wrong or the input did not adhere to the standards set by the problem
        return None

And even this is technically not as efficient as it could be. Let me know if you try this and whether it solves whatever issue you were experiencing with expected results.

CodePudding user response:

In your code the final part should not be in the else block, nor even in the for loop:

      if count > count1:
            return d['odd']
      return d['even']

Like this is may give a wrong result. For instance, if the first number in the input is odd, and is the only odd one, then this code will return d['even'] which is obviously wrong.

Place these lines after the loop (with correct indentation) and it should work.

However, this problem can be solved without dictionary or extra lists. Have a go at it.

def find_outlier(integers): parity = integers[-2] % 2 if integers[-1] % 2 != parity: if integers[0] % 2 != parity: return integers[-2] else: return integers[-1] for i in integers: if i % 2 != parity: return i

CodePudding user response:

Would you try this approach - to see if it help you: (It passed the posted inputs ...)

Some observations here - generally it's not recommend to use index to get list items (your index-way); secondly it's just need one for-loop pass to determine if the number is even or odd then put them in each category. Then at the end just check the size of these 2 lists.

Of course, there's still room to improve it - but that's beyond the current scope of question.

def find_outlier(integers):
    odds = [x for x in integers if x & 1]
    evens= [x for x in integers if not x%2]

    return odds[0] if len(evens) > len(odds) else evens[0] # lesser is the answer
  • Related