{"id":278,"date":"2013-04-28T04:07:29","date_gmt":"2013-04-28T04:07:29","guid":{"rendered":"http:\/\/alexboisvert.com\/musings\/?p=278"},"modified":"2013-04-28T04:11:48","modified_gmt":"2013-04-28T04:11:48","slug":"code-first-optimize-later-but-dont-forget-to-optimize","status":"publish","type":"post","link":"https:\/\/alexboisvert.com\/musings\/2013\/04\/28\/code-first-optimize-later-but-dont-forget-to-optimize\/","title":{"rendered":"Code first, optimize later (but don&#8217;t forget to optimize!)"},"content":{"rendered":"<p>I am totally on board with the &#8220;code first, optimize later&#8221; school of programming.  But sometimes one can forget to optimize, which can be a minor issue (if the code was already pretty optimized) or a major one (if there&#8217;s a glaringly obvious improvement to be made).  I recently coded something up to help someone out and it definitely needed some optimization before it was done.<\/p>\n<p>If you haven&#8217;t done <a href=\"http:\/\/xwordcontest.com\/2013\/04\/mgwcc-255-friday-april-19th-2013-shake-it-up.html\">Matt Gaffney&#8217;s &#8220;Shake It Up&#8221; crossword<\/a> you might want to do it before reading further, because there will be massive spoilers.  Done?  All right, let&#8217;s continue.<br \/>\n<!--more--><\/p>\n<p>So Matt asked me if there would be a way to fill a corner of a crossword grid with a 4&#215;4 block of letters such that (a) one square was a Qu rebus and (b) the 4&#215;4 block contained a 17-letter word following Boggle rules.  In Boggle, you try to make long words by moving like a king in chess through the 4&#215;4 block, never landing on the same letter more then once.  Now, it&#8217;s certainly easy to make a block like that which spells, say, SESQUICENTENNIALS:<\/p>\n<pre>\r\nSESQ\r\nNECI\r\nTENN\r\nSLAI\r\n<\/pre>\n<p>but it&#8217;s harder to make one that would then fit inside a crossword.  Here, for instance, we have the troubling EEEL and SNTS, letter patterns which don&#8217;t fit in many good crossword entries.<\/p>\n<p>My first thought was: for each 17-letter Boggle word (I started with INCONSEQUENTIALLY, SESQUICENTENNIALS and QUADRICENTENNIALS, but others are possible) I created a random grid with those letters, and then checked to see if the word was actually inside with Boggle rules, and then if the resulting letter patterns were good for a crossword.  I was pretty happy with this solution, but it was painfully slow!  Why?  Well, essentially because 16! is a humongous number (20,922,789,888,000 &#8212; approximately the number of red blood cells in the human body, thanks <a href=\"http:\/\/www.wolframalpha.com\/input\/?i=16!\">Wolfram Alpha!<\/a>) and so I was making 20 trillion grids (give or take) for each word I wanted to analyze.  I had a working solution, but it was unbearably slow, so I needed to optimize.<\/p>\n<p>My next thought was: instead of making a random grid and checking if it&#8217;s Boggle-friendly, why not just start with a Boggle-friendly grid?  This turned out to be no harder to code up than checking to see if a grid contained the word and it dropped the number of possible grids from 20 trillion to under 400,000.  Still a big number, but WAY smaller.  (For reference: 20 trillion seconds is over 600,000 years; 400,000 seconds is about four and a half days).  This made the algorithm quite fast.<\/p>\n<p><a href=\"http:\/\/pastebin.com\/HVpQWpWz\">You can check out the code here<\/a>.  I wrote it in C++ because that&#8217;s how I write all my code when I need it to run fast.  You&#8217;ll note in the code that there&#8217;s another optimization that can be made, but at this point I&#8217;m happy with how fast it ran.  Oh, and it did work for Matt &#8212; he was able to take some of the output and make a pretty nice crossword with it.<\/p>\n<p>Enjoy!<\/p>\n","protected":false},"excerpt":{"rendered":"<p>I am totally on board with the &#8220;code first, optimize later&#8221; school of programming. But sometimes one can forget to optimize, which can be a minor issue (if the code was already pretty optimized) or a major one (if there&#8217;s &hellip; <a href=\"https:\/\/alexboisvert.com\/musings\/2013\/04\/28\/code-first-optimize-later-but-dont-forget-to-optimize\/\">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-278","post","type-post","status-publish","format-standard","hentry","category-coding","category-puzzles"],"_links":{"self":[{"href":"https:\/\/alexboisvert.com\/musings\/wp-json\/wp\/v2\/posts\/278","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=278"}],"version-history":[{"count":3,"href":"https:\/\/alexboisvert.com\/musings\/wp-json\/wp\/v2\/posts\/278\/revisions"}],"predecessor-version":[{"id":281,"href":"https:\/\/alexboisvert.com\/musings\/wp-json\/wp\/v2\/posts\/278\/revisions\/281"}],"wp:attachment":[{"href":"https:\/\/alexboisvert.com\/musings\/wp-json\/wp\/v2\/media?parent=278"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/alexboisvert.com\/musings\/wp-json\/wp\/v2\/categories?post=278"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/alexboisvert.com\/musings\/wp-json\/wp\/v2\/tags?post=278"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}