Finding distance from valid number

66 Views Asked by At

I have a game related problem that is pretty complex. Here is the simplified version of the problem. I have a list of "good" numbers.

mylist="""100 101 102 104 105 106 107 220 221 289 290 542 544 """

The customer has a choice of 5 numbers like 103, 299 and 999 and I need to sort those choices based on it's relevance to the actual list.

z = """103 299 999 108 543 """

103 is the best choice because it is closest to the good numbers. 299 is better option than 999 because of it's distance from good numbers.

Here is the python code that returns the distance of each number from element of the list and it shows the count. For e.g. there are 2 occurrences of distance "1"

103-102=1
103-104=-1

It means there are 2 numbers available at a "distance" of 1 for the given number 103. It is displayed as # 103 [( 1, 2 )]

finallist=[]

for y in z.split():
    newlist=[]
    for i in mylist.split():
        diff=int(y)-int(i)
        newlist.append(abs(diff))
    finallist.append((y, newlist))

from collections import Counter

for i, d in finallist:
    c=Counter(d)
    print (i, c.most_common())

103 [(1, 2), (2, 2), (3, 2), (4, 1), (117, 1), (118, 1), (439, 1), (441, 1), (186, 1), (187, 1)]
299 [(192, 1), (193, 1), (194, 1), (195, 1), (197, 1), (198, 1), (199, 1), (9, 1), (10, 1), (78, 1), (79, 1), (243, 1), (245, 1)]
999 [(897, 1), (898, 1), (899, 1), (709, 1), (710, 1), (455, 1), (457, 1), (778, 1), (779, 1), (892, 1), (893, 1), (894, 1), (895, 1)]
108 [(1, 1), (2, 1), (3, 1), (4, 1), (6, 1), (7, 1), (8, 1), (112, 1), (113, 1), (434, 1), (436, 1), (181, 1), (182, 1)]
543 [(1, 2), (322, 1), (323, 1), (436, 1), (437, 1), (438, 1), (439, 1), (441, 1), (442, 1), (443, 1), (253, 1), (254, 1)]

I want to sort these numbers in the following order:

103 because it has highest number of double occurances for lower values like 1,2,3
108 because it is part of contiguous list
543 because of the instance of double occurance
299 because closer to list
999 least relevant 

If that is not possible, it is ok if I get sort order of 103, 543, 108 ...

I tried to consider the average but that did not return the expected weight.

# finallist.append((y, sum(newlist)/len(mylist)))

I will like to know if this is a mathematical problem.

Is there any way to calculate overall relevance of a number to the given list of numbers?

1

There are 1 best solutions below

0
On BEST ANSWER

Your whole problem is that you are not able to exactly describe what it means for a number to be close to the list. As such it's very nice that you've included an example of what you mean. If you sum all of the reciprocals in the list, you get the sort order you want in this case. I hope this will generalize to what you meant in other cases as well.

Here is the updated code

finallist=[]

for y in z.split():
    newlist=[]
    for i in mylist.split():
        diff=int(y)-int(i)
        newlist.append(1/abs(diff))
finallist.append((y, sum(newlist)))

So you can call

sorted(finallist, key=lambda x: -x[1])

[('103', 3.948957667177934),
 ('108', 2.5512523646278855),
 ('543', 2.030021412668412),
 ('299', 0.2806110083679157),
 ('999', 0.01759146176664312)]

Hope this helps, otherwise please clarify your problem statement and give a case where it does not work as expected.

It would also make for better code if you do not store your integers in strings, but instead do

mylist=[100, 101, 102, 104, 105, 106, 107, 220, 221, 289, 290, 542, 544]

This way you can avoid converting from string to integer each time you need a number, which should be faster.