Live data from Hacker News

Python code to solve xkcd 1313 by Peter Norvig

nbviewer.ipython.org

31–40 of 75 posts

Re: Python code to solve xkcd 1313 by Peter Norvig

#31
post #18
post #13

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…

[deleted]

Re: Python code to solve xkcd 1313 by Peter Norvig

#35

What would be a use for finding a minimal discriminating regex? Perhaps understanding the difference between boys' and girls' names?

Performance. For example if you are syntax highlighting a programming language with hundreds of keywords, then using a regexp like "(kwd1|kwd2|...|kwdn)" is not very efficient. An optimized regexp can do the same matching much faster.

Re: Python code to solve xkcd 1313 by Peter Norvig

#36
This is a great article. It's pretty fun to play around with this heuristic:

  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

#37

Exercise 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.

Re: Python code to solve xkcd 1313 by Peter Norvig

#39
post #37

Exercise 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.

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 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

#40
post #37

Earlier 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…

If you're after hashes you could just match a string of hexadecimal digits of a specific length (such as [0-9a-f]{16} ); much easier to define than English text.
Post reply on HN