patternpythonMinor
Number Of Matching Elements In Two Lists
Viewed 0 times
numberelementstwolistsmatching
Problem
I have many sets of 2 strings. I'm trying to determine the number of matching elements in these 2 strings. The rules are if the strings share a common letter, that's a point, order does matter, but each letter in the first string can only match one of the letters in the second string. So in the strings
Hopefully that gets across how it works.
Here is the most efficient code I've been able to come up with, but its horribly convoluted. I hoping someone could think of something better.
Surely this isn't the best way to do this, but I haven't been able to figure anything else out. I tried creating an algorithm with
'aaaab', 'acccc', only 1 point is awarded because there is only one 'a' to match in the second string. Here are a few examples:aaabb bbaaa 5
aabbb bbbaa 5
aaabb aabbb 4
aaabb ccaaa 3
aaaaa bbbbb 0
ababa babab 4
aabcc babaf 3
abcde abfgh 2
bacde abdgh 3Hopefully that gets across how it works.
Here is the most efficient code I've been able to come up with, but its horribly convoluted. I hoping someone could think of something better.
def Score(guess, solution):
guess = list(guess)
solution = list(solution)
c = 0
for g in guess:
if g in solution and g != "_":
c += 1
solution[solution.index(g)] = "_"
return cSurely this isn't the best way to do this, but I haven't been able to figure anything else out. I tried creating an algorithm with
Counter and doing guess&solution, which worked, but ended up being way slower. Anyone have any ideas?Solution
As you have updated your examples, you can write some code to ensure the code we are about to write works properly :
Now, the main issue in your code is that we are performing complicated (dirty?) string logic and checking many times if some letter is in a list. The real solution is to count letters in both string. Each letter will count for n points where n is the minimum between the number of times it appears in string 1 and the number of times it appears in string 2.
Using
from collections import Counter
Abusing generator expressions, you can also write this :
def main():
"""Main function"""
assert Score('aaabb', 'bbaaa') == 5
assert Score('aabbb', 'bbbaa') == 5
assert Score('aaabb', 'aabbb') == 4
assert Score('aaabb', 'ccaaa') == 3
assert Score('aaaaa', 'bbbbb') == 0
assert Score('ababa', 'babab') == 4
assert Score('aabcc', 'babaf') == 3
assert Score('abcde', 'abfgh') == 2
assert Score('bacde', 'abdgh') == 3Now, the main issue in your code is that we are performing complicated (dirty?) string logic and checking many times if some letter is in a list. The real solution is to count letters in both string. Each letter will count for n points where n is the minimum between the number of times it appears in string 1 and the number of times it appears in string 2.
Using
Counter, you can write this :from collections import Counter
def Score(guess, solution):
g = Counter(guess)
s = Counter(solution)
n = 0
for l,c in g.iteritems():
n+=min(c, s[l])
return nAbusing generator expressions, you can also write this :
def Score(s1, s2):
c = Counter(s2)
return sum(min(n, c[l]) for l,n in Counter(s1).iteritems())Code Snippets
def main():
"""Main function"""
assert Score('aaabb', 'bbaaa') == 5
assert Score('aabbb', 'bbbaa') == 5
assert Score('aaabb', 'aabbb') == 4
assert Score('aaabb', 'ccaaa') == 3
assert Score('aaaaa', 'bbbbb') == 0
assert Score('ababa', 'babab') == 4
assert Score('aabcc', 'babaf') == 3
assert Score('abcde', 'abfgh') == 2
assert Score('bacde', 'abdgh') == 3def Score(guess, solution):
g = Counter(guess)
s = Counter(solution)
n = 0
for l,c in g.iteritems():
n+=min(c, s[l])
return ndef Score(s1, s2):
c = Counter(s2)
return sum(min(n, c[l]) for l,n in Counter(s1).iteritems())Context
StackExchange Code Review Q#51525, answer score: 3
Revisions (0)
No revisions yet.