Can someone explain what does this line mean and why does he use it as heuristic? key=lambda c: 3*len(matches(c, uncovered)) - len(c)
IMHO, sadly, that part is serving as a shibboleth. The clue is how he explains all the simple parts of the script with comments, but leaves this part unexplained, making some of us feel left out of the cool club. Implying: if you don't grasp it immediately you must not be up to it. Overall it's a great post, but as to the cryptic parts of it, it's disappointing to see this kind of thing on the part of someone we all…
Python code to solve xkcd 1313 by Peter Norvig
31–40 of 75 posts
Re: Python code to solve xkcd 1313 by Peter Norvig
#32When I read 'subtitles', i wondered about the .srt files of the movies.
Re: Python code to solve xkcd 1313 by Peter Norvig
#33What would be a use for finding a minimal discriminating regex? Perhaps understanding the difference between boys' and girls' names?
Re: Python code to solve xkcd 1313 by Peter Norvig
#34EDIT: possibly down-voted because someone though it was sarcastic???
I was actually thinking of this problem before the XKCD comic, for detecting hashes on hardrives efficiently...
Re: Python code to solve xkcd 1313 by Peter Norvig
#35What would be a use for finding a minimal discriminating regex? Perhaps understanding the difference between boys' and girls' names?
Re: Python code to solve xkcd 1313 by Peter Norvig
#36 lambda c: 3*len(matches(c, uncovered)) - len(c)
Here's a trivial way to explore it: say we generalize the heuristic to H(a, b). H(a,b) = lambda c: a*len(matches(c, uncovered)) - b*len(c)
The original heuristic is considered H(3,1) by this definition. Then we can play around with a and b to see if we'd get smaller results. def findregex_lambda(winners, losers, a, b):
"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: a*len(matches(c, winners)) - b*len(c))
cover.append(best)
pool.remove(best)
winners = winners - matches(best, winners)
return '|'.join(cover)
>>> findregex_lambda(starwars, startrek, 3, 1)
' T|E.P| N'
>>> findregex_lambda(starwars, startrek, 3, 2)
' T|B| N| M'
Or, to automate this: def best_H_heuristic(winners, losers):
d = {(a,b) : len(findregex_lambda(winners, losers, a,b)) for a in range(0,4) for b in range(0,4)}
return min(d, key=d.get)
>>> best_H_heuristic(starwars, startrek):
(3,1)
Looks like H(3,1) is pretty good for this case. What about the nfl teams? >>> best_H_heuristic(nfl_in, nfl_out)
(3, 2)
>>> findregex_lambda(nfl_in, nfl_out, 3, 1)
'pa|g..s|4|fs|sa|se|lt|os'
>>> findregex_lambda(nfl_in, nfl_out, 3, 2)
'pa|ch|4|e.g|sa|se|lt|os'
Not the best heuristic there. H(3,1) wins or ties for the boys/girls set, left/right set and drugs/cities set, which just goes to show you that picking a heuristic off a gut guess isn't such a bad approach.You could also explore heuristics of different forms:
M(a,b,d,e) = lambda c: a*len(matches(c, uncovered))^b - d*len(c)^e
Or trying completely different formats: L(a,b) = lambda c: a*log(len(matches(c, uncovered))) - b*len(c)Re: Python code to solve xkcd 1313 by Peter Norvig
#37Exercise for the reader, write a regex to distinguish random noise from English EDIT: possibly down-voted because someone though it was sarcastic??? I was actually thinking of this problem before the XKCD comic, for detecting hashes on hardrives efficiently...
Re: Python code to solve xkcd 1313 by Peter Norvig
#38 /M | [TN]|B/
is suboptimal, but could be / [TMN]|B/
But that (and the article) leaves out the subtitle for Star Trek 1: "The Motion Picture". For that, Randall's original expression works.Re: Python code to solve xkcd 1313 by Peter Norvig
#39Exercise for the reader, write a regex to distinguish random noise from English EDIT: possibly down-voted because someone though it was sarcastic??? I was actually thinking of this problem before the XKCD comic, for detecting hashes on hardrives efficiently...
Almost any regex containing a common English phrase of a few words, like /of course/, would give you a very high accuracy rate on a large enough dataset and a very low false positive rate. English has low entropy per bit.
(note the inspiration was a nefarious regex scanner for finding bitcoin hashes. I have no intention of building such a thing, but the idea of a random detector regex intrigued me. Is it possible?)
My idea was more like calculate the statistics of character n-grams in english (all of which exist in random noise too), but count the most unlikely occurrences until you hit some probabilistic threshold that indicates some well thought out decision boundary.
Re: Python code to solve xkcd 1313 by Peter Norvig
#40Earlier quoted context omitted.
Almost any regex containing a common English phrase of a few words, like /of course/, would give you a very high accuracy rate on a large enough dataset and a very low false positive rate. English has low entropy per bit.
That strategy would return results for any phrase not containing "of course". Which would be rather a lot of results in any document. I am envisioning a regex that plucks hashes from emails, for example. Some parts English, some parts cryptographic "noise". Pick the noise from the English (note the inspiration was a nefarious regex scanner for finding bitcoin hashes. I have no intention of building such a thing, but…