Home > Software design >  Find the unique number - Codewars
Find the unique number - Codewars

Time:12-10

I am trying to finish this kata on Codewars: https://i.stack.imgur.com/PxHDV.png

Here's my code suggestion:

import numpy as np

def find_uniq(arr):
    search_array = np.array(arr)
    print(search_array)
    unique = 0
    for number in search_array:
        if number != search_array[0]:
            unique = number
    print(unique)
    return unique

Here's what happens when:

1 - I press "Test": https://i.stack.imgur.com/9JO9t.png

2 - I press "Attempt": https://i.stack.imgur.com/gEMXL.png

So, I'm not able to finish this damn kata because there's that "1 should equal 0 problem". I've lost so much time thinking about what may be wrong with this, I am about to give up :(

Thoughts?

CodePudding user response:

Your code makes the assumption that which ever number is unequal to the first number is the unique number, this runs into problems when the first number is the unique number. You would also need to check whether the second number is equal to the third to determine whether the first number possibly is the unique number.

Alternatively you could use:

for number in search_array:
    counter = search_array.count(search_array[number])
    if counter == 1:
        return number
        break

CodePudding user response:

What you are doing is comparing each numbers to the first number of the array. So it work if the unique number is not the first one, but fail when it is the first one.

I suggest you to initialize unique to search_array[0] and start your for loop at the second element.

Then...think ! Maybe you can sort your search_array, maybe you can store temporary unique numbers in an array... :)

CodePudding user response:

As explained by the other users, you are comparing each element ONLY to the first one in the list, so if this first element is the unique, your code isn't going to work.

My aproach to this problem is to create a new list, almost equal to the original one, but shifted as this:

original=[3,3,4,3,3]
new=[3,4,3,3,3]

So, if you calculate "original-new", you get a list with almost all numbers equal to 0, except where the unique number is ON BOTH lists.

You can create the new list as follows:

new=original[1:] #all elements, except the first
new.append(original[0]) #appends the first element in the original to the last position

compare=[original[i]-new[i] for i in range(len(original))]

compare=[0,-1,1,0,0]

You can get the indexes:

indexes=[i for i in range len(original) if original[i]-new[i]!=0]

indexes=[1,2]

As I shifted the original list to the left, the index where the unique number is its the last one.

So, the unique number is:

unique=original[indexes[-1]]

The full code I tested:

#Creates a random list with a unique number in a random position    
n=1000000
a=[random.uniform(0,1)]*n
pos=round(random.uniform(0,n-1))
a[pos]=random.uniform(0,1)

#Creates the new list to compare
b=a[1:]
b.append(a[0])

#Finds the unique number
unique=a[[i for i in range(len(a)) if a[i]-b[i]!=0][-1]]

If you use Numpy, you can get a 3,5 times faster code:

array_a=np.array(a)
array_b=array_a[1:]
array_b=np.append(array_b,array_a[-1])
compare=array_a-array_b
unique=array_a[compare!=0][-1]

Greetings.

  • Related