Không phải giải pháp của tôi (rõ ràng tôi không phải là peter norvig!) Mà đây là một giải pháp cho câu hỏi (sửa đổi một chút) lịch sự của anh ấy:
http://nbviewer.ipython.org/url/norvig.com/ipython/xkcd1313.ipynb
chương trình anh ấy đưa ra như sau (công việc của anh ấy, không phải của tôi):
def findregex(winners, losers):
"Find a regex that matches all winners but no losers (sets of strings)."
# Make a pool of candidate components, then pick from them to cover winners.
# On each iteration, add the best component to 'cover'; finally disjoin them together.
pool = candidate_components(winners, losers)
cover = []
while winners:
best = max(pool, key=lambda c: 3*len(matches(c, winners)) - len(c))
cover.append(best)
pool.remove(best)
winners = winners - matches(best, winners)
return '|'.join(cover)
def candidate_components(winners, losers):
"Return components, c, that match at least one winner, w, but no loser."
parts = set(mappend(dotify, mappend(subparts, winners)))
wholes = {'^'+winner+'$' for winner in winners}
return wholes | {p for p in parts if not matches(p, losers)}
def mappend(function, *sequences):
"""Map the function over the arguments. Each result should be a sequence.
Append all the results together into one big list."""
results = map(function, *sequences)
return [item for result in results for item in result]
def subparts(word):
"Return a set of subparts of word, consecutive characters up to length 4, plus the whole word."
return set(word[i:i+n] for i in range(len(word)) for n in (1, 2, 3, 4))
def dotify(part):
"Return all ways to replace a subset of chars in part with '.'."
if part == '':
return {''}
else:
return {c+rest for rest in dotify(part[1:]) for c in ('.', part[0]) }
def matches(regex, strings):
"Return a set of all the strings that are matched by regex."
return {s for s in strings if re.search(regex, s)}
answer = findregex(winners, losers)
answer
# 'a.a|i..n|j|li|a.t|a..i|bu|oo|n.e|ay.|tr|rc|po|ls|oe|e.a'
trong đó người thắng và người thua là danh sách người thắng và người thua tương ứng (hoặc bất kỳ 2 danh sách nào của khóa học) xem bài viết để được giải thích chi tiết.
/^item1|atem2|item3|item4$/
có lẽ có quyền ưu tiên ngoài ý muốn (chuỗi phải bắt đầu bằngitem1
, chứaatem2
, chứaitem3
hoặc kết thúc bằngitem4
).