This is a follow-up to my previous question about finding min and max values of an iterable. Aho-Corasick algorithm was suggested to solve the problem. Below is my solution with the use of ahocorapy library.
Short re-cap of the problem:
You are given 2 arrays (
genes
andhealth
), one of which have a 'gene' name, and the other - 'gene' weight (aka health). You then given a bunch of strings, each containing valuesm
andn
, which denote the start and end of the slice to be applied to thegenes
andhealth
arrays, and the 'gene'-string, for which we need to determine healthiness. Then we need to return health-values for the most and the least healthy strings.
I think there might be something off with the code, but not sure what. It works quite fine for small testcases, giving more or less same timing as previous versions of the solution showed, but when it comes to large testcases, my PC basically hangs.
Example of a small testcase:
genes = ['a', 'b', 'c', 'aa', 'd', 'b']
health = [1, 2, 3, 4, 5, 6]
gene1 = "1 5 caaab" (result = 19 = max)
gene2 = "0 4 xyz" (result = 0 = min)
gene3 = "2 4 bcdybc" (result = 11)
Large testcase (2 lists 100K elements each; testcase 41K+ elements): txt in my dropbox (2,80 MB) (too large for pastebin)
So, I have 2 questions: 1) What is wrong with my code, how can I impore its performace 2) How do I apply the Aho-Corasick without turning to any non-standard library (because, most likely, it cannot be installed on HackerRank server)
def geneshealth(genes, health, testcase):
from ahocorapy.keywordtree import KeywordTree
import math
min_weight = math.inf
max_weight = -math.inf
for case in testcase:
#construct the keyword tree from appropriately sliced "genes" list
kwtree = KeywordTree(case_insensitive=True)
fl, ceil, g = case.split()
for i in genes[int(fl):int(ceil)+1]:
kwtree.add(i)
kwtree.finalize()
#search the testcase list for matches
result = list(kwtree.search_all(g))
hea = 0
for gn, _ in result:
for idx, val in enumerate(genes):
if val == gn:
hea += health[idx]
if hea < min_weight:
min_weight = hea
if hea > max_weight:
max_weight = hea
return(min_weight, max_weight)