{"id":244,"date":"2012-11-05T03:49:06","date_gmt":"2012-11-05T03:49:06","guid":{"rendered":"http:\/\/alexboisvert.com\/musings\/?p=244"},"modified":"2012-11-05T03:49:06","modified_gmt":"2012-11-05T03:49:06","slug":"joons-puzzler","status":"publish","type":"post","link":"https:\/\/alexboisvert.com\/musings\/2012\/11\/05\/joons-puzzler\/","title":{"rendered":"Joon&#8217;s puzzler"},"content":{"rendered":"<p>Joon recently posted <a href=\"https:\/\/twitter.com\/joonpahk\/status\/264028534496976896\">the following on Twitter<\/a>:<\/p>\n<blockquote><p>wordplay #puzzler: think of two unrelated phrases, both with enumeration 3, 4. the 3-letter words are synonyms; so are the 4-letter words. <\/p><\/blockquote>\n<p>Well, I had just recently downloaded the unbelievably awesome <a href=\"http:\/\/nltk.org\/\">natural language toolkit for Python<\/a> so I thought I&#8217;d test it out on this problem.  Here&#8217;s what I came up with:<br \/>\n[python]<br \/>\n#!\/usr\/bin\/python<\/p>\n<p>from nltk.corpus import wordnet as wn<br \/>\nimport re<br \/>\nimport sys<\/p>\n<p>myfile = sys.argv[1]<br \/>\nword1_length = int(sys.argv[2])<br \/>\nword2_length = int(sys.argv[3])<\/p>\n<p>def get_synonyms(word, length):<br \/>\n    &#8221;&#8217;<br \/>\n    Gets all synonyms of `word` of length `length`<br \/>\n    &#8221;&#8217;<br \/>\n    syns = list()<br \/>\n    synsets = wn.synsets(word)<br \/>\n    for synset in synsets:<br \/>\n        for w in synset.lemma_names:<br \/>\n            if len(w) == length and w != word and w not in syns:<br \/>\n                syns.append(w)<br \/>\n    return syns<\/p>\n<p>fid = open(myfile,&#8217;r&#8217;)<br \/>\ndict = [x.rstrip(&#8216;\\r\\n&#8217;) for x in fid.readlines()]<br \/>\nfid.close()<\/p>\n<p># Slim this down a bit<br \/>\nmy_pattern = r&#8217;^[a-z]{%i}_[a-z]{%i}$&#8217; % (word1_length, word2_length)<br \/>\nmy_phrases = [x for x in dict if re.match(my_pattern,x)]<\/p>\n<p># Go through and check<br \/>\nfor p in my_phrases:<br \/>\n    w1 = p[:word1_length]<br \/>\n    w2 = p[word1_length+1:]<br \/>\n    # Get synonyms of the appropriate length<br \/>\n    l1 = get_synonyms(w1,word1_length)<br \/>\n    l2 = get_synonyms(w2,word2_length)<br \/>\n    if len(l1) != 0 and len(l2) != 0:<br \/>\n        for t1 in l1:<br \/>\n            for t2 in l2:<br \/>\n                test_phrase = t1 + &#8216;_&#8217; + t2<br \/>\n                if test_phrase in my_phrases:<br \/>\n                    print p + &#8216; -> &#8216; +  test_phrase<br \/>\n[\/python]<\/p>\n<p>To use it you will need a fairly comprehensive list of phrases &#8212; the <a href=\"http:\/\/dumps.wikimedia.org\/enwiktionary\/latest\/\">data dump from Wiktionary<\/a> is what I used here.  Just run it as<\/p>\n<pre>\r\npuzzler.py enwiki.txt 3 4\r\n<\/pre>\n<p>and it will spit out:<\/p>\n<pre>\r\nbad_lots -> big_deal\r\nbad_lots -> big_band\r\nbad_mind -> big_head\r\nbig_head -> bad_mind\r\nbum_rush -> rat_race\r\nhad_best -> get_well\r\nhit_home -> off_base\r\noff_base -> hit_home\r\nrat_race -> bum_rush\r\n<\/pre>\n<p>(Yes, <a href=\"http:\/\/wordnetweb.princeton.edu\/perl\/webwn?s=big&#038;sub=Search+WordNet&#038;o2=&#038;o0=1&#038;o8=1&#038;o1=1&#038;o7=&#038;o5=&#038;o9=&#038;o6=&#038;o3=&#038;o4=&#038;h=\">WordNet thinks that &#8220;big&#8221; and &#8220;bad&#8221; are synonyms<\/a>.)<\/p>\n<p>You may notice that <a href=\"https:\/\/twitter.com\/joonpahk\/status\/264436934020046848\">Joon&#8217;s intended answer<\/a> isn&#8217;t among the results &#8212; one of those phrases wasn&#8217;t on Wiktionary &#8230; until I added it (it will probably be in the next data dump).<\/p>\n<p>Anyway!  You may notice that the code offers you room to work with other word lengths.  Is there anything interesting good there?  Well, I kind of like &#8220;light switch&#8221; and &#8220;short-change&#8221;.  &#8220;Well liquors&#8221; and &#8220;good spirits&#8221; is a good one too.  Anything else?  Feel free to experiment with the code and let me know in the comments.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Joon recently posted the following on Twitter: wordplay #puzzler: think of two unrelated phrases, both with enumeration 3, 4. the 3-letter words are synonyms; so are the 4-letter words. Well, I had just recently downloaded the unbelievably awesome natural language &hellip; <a href=\"https:\/\/alexboisvert.com\/musings\/2012\/11\/05\/joons-puzzler\/\">Continue reading <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[3,5],"tags":[],"class_list":["post-244","post","type-post","status-publish","format-standard","hentry","category-coding","category-puzzles"],"_links":{"self":[{"href":"https:\/\/alexboisvert.com\/musings\/wp-json\/wp\/v2\/posts\/244","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/alexboisvert.com\/musings\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/alexboisvert.com\/musings\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/alexboisvert.com\/musings\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/alexboisvert.com\/musings\/wp-json\/wp\/v2\/comments?post=244"}],"version-history":[{"count":2,"href":"https:\/\/alexboisvert.com\/musings\/wp-json\/wp\/v2\/posts\/244\/revisions"}],"predecessor-version":[{"id":246,"href":"https:\/\/alexboisvert.com\/musings\/wp-json\/wp\/v2\/posts\/244\/revisions\/246"}],"wp:attachment":[{"href":"https:\/\/alexboisvert.com\/musings\/wp-json\/wp\/v2\/media?parent=244"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/alexboisvert.com\/musings\/wp-json\/wp\/v2\/categories?post=244"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/alexboisvert.com\/musings\/wp-json\/wp\/v2\/tags?post=244"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}