<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/atom10full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><feed xmlns="http://www.w3.org/2005/Atom" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0">
 
 <title>The Kanwei Decrees...</title>
 
 <link href="http://kanwei.com/" />
 <updated>2009-10-06T02:58:56-04:00</updated>
 <id>http://kanwei.com/</id>
 <author>
   <name>Kanwei Li</name>
   <email>kanwei@gmail.com</email>
 </author>

 
 <link rel="self" href="http://feeds.feedburner.com/kanwei" type="application/atom+xml" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com" /><entry>
   <title>Facebook Jobs Puzzle&amp;mdash;battleship</title>
   <link href="http://feedproxy.google.com/~r/kanwei/~3/wtrzVjNXBS0/facebook-battleship.html" />
   <updated>2009-10-06T00:00:00-04:00</updated>
   <id>http://kanwei.com/code/2009/10/06/facebook-battleship</id>
   <content type="html">&lt;p&gt;From &lt;a href="http://www.facebook.com/careers/puzzles.php?puzzle_id=14"&gt;Facebook's Job Puzzles page&lt;/a&gt;:&lt;/p&gt;

&lt;p&gt;Well, now that I have no use for a Facebook job, I better start posting the rest of my solutions. This was a fun one... a straightforward puzzle with no requirements for fancy algorithms or data structures... just good old organic strategy.&lt;/p&gt;

&lt;p&gt;In battleship, you can hit every boat by laying down a checkerboard firing pattern:&lt;/p&gt;

&lt;p&gt;&lt;img src="/code/battleship.png" /&gt;&lt;/p&gt;

&lt;p&gt;Once you hit something, you can aim for one of the four adjacent squares to finish off the boat.&lt;/p&gt;

&lt;p&gt;You can either randomly aim at squares in the pattern or hard-code a certain sequence, which is what I did. There might be an optimal sequence/strategy for statistical reasons, but then again a smart opponent can adapt and counter any specific strategy. That's all extra credit for you folks out there.&lt;/p&gt;

&lt;p&gt;The following solution in Ruby passed the Facebook puzzle robot:&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="c1"&gt;#!/usr/bin/env ruby&lt;/span&gt;
&lt;span class="nb"&gt;require&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;gen-rb/Battleship&amp;#39;&lt;/span&gt;

&lt;span class="n"&gt;host&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;ARGV&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="no"&gt;ARGV&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;thriftpuzzle.facebook.com&amp;quot;&lt;/span&gt;
&lt;span class="n"&gt;port&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;ARGV&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="no"&gt;ARGV&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;].&lt;/span&gt;&lt;span class="n"&gt;to_i&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;9060&lt;/span&gt;

&lt;span class="n"&gt;trans&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Thrift&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Socket&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;host&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;port&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;trans&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;open&lt;/span&gt;

&lt;span class="vg"&gt;$battle&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Battleship&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Client&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="no"&gt;Thrift&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;BinaryProtocol&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;trans&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="nb"&gt;p&lt;/span&gt; &lt;span class="vg"&gt;$battle&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;registerClient&lt;/span&gt;

&lt;span class="nb"&gt;p&lt;/span&gt; &lt;span class="vg"&gt;$battle&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;placePiece&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="no"&gt;Ship&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;CARRIER&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;     &lt;span class="no"&gt;Coordinate&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;new&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="ss"&gt;:row&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:column&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;}),&lt;/span&gt; &lt;span class="kp"&gt;true&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nb"&gt;p&lt;/span&gt; &lt;span class="vg"&gt;$battle&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;placePiece&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="no"&gt;Ship&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;BATTLESHIP&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;  &lt;span class="no"&gt;Coordinate&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;new&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="ss"&gt;:row&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:column&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;}),&lt;/span&gt; &lt;span class="kp"&gt;false&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nb"&gt;p&lt;/span&gt; &lt;span class="vg"&gt;$battle&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;placePiece&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="no"&gt;Ship&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;DESTROYER&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;   &lt;span class="no"&gt;Coordinate&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;new&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="ss"&gt;:row&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:column&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;}),&lt;/span&gt; &lt;span class="kp"&gt;true&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nb"&gt;p&lt;/span&gt; &lt;span class="vg"&gt;$battle&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;placePiece&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="no"&gt;Ship&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;SUBMARINE&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;   &lt;span class="no"&gt;Coordinate&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;new&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="ss"&gt;:row&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;7&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:column&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;}),&lt;/span&gt; &lt;span class="kp"&gt;false&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nb"&gt;p&lt;/span&gt; &lt;span class="vg"&gt;$battle&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;placePiece&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="no"&gt;Ship&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;PATROL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;      &lt;span class="no"&gt;Coordinate&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;new&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="ss"&gt;:row&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:column&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;7&lt;/span&gt;&lt;span class="p"&gt;}),&lt;/span&gt; &lt;span class="kp"&gt;false&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;sequence&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;[]&lt;/span&gt;
&lt;span class="vg"&gt;$done&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;[]&lt;/span&gt;
&lt;span class="vg"&gt;$ptdown&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kp"&gt;false&lt;/span&gt;

&lt;span class="n"&gt;sequence&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;
  &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;7&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;7&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;9&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;9&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;7&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;9&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;7&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;7&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;9&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;7&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;9&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;9&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;]&lt;/span&gt;
  
&lt;span class="n"&gt;strat1&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;
  &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;7&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;7&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;9&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;7&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;9&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;7&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;9&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;9&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;]&lt;/span&gt;

&lt;span class="n"&gt;strat2&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;
  &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;7&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;9&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;7&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;9&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;9&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;]&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;attack&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pos&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kp"&gt;nil&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="vg"&gt;$done&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;include?&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pos&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kp"&gt;nil&lt;/span&gt; &lt;span class="k"&gt;unless&lt;/span&gt; &lt;span class="n"&gt;pos&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;pos&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;pos&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;pos&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;
  
  &lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="vg"&gt;$battle&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;isMyTurn&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;times&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
  &lt;span class="vg"&gt;$done&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;pos&lt;/span&gt;
  &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="vg"&gt;$battle&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;attack&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="no"&gt;Coordinate&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;new&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="ss"&gt;:row&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;pos&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:column&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;pos&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="p"&gt;}))&lt;/span&gt;
  &lt;span class="vg"&gt;$ptdown&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kp"&gt;true&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="no"&gt;AttackResult&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;SUNK_PATROL&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;neighbors&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pos&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;# North, South, East, West&lt;/span&gt;
  &lt;span class="o"&gt;[&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;pos&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;pos&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;pos&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;pos&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;pos&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;pos&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;]]&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;pos&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;pos&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;]]&lt;/span&gt; &lt;span class="o"&gt;]&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;hit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pos&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;direction&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kp"&gt;nil&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;pos&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; &lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;direction&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;
  &lt;span class="n"&gt;neighs&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;neighbors&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pos&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;direction&lt;/span&gt;
    &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;attack&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pos&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kp"&gt;false&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;nil?&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;hit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;neighs&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;direction&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;direction&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="no"&gt;AttackResult&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;HIT&lt;/span&gt;
    &lt;span class="c1"&gt;# return (result &amp;lt; 6) ? true : false&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kp"&gt;false&lt;/span&gt;
  &lt;span class="k"&gt;else&lt;/span&gt;
    &lt;span class="n"&gt;neighs&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;each_with_index&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;hit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="k"&gt;begin&lt;/span&gt;
  &lt;span class="kp"&gt;loop&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;sequence&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;empty?&lt;/span&gt;
      &lt;span class="vg"&gt;$ptdown&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="n"&gt;sequence&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;strat2&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;sequence&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;strat1&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
    &lt;span class="n"&gt;next_move&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;sequence&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;shift&lt;/span&gt;
    &lt;span class="k"&gt;next&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="vg"&gt;$done&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;include?&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;next_move&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;attack&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;next_move&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="no"&gt;AttackResult&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;HIT&lt;/span&gt;
      &lt;span class="n"&gt;hit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;next_move&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="k"&gt;rescue&lt;/span&gt; &lt;span class="no"&gt;Thrift&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;TransportException&lt;/span&gt;
  &lt;span class="n"&gt;trans&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;close&lt;/span&gt;
  &lt;span class="nb"&gt;exit&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/pre&gt;
&lt;/div&gt;

&lt;img src="http://feeds.feedburner.com/~r/kanwei/~4/wtrzVjNXBS0" height="1" width="1"/&gt;</content>
 <feedburner:origLink>http://kanwei.com/code/2009/10/06/facebook-battleship.html</feedburner:origLink></entry>
 
 <entry>
   <title>Morality and Markets</title>
   <link href="http://feedproxy.google.com/~r/kanwei/~3/WEJiP1OVWC8/morality-and-markets.html" />
   <updated>2009-10-05T00:00:00-04:00</updated>
   <id>http://kanwei.com/2009/10/05/morality-and-markets</id>
   <content type="html">&lt;p&gt;I am fascinated by Michael Sandel's course on Justice at Harvard, which is now being televised on PBS and &lt;a href="http://www.justiceharvard.org/"&gt;broadcasted online for free&lt;/a&gt;. He is an effective instructor from what I've seen so far. My interest piqued, I sought more of his material and discovered that he delivered the 2009 Reith Lectures, which I have finished listening to.&lt;/p&gt;

&lt;p&gt;He says in the first lecture:&lt;/p&gt;

&lt;blockquote&gt;
We're living with the economic fallout of the financial crisis and we're struggling to make sense of it. One way of understanding what's happened is to see that we're at the end of an era, an era of market triumphalism. The last three decades were a heady, reckless time of market mania and deregulation. We had the free market fundamentalism of the Reagan-Thatcher years and then we had the market friendly Neo-Liberalism of the Clinton and Blair years, which moderated but also consolidated the faith that markets are the primary mechanism for achieving the public good.&lt;/blockquote&gt;


&lt;p&gt;This statement may sound fine and good to those without a background in Austrian Economics or an honest view of history, especially after the recent bubble collapse. Instead of taking easy knee-jerk stances on capitalism and free-markets, let's instead explore what free markets and capitalism really are.&lt;/p&gt;

&lt;p&gt;Free markets are simply transactions between voluntary parties in non-coercive situations, and capitalism is simply letting private parties decide on the distribution of money, labor, and goods instead of the government.&lt;/p&gt;

&lt;p&gt;No country today has truly free markets. Just like no country can ever become totally socialistic or communist, there is always going to be coercion of some sort in the world to prevent completely free markets. Indeed, a completely capitalistic society without any coercion and where goods are perfectly distributed through voluntary transactions to fulfill personal preferences is just as utopian and impossible as a fully communist society where everyone gets what they need by an omniscient state.&lt;/p&gt;

&lt;p&gt;So what's the difference? Easy: one is compatible with natural law, and the other is completely incompatible.&lt;/p&gt;

&lt;p&gt;We live in a world of competition. In nature, it's "dog eat dog." However, humans stopped eating dogs a while ago (at least most societies) and we now have morality and have put restrictions on what is considered ethical. The Founding Fathers said, "life, liberty, and the pursuit of happiness." Assuming the latter implies property rights, and that the Founding Fathers were correct, we can say that everyone is entitled to their lives, their freedom, and the fruits of their labor. Capitalism naturally fits these rights: you own what you earn, and you can trade what you have with someone else, if you want to. Communism is the opposite: you don't own anything, and the state takes care of all your needs, ignoring your preferences.&lt;/p&gt;

&lt;p&gt;Backing up to Sandel's quote, I disagree with his interpretation of deregulation and "free market fundamentalism" as being the causes of our current problems. He does not explain the rationale or give any examples, so we don't know what his reasoning is. Our money supply, controlled by the Federal Reserve, is far from free, favoring banks and the government. People are forced to pay a third of their salaries for things they have no control over. On the free to unfree market spectrum, we are moving further and further from the free end.&lt;/p&gt;

&lt;p&gt;Sandel raises another point that is much better developed:&lt;/p&gt;

&lt;blockquote&gt;
And to have this debate, we have to think through the moral limits of markets. We need to recognize that there are some things that money can't buy and other things that money can buy but shouldn't... Economists often assume that markets are inert, that they do not touch or taint the goods they regulate. But this is a mistake. Markets leave their mark. Often market incentives erode or crowd out non-market incentives... Perhaps the best-known example of market norms eroding or crowding out non-market norms involves the case of blood donation. The sociologist Richard Titmuss compared the United States system, which permitted the buying and selling of blood for transfusion, with the system in the UK which banned financial incentives and relied wholly on donated blood. Titmuss found that rather than improve the quality and supply of blood, the commercialization of blood led to shortages, inefficiencies and a greater incidence of contaminated blood. His explanation: putting a price on blood turned what had been a gift into a commodity. It changed the norms associated with blood donation. Once blood is bought and sold in the market, people are less likely to feel a moral obligation to give it out of altruism.&lt;/blockquote&gt;


&lt;p&gt;He gives plenty more examples along the same line that ask the same question: should markets be used to make all decisions?&lt;/p&gt;

&lt;p&gt;Let's discuss the blood donation example. First of all, the cost of donating blood is low (give up about one hour of time for a resource that's easily replenished) while the rewards are high (the feeling that you're potentially saving someone's life). Because the cost is low, a market may not even be necessary. Titmuss's argument that "putting a price on blood turned what had been a gift into a commodity" may be valid, but inconsequential. If more blood is needed, you can hold more donation drives. If even that is insufficient, you can offer payment. There is no coercion of any sort.&lt;/p&gt;

&lt;p&gt;Pollution is another heated topic that is often discussed. Should "cap and trade" programs be initiated to control pollution? Sandel is completely right on this topic and the answer is no:&lt;/p&gt;

&lt;p&gt;1) Mandating an arbitrary upper pollution limit and imposing fines is coercion for an act (polluting) that is almost impossible to quantify, unless some party is directly hurt as a result (usually not the case).&lt;/p&gt;

&lt;p&gt;2) Imposing limits and credits gives companies a license to pollute.&lt;/p&gt;

&lt;p&gt;I think it is rather obvious that any company that wants to succeed in a free market environment will try to minimize the potentiality for social ostracism and a tarnished reputation, and thus will want to minimize pollution out of goodwill and publicity. However, until technology improves, pollution will always be a byproduct of some processes, including breathing.&lt;/p&gt;

&lt;p&gt;What do you think will reduce pollution more: taxing your power company for polluting, who will simply increase what they charge you to make up for it, or ostracizing your neighbor for driving an oversized Hummer? What do you think has already happened?&lt;/p&gt;

&lt;p&gt;Note that some people will consider "cap and trade" programs as "free market intrusions" to public policy, and this is completely false. Cap and trade programs are pseudo-markets enforced by government mandate and coercion through taxation; there is nothing free in speech or beer about it.&lt;/p&gt;

&lt;p&gt;But just because some things in life don't really fit markets, doesn't mean that markets shouldn't be used for most things. Healthcare and education, two domains that require serious labor, need to be distributed by markets. Access to food and shelter are not rights, and neither are healthcare and education. To make a moral case for them would fail unless we defined them as rights, and even if we did, we would fail like the communists for practical reasons.&lt;/p&gt;

&lt;p&gt;Morality and free markets depend on each other. Free markets rely on non-coercion, and members of free market communities have much to lose from being amoral. Sandel is partially right: markets needn't/shouldn't be used for everything, but for everything else, there's free markets.&lt;/p&gt;
&lt;img src="http://feeds.feedburner.com/~r/kanwei/~4/WEJiP1OVWC8" height="1" width="1"/&gt;</content>
 <feedburner:origLink>http://kanwei.com/2009/10/05/morality-and-markets.html</feedburner:origLink></entry>
 
 <entry>
   <title>Thesis and Life After Thesis</title>
   <link href="http://feedproxy.google.com/~r/kanwei/~3/V8WfxvqEi34/life-after-thesis.html" />
   <updated>2009-09-03T00:00:00-04:00</updated>
   <id>http://kanwei.com/2009/09/03/life-after-thesis</id>
   <content type="html">&lt;p&gt;So I had been hoping to have written tons of blog posts, posted solutions to NP-hard problems, and become an internet celebrity by the end of the 2009 summer. Unfortunately, something called a Masters Thesis took over my life and turned me into a zombie for all of 3 months. Only recently have I stopped walking in a staggered fashion with a dull look in my eyes.&lt;/p&gt;

&lt;p&gt;Writing a thesis is like being a slave to yourself. When the initial excitement ends and the actual work begins, you begin to think about how you got into this predicament. It didn't seem so bad on paper. I mean, you've always done well in class, so why would a thesis be any different? Besides, you have a whole summer.&lt;/p&gt;

&lt;p&gt;Two months in, you stare into the ceiling at night and immediately fall asleep due to mental exhaustion. You feel a huge elephant sitting on your brain-waves. Ideas once crystal clear are now hazy. You lose confidence in your writing. Coding standards get thrown out the window as the deadlines approach. You don't mind sleeping under your desk.&lt;/p&gt;

&lt;p&gt;But then you ignore the doubts in the back of your head, focus, bite the bullet, and pull through. If you're lucky to have a &lt;a href="http://www.mathcs.emory.edu/~jlu/"&gt;great advisor&lt;/a&gt; like I did, the result is a great feeling of satisfaction as you finish and defend your thesis.&lt;/p&gt;

&lt;p&gt;My topic was to get a better sense of how to do query optimization on &lt;a href="http://en.wikipedia.org/wiki/SPARQL"&gt;SPARQL queries&lt;/a&gt;, the newly W3C formalized query language for RDF. I based my work on a novel indexing structure called TripleT developed by &lt;a href="http://www.win.tue.nl/~gfletche/"&gt;Dr. George Fletcher&lt;/a&gt;. I looked at the different kinds of SPARQL joins possible and for each general case, came up with a general game-plan to ensure good join ordering.&lt;/p&gt;

&lt;p&gt;Take a look if you're interested: &lt;a href="/research/Kanwei_Li_Thesis.pdf"&gt;Cost Analysis of Joins in RDF Query Processing Using the TripleT Index&lt;/a&gt;. (40 page PDF)&lt;/p&gt;

&lt;p&gt;Life after thesis involves working full-time. A new beginning of paychecks and no homework. Should be fun.&lt;/p&gt;
&lt;img src="http://feeds.feedburner.com/~r/kanwei/~4/V8WfxvqEi34" height="1" width="1"/&gt;</content>
 <feedburner:origLink>http://kanwei.com/2009/09/03/life-after-thesis.html</feedburner:origLink></entry>
 
 <entry>
   <title>Universal Healthcare</title>
   <link href="http://feedproxy.google.com/~r/kanwei/~3/dy3q665XWjo/universal-healthcare.html" />
   <updated>2009-08-15T00:00:00-04:00</updated>
   <id>http://kanwei.com/2009/08/15/universal-healthcare</id>
   <content type="html">&lt;p&gt;There is a raging battle out on the internet and in real life about universal healthcare. I find it quite funny because the people arguing against universal healthcare have absolutely no chance; the proponents don't fight fair!&lt;/p&gt;

&lt;p&gt;It generally goes like this: (A = anti-universal healthcare, F = for universal healthcare)&lt;/p&gt;

&lt;p&gt;A: Universal healthcare will make things worse because prices will rise even further and the quality will drop as well.&lt;/p&gt;

&lt;p&gt;F: LOL, LOOK AT SWEDEN AND CANADA AND CUBA&lt;/p&gt;

&lt;p&gt;A: Have you done your homework? Most of those countries have lower healthcare quality and many people can't even get into the system because it's over-burdened. Some people in those countries can't get healthcare even if they wanted to pay out of pocket because it's all government operated, so they go to America instead for treatment. Those countries have a fraction of the US population, have taxes twice as high, and yet can barely compete with the shoddy system America has. For that much tax you'd expect your laundry to be done for free too.&lt;/p&gt;

&lt;p&gt;F: UR LYIN. SWEDEN HAS THE HIGHEST LIVING STANDARD. CANADIANS SEEM OK TOO. CUBA OWNS US AT BASEBALL SO THEY MUST BE COOL TOO&lt;/p&gt;

&lt;p&gt;A: Whatever. For effective reform, we should allow people to start paying for healthcare directly by giving more people access to tax-free Health Savings Accounts, let uncertified doctors practice, and not require companies to provide healthcare, which lowers demand and increases supply, thus lowering prices and letting private practice be profitable again. It's sound economics.&lt;/p&gt;

&lt;p&gt;F: BUT WHAT ABOUT THE 1% OF THE POPULATION WHO CAN'T GET HEALTHCARE? YOU'RE EVIL. YOU'RE PRIVILEGED AND HAVE NO IDEA WHAT IT FEELS LIKE TO HAVE NO INSURANCE (COINCIDENTALLY, NEITHER DO I). EVERYBODY SHOULD HAVE HEALTHCARE, THINK OF THE CHILDREN AND WHALES&lt;/p&gt;

&lt;p&gt;A: That sounds nice in theory, but who's going to pay for it?&lt;/p&gt;

&lt;p&gt;F: YOU ARE&lt;/p&gt;

&lt;p&gt;A: Not just me, but you too, and everyone else. We're all going to be paying more for less return. Does that make any sense?&lt;/p&gt;

&lt;p&gt;F: DON'T TRY TO REASON YOUR WAY OUT OF THIS, YOU UNPATRIOTIC WEASEL&lt;/p&gt;

&lt;p&gt;A: You're being allured by socialism and its promises of something for nothing. It's never worked, however, as exemplified by a century of socialist experimentation in China and the Soviet Union that killed millions.&lt;/p&gt;

&lt;p&gt;F: LOL THOSE GUYS WERE NOOBS. WE'RE AMERICANS FFS! WE CAN DO IT! YES WE CAN!!!!!111&lt;/p&gt;

&lt;p&gt;To the proponents of universal healthcare: if you're really so worried about uninsured people, and not just trying to satisfy an emotional need or obtaining a moral victory, please start a charity and chip in your own money instead of telling everyone else to.&lt;/p&gt;
&lt;img src="http://feeds.feedburner.com/~r/kanwei/~4/dy3q665XWjo" height="1" width="1"/&gt;</content>
 <feedburner:origLink>http://kanwei.com/2009/08/15/universal-healthcare.html</feedburner:origLink></entry>
 
 <entry>
   <title>99 Bottles of Beer in Clojure</title>
   <link href="http://feedproxy.google.com/~r/kanwei/~3/HLkbm7Ig694/clojure-bottles-beer.html" />
   <updated>2009-05-07T00:00:00-04:00</updated>
   <id>http://kanwei.com/code/2009/05/07/clojure-bottles-beer</id>
   <content type="html">&lt;p&gt;Programmers, in their continual search for popular acceptance, have made writing a program to generate the
lyrics of &lt;a href="http://99-bottles-of-beer.net/lyrics.html"&gt;99 Bottles of Beer&lt;/a&gt; into somewhat of an advanced
"Hello World" exercise. I did it today in Clojure and it took me about 5 minutes. There's a &lt;a href="http://99-bottles-of-beer.net/"&gt;repository&lt;/a&gt; of programs written in 1270 programming languages.&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="c1"&gt;; 99 bottles of beer in Clojure&lt;/span&gt;
&lt;span class="c1"&gt;; Kanwei Li, 2009&lt;/span&gt;

&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;defn &lt;/span&gt;&lt;span class="nv"&gt;inflect-bottle&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;time&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
  &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;cond &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;= &lt;/span&gt;&lt;span class="nv"&gt;time&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="s"&gt;&amp;quot;1 bottle of beer&amp;quot;&lt;/span&gt;
        &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;= &lt;/span&gt;&lt;span class="nv"&gt;time&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="s"&gt;&amp;quot;no more bottles of beer&amp;quot;&lt;/span&gt;
        &lt;span class="nv"&gt;:else&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;str &lt;/span&gt;&lt;span class="nv"&gt;time&lt;/span&gt; &lt;span class="s"&gt;&amp;quot; bottles of beer&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)))&lt;/span&gt;

&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;defn &lt;/span&gt;&lt;span class="nv"&gt;sing&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;time&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
  &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;= &lt;/span&gt;&lt;span class="nv"&gt;time&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;println &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;str &lt;/span&gt;&lt;span class="s"&gt;&amp;quot;No more bottles of beer on the wall, no more bottles of beer.\n&amp;quot;&lt;/span&gt; 
                  &lt;span class="s"&gt;&amp;quot;Go to the store and buy some more, 99 bottles of beer on the wall.&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;let &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;inflected&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;inflect-bottle&lt;/span&gt; &lt;span class="nv"&gt;time&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
          &lt;span class="nv"&gt;next-time&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;- &lt;/span&gt;&lt;span class="nv"&gt;time&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)]&lt;/span&gt;
      &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;println &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;str &lt;/span&gt;&lt;span class="nv"&gt;inflected&lt;/span&gt; &lt;span class="s"&gt;&amp;quot; on the wall, &amp;quot;&lt;/span&gt; &lt;span class="nv"&gt;inflected&lt;/span&gt; 
                    &lt;span class="s"&gt;&amp;quot;.\nTake one down and pass it around, &amp;quot;&lt;/span&gt; 
                    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;inflect-bottle&lt;/span&gt; &lt;span class="nv"&gt;next-time&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="s"&gt;&amp;quot; on the wall.\n&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
      &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;recur&lt;/span&gt; &lt;span class="nv"&gt;next-time&lt;/span&gt;&lt;span class="p"&gt;))))&lt;/span&gt;

&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;sing&lt;/span&gt; &lt;span class="mi"&gt;99&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;
&lt;/div&gt;

&lt;img src="http://feeds.feedburner.com/~r/kanwei/~4/HLkbm7Ig694" height="1" width="1"/&gt;</content>
 <feedburner:origLink>http://kanwei.com/code/2009/05/07/clojure-bottles-beer.html</feedburner:origLink></entry>
 
 <entry>
   <title>Facebook Jobs Puzzle&amp;mdash;hoppity in Clojure</title>
   <link href="http://feedproxy.google.com/~r/kanwei/~3/L9mV_mfTJFc/facebook-hoppity-clojure-io.html" />
   <updated>2009-04-30T00:00:00-04:00</updated>
   <id>http://kanwei.com/code/2009/04/30/facebook-hoppity-clojure-io</id>
   <content type="html">&lt;p&gt;Puzzle is from &lt;a href="http://www.facebook.com/careers/puzzles.php"&gt;Facebook's Job Puzzles page&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;I try to learn as many languages as I can in my spare time, and Clojure is my latest subject. I think
it has potential to replace Ruby as my primary general purpose language.&lt;/p&gt;

&lt;p&gt;To make sure I had the build process right for the puzzle submission, I decided to solve the easy
hoppity puzzle in Clojure. However, I hit a stumbling block almost immediately... I didn't know
how to read from a file!&lt;/p&gt;

&lt;p&gt;I have Stuart Halloway's beta book on Clojure and tried to look up how to do file I/O, but couldn't
find anything. (I do recommend the book though, it is quite good, especially on concurrency).&lt;/p&gt;

&lt;p&gt;&lt;a href="http://www.amazon.com/gp/product/1934356336?ie=UTF8&amp;amp;tag=a01f6d-20&amp;amp;linkCode=as2&amp;amp;camp=1789&amp;amp;creative=390957&amp;amp;creativeASIN=1934356336"&gt;&lt;img border="0" src="/code/clojure.jpg"&gt; Buy it from Amazon&lt;/a&gt;&lt;img src="http://www.assoc-amazon.com/e/ir?t=a01f6d-20&amp;amp;l=as2&amp;amp;o=1&amp;amp;a=1934356336" width="1" height="1" border="0" alt="" style="border:none !important; margin:0px !important;" /&gt;&lt;/p&gt;

&lt;p&gt;Neither is it explained on the official &lt;a href="http://clojure.org"&gt;Clojure website&lt;/a&gt;. These
little things need to be mentioned more prominently for fast adoption. Anyways, I realized that
using the standard Java approach would work, so I used the BufferedReader and FileReader stack.&lt;/p&gt;

&lt;p&gt;Note that Clojure looks just like Lisp, and has basically all of the features of Lisp that make it good.
The fact that it can use any Java library is a huge win as well.&lt;/p&gt;

&lt;p&gt;In Clojure, arguments passed in from the command line are kept as a vector called
 &lt;code&gt;*command-line-args*&lt;/code&gt;, and you can get the nth argument by unsurprisingly using the
&lt;code&gt;nth&lt;/code&gt; function, like I do below.&lt;/p&gt;

&lt;p&gt;Anything with a period in the function name is a Java method call, so it's easy to tell what's pure
Clojure and what's Java. Clojure seems to rely on Java for all I/O, which is not a bad
decision, but should be better documented.&lt;/p&gt;

&lt;p&gt;I will be posting more on Clojure as I play with it!&lt;/p&gt;

&lt;p&gt;The following solution passed the Facebook puzzle robot:&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="c1"&gt;; Hoppity hop in Clojure&lt;/span&gt;
&lt;span class="c1"&gt;; Kanwei Li, 2009&lt;/span&gt;

&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;def &lt;/span&gt;&lt;span class="nv"&gt;*input-file*&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;nth &lt;/span&gt;&lt;span class="nv"&gt;*command-line-args*&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;def &lt;/span&gt;&lt;span class="nv"&gt;*input*&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;java&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;io&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;BufferedReader&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;java&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;io&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;FileReader&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt; &lt;span class="nv"&gt;*input-file*&lt;/span&gt;&lt;span class="p"&gt;)))&lt;/span&gt;

&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;defn &lt;/span&gt;&lt;span class="nv"&gt;get-num&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;
  &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;Integer&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;first &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;split&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;readLine&lt;/span&gt; &lt;span class="nv"&gt;*input*&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="s"&gt;&amp;quot;\n&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;))))&lt;/span&gt;

&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;dotimes &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;i&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;get-num&lt;/span&gt;&lt;span class="p"&gt;)]&lt;/span&gt;
  &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;let &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;num&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;+ &lt;/span&gt;&lt;span class="nv"&gt;i&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="nv"&gt;answer&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;cond &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;= &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;rem &lt;/span&gt;&lt;span class="nv"&gt;num&lt;/span&gt; &lt;span class="mi"&gt;15&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="s"&gt;&amp;quot;Hop&amp;quot;&lt;/span&gt;
                     &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;= &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;rem &lt;/span&gt;&lt;span class="nv"&gt;num&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="s"&gt;&amp;quot;Hophop&amp;quot;&lt;/span&gt;
                     &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;= &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;rem &lt;/span&gt;&lt;span class="nv"&gt;num&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="s"&gt;&amp;quot;Hoppity&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)]&lt;/span&gt;
    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;not &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;nil? &lt;/span&gt;&lt;span class="nv"&gt;answer&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
      &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;println &lt;/span&gt;&lt;span class="nv"&gt;answer&lt;/span&gt;&lt;span class="p"&gt;))))&lt;/span&gt;
&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;In contrast to my Ruby version, there is no LOC difference, and they are both well-readable to me.&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="c1"&gt;#!/usr/bin/env ruby&lt;/span&gt;
&lt;span class="c1"&gt;# Hoppity puzzle&lt;/span&gt;
&lt;span class="c1"&gt;# Kanwei Li, 2009&lt;/span&gt;

&lt;span class="n"&gt;filename&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;ARGV&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;
&lt;span class="n"&gt;input&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;File&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;filename&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;n&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;input&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;gets&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;to_i&lt;/span&gt;
&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;upto&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="mi"&gt;15&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
    &lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;Hop&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;
  &lt;span class="k"&gt;elsif&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
    &lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;Hophop&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;
  &lt;span class="k"&gt;elsif&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
    &lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;Hoppity&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/pre&gt;
&lt;/div&gt;

&lt;img src="http://feeds.feedburner.com/~r/kanwei/~4/L9mV_mfTJFc" height="1" width="1"/&gt;</content>
 <feedburner:origLink>http://kanwei.com/code/2009/04/30/facebook-hoppity-clojure-io.html</feedburner:origLink></entry>
 
 <entry>
   <title>Moving from Ruby to Python</title>
   <link href="http://feedproxy.google.com/~r/kanwei/~3/DdPNVci6Yg4/moving-to-python.html" />
   <updated>2009-04-01T00:00:00-04:00</updated>
   <id>http://kanwei.com/code/2009/04/01/moving-to-python</id>
   <content type="html">&lt;p&gt;I've been using Ruby ever since a good friend told me to jump on the Rails bandwagon when it was back in beta, around 2005. After having only programmed production code in PHP, Ruby was like, way hard, but I had to learn it because of peer pressure.&lt;/p&gt;

&lt;p&gt;4 years later, after struggling needlessly through coursework and projects using Ruby (where I could have been using Java instead), I'm finally ready to ditch the beast. I've lost coding competitions because of Ruby's speed. I've stared at code for seconds and not been able to figure it out. I even tried to implement &lt;a href="http://github.com/kanwei/algorithms/tree/master"&gt;data structures&lt;/a&gt; in Ruby, and ended up doing them in C. People make fun of me on a daily basis when I utter the famous last words: "Ruby's not that slow..."&lt;/p&gt;

&lt;p&gt;Anyways, it's 2009 and a good time as any to switch. I've been learning Haskell on the side, but it's not production ready. In my search for the ultimate Ruby replacement language, I stumbled on one called Python that seems to have some momentum going for it. I think some big companies are even using it in production! Anyways, here are some of the pros vs Ruby:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Whitespace matters. Having to "end" everything in Ruby really sucks, especially since my code is always correctly aligned.&lt;/li&gt;
&lt;li&gt;No ternary if. Seriously, I have to type this kind of crap in Ruby all the time:
    
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="n"&gt;v&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;empty?&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;shift&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kp"&gt;nil&lt;/span&gt;
&lt;/pre&gt;
&lt;/div&gt;

    In Python this would be:
    
&lt;div class="highlight"&gt;&lt;pre&gt;    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="nb"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mf"&gt;0&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="n"&gt;v&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mf"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
            &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mf"&gt;1&lt;/span&gt;&lt;span class="p"&gt;:]&lt;/span&gt;
    &lt;span class="k"&gt;else&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="n"&gt;v&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="bp"&gt;None&lt;/span&gt;
&lt;/pre&gt;
&lt;/div&gt;

    This is clearly less error-prone and more readable than Ruby's.
&lt;/li&gt;
&lt;li&gt;Better built-in methods. For example, you can simply do &lt;code&gt;sum([1,2,3])&lt;/code&gt; in Python, whereas you would have to do &lt;code&gt;[1,2,3].inject(0) { |sum, i| sum += i }&lt;/code&gt; in Ruby. Seriously????? Why is it called inject anyways. Ruby's authors were clearly not well at English.&lt;/li&gt;
&lt;li&gt;Faster. Because Python is so much simpler than Ruby, its VM is almost an order of magnitude faster to make up.&lt;/li&gt;
&lt;li&gt;More production ready. I read somewhere that Google is using Python.&lt;/li&gt;
&lt;li&gt;Better commenting. In Python you can do:
    
&lt;div class="highlight"&gt;&lt;pre&gt;    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;getTime&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
        &lt;span class="sd"&gt;&amp;#39;&amp;#39;&amp;#39;Returns a string timestamp in the form: &amp;#39;Time hh:mm:ss&amp;#39; &amp;#39;&amp;#39;&amp;#39;&lt;/span&gt;
            &lt;span class="o"&gt;...&lt;/span&gt;
&lt;/pre&gt;
&lt;/div&gt;

    but in Ruby you're stuck with
    
&lt;div class="highlight"&gt;&lt;pre&gt;    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;get_time&lt;/span&gt;
        &lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="k"&gt;begin&lt;/span&gt; &lt;span class="n"&gt;doc&lt;/span&gt;
            &lt;span class="no"&gt;Returns&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="n"&gt;string&lt;/span&gt; &lt;span class="n"&gt;timestamp&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="n"&gt;the&lt;/span&gt; &lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;Time hh:mm:ss&amp;#39;&lt;/span&gt;
        &lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="k"&gt;end&lt;/span&gt;
        &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;.&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;
&lt;/pre&gt;
&lt;/div&gt;

    Look at how much space we're saving with Python. LOC matters, people.&lt;/li&gt;
&lt;/ul&gt;   


&lt;p&gt;These are just some of the reasons that I'm moving over. Look forward to code samples and solutions in Python from me in the future!&lt;/p&gt;
&lt;img src="http://feeds.feedburner.com/~r/kanwei/~4/DdPNVci6Yg4" height="1" width="1"/&gt;</content>
 <feedburner:origLink>http://kanwei.com/code/2009/04/01/moving-to-python.html</feedburner:origLink></entry>
 
 <entry>
   <title>Fixing git commit emails using git filter-branch</title>
   <link href="http://feedproxy.google.com/~r/kanwei/~3/pirCs_nHd-k/fixing-git-email.html" />
   <updated>2009-03-29T00:00:00-04:00</updated>
   <id>http://kanwei.com/code/2009/03/29/fixing-git-email</id>
   <content type="html">&lt;p&gt;When I created the git repository for my &lt;a href="http://github.com/kanwei/algorithms/tree/master"&gt;Ruby algorithms library&lt;/a&gt;, I was a git noob and didn't properly set up my email in my .gitconfig. While this is fine, it makes it so that your activity graphs on Github don't reflect the period where you didn't set your email, since that's how Github rolls. Anyways, I ran the following script, then did a &lt;code&gt;git push -f&lt;/code&gt; to do a force push to Github or any other remote repository.&lt;/p&gt;

&lt;p&gt;If you don't force it, you will get &lt;code&gt; ! [rejected]        master -&gt; master (non-fast forward)&lt;/code&gt;, since you're updating past history.&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="c"&gt;#!/bin/sh&lt;/span&gt;

git filter-branch --env-filter &lt;span class="s1"&gt;&amp;#39;&lt;/span&gt;

&lt;span class="s1"&gt;an=&amp;quot;$GIT_AUTHOR_NAME&amp;quot;&lt;/span&gt;
&lt;span class="s1"&gt;am=&amp;quot;$GIT_AUTHOR_EMAIL&amp;quot;&lt;/span&gt;
&lt;span class="s1"&gt;cn=&amp;quot;$GIT_COMMITTER_NAME&amp;quot;&lt;/span&gt;
&lt;span class="s1"&gt;cm=&amp;quot;$GIT_COMMITTER_EMAIL&amp;quot;&lt;/span&gt;
&lt;span class="s1"&gt; &lt;/span&gt;
&lt;span class="s1"&gt;if [ &amp;quot;$GIT_COMMITTER_NAME&amp;quot; = &amp;quot;Kanwei Li&amp;quot; ]&lt;/span&gt;
&lt;span class="s1"&gt;then&lt;/span&gt;
&lt;span class="s1"&gt;cm=&amp;quot;kanwei@gmail.com&amp;quot;&lt;/span&gt;
&lt;span class="s1"&gt;fi&lt;/span&gt;
&lt;span class="s1"&gt;if [ &amp;quot;$GIT_AUTHOR_NAME&amp;quot; = &amp;quot;Kanwei Li&amp;quot; ]&lt;/span&gt;
&lt;span class="s1"&gt;then&lt;/span&gt;
&lt;span class="s1"&gt;am=&amp;quot;kanwei@gmail.com&amp;quot;&lt;/span&gt;
&lt;span class="s1"&gt;fi&lt;/span&gt;

&lt;span class="s1"&gt;export GIT_AUTHOR_EMAIL=$am&lt;/span&gt;
&lt;span class="s1"&gt;export GIT_COMMITTER_EMAIL=$cm&lt;/span&gt;
&lt;span class="s1"&gt;&amp;#39;&lt;/span&gt;
&lt;/pre&gt;
&lt;/div&gt;

&lt;img src="http://feeds.feedburner.com/~r/kanwei/~4/pirCs_nHd-k" height="1" width="1"/&gt;</content>
 <feedburner:origLink>http://kanwei.com/code/2009/03/29/fixing-git-email.html</feedburner:origLink></entry>
 
 <entry>
   <title>Facebook Jobs Puzzle&amp;mdash;peaktraffic</title>
   <link href="http://feedproxy.google.com/~r/kanwei/~3/9XU2D4uRd84/facebook-peaktraffic.html" />
   <updated>2009-03-26T00:00:00-04:00</updated>
   <id>http://kanwei.com/code/2009/03/26/facebook-peaktraffic</id>
   <content type="html">&lt;p&gt;From &lt;a href="http://www.facebook.com/jobs_puzzles/index.php"&gt;Facebook's Job Puzzles page&lt;/a&gt;:&lt;/p&gt;

&lt;p&gt;Cliques are sets of vertices in a graph that are complete, meaning there is an edge between every pair of the vertices in the clique. This Facebook puzzle is to find maximal cliques in presumably a large but sparse data set, since the problem is NP-complete (worst-case is when the graph is dense).&lt;/p&gt;

&lt;p&gt;I will come back and cover this in broader detail at a later time.&lt;/p&gt;

&lt;p&gt;The following solution in Ruby passed the Facebook puzzle robot:&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="c1"&gt;#!/usr/bin/env ruby&lt;/span&gt;
&lt;span class="c1"&gt;# VROOM&lt;/span&gt;
&lt;span class="c1"&gt;# Kanwei Li, 2009&lt;/span&gt;

&lt;span class="c1"&gt;# Make sure input file exists and read from it&lt;/span&gt;
&lt;span class="n"&gt;filename&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;ARGV&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;
&lt;span class="k"&gt;unless&lt;/span&gt; &lt;span class="n"&gt;filename&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="no"&gt;File&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;exist?&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;filename&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;error: must specify a valid input file&amp;quot;&lt;/span&gt;
  &lt;span class="nb"&gt;exit&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="n"&gt;input&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;File&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;filename&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="vg"&gt;$build_matrix&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
&lt;span class="vg"&gt;$adj_matrix&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;

&lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="n"&gt;line&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;input&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;gets&lt;/span&gt;
  &lt;span class="n"&gt;line&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;strip!&lt;/span&gt;
  &lt;span class="k"&gt;next&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;line&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;empty?&lt;/span&gt;

  &lt;span class="n"&gt;splitted&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;line&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;split&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="se"&gt;\t&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;splitted&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;
  &lt;span class="k"&gt;unless&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;
    &lt;span class="vg"&gt;$build_matrix&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;||=&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
    &lt;span class="vg"&gt;$build_matrix&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="o"&gt;][&lt;/span&gt;&lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kp"&gt;true&lt;/span&gt;
    
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="vg"&gt;$build_matrix&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="vg"&gt;$build_matrix&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="o"&gt;][&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;
      &lt;span class="vg"&gt;$adj_matrix&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;||=&lt;/span&gt; &lt;span class="o"&gt;[]&lt;/span&gt;
      &lt;span class="vg"&gt;$adj_matrix&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;
      &lt;span class="vg"&gt;$adj_matrix&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;||=&lt;/span&gt; &lt;span class="o"&gt;[]&lt;/span&gt;
      &lt;span class="vg"&gt;$adj_matrix&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="vg"&gt;$cliques&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;[]&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;print_cliques&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;set&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;neighbors&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;seen&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;neighbors&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;empty?&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;seen&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;empty?&lt;/span&gt;
    &lt;span class="vg"&gt;$cliques&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;set&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;sort&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;, &amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;set&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;size&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;
  &lt;span class="k"&gt;else&lt;/span&gt;
    &lt;span class="n"&gt;possible_pivots&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;neighbors&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;seen&lt;/span&gt;
    &lt;span class="n"&gt;pivot&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;possible_pivots&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;inject&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kp"&gt;nil&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;best&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;p&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
      &lt;span class="n"&gt;best&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;nil?&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="vg"&gt;$adj_matrix&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;p&lt;/span&gt;&lt;span class="o"&gt;].&lt;/span&gt;&lt;span class="n"&gt;size&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;best&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;size&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="n"&gt;best&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;p&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;best&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
    &lt;span class="n"&gt;neighbors&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;size&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;times&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
      &lt;span class="n"&gt;n&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;neighbors&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;
      &lt;span class="k"&gt;next&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="vg"&gt;$adj_matrix&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="o"&gt;].&lt;/span&gt;&lt;span class="n"&gt;include?&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pivot&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="n"&gt;neighbors&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kp"&gt;nil&lt;/span&gt;
      &lt;span class="n"&gt;print_cliques&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;set&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;neighbors&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;compact&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="vg"&gt;$adj_matrix&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;seen&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="vg"&gt;$adj_matrix&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="n"&gt;seen&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="n"&gt;print_cliques&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;[]&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="vg"&gt;$adj_matrix&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;keys&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;[]&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="vg"&gt;$cliques&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;sort&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;
&lt;/pre&gt;
&lt;/div&gt;

&lt;img src="http://feeds.feedburner.com/~r/kanwei/~4/9XU2D4uRd84" height="1" width="1"/&gt;</content>
 <feedburner:origLink>http://kanwei.com/code/2009/03/26/facebook-peaktraffic.html</feedburner:origLink></entry>
 
 <entry>
   <title>Facebook Jobs Puzzle&amp;mdash;usrbincrash Revisited</title>
   <link href="http://feedproxy.google.com/~r/kanwei/~3/o3uZWABTsNI/facebook-usrbincrash-revisited.html" />
   <updated>2009-03-22T00:00:00-04:00</updated>
   <id>http://kanwei.com/code/2009/03/22/facebook-usrbincrash-revisited</id>
   <content type="html">&lt;p&gt;This is a followup to my &lt;a href="/code/2009/02/17/facebook-usrbincrash.html"&gt;old solution.&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;So, I apparently have readers! Thank you for writing and contacting me on numerous occasions. I enjoy discussing and discovering algorithms, so keep them coming.&lt;/p&gt;

&lt;p&gt;Many of you have pointed out that my greedy solution doesn't work, and you're completely right. Here's an example I was sent:&lt;/p&gt;

&lt;pre&gt;
    1250
    LJS93K       1300       10500
    A            1200       6000
    J38ZZ9       700        4750
    B            550        3300
    HJ394L       200        3250
    O1IE82       75         10250

    Following your algorithm, it seems to instantly eliminate a necessary
    ingredient for the optimum solution, which to me is one J38ZZ9 and one "B", totaling $8050.
&lt;/pre&gt;


&lt;p&gt;For some reason, I couldn't figure out the recurrence relationship for dynamic programming by myself until one of you showed it to me. Thanks, now it's MINE!!!&lt;/p&gt;

&lt;p&gt;Anyways, I re-implemented it and like this one better, since it's optimal, although it does take O(nW) time instead of like, O(n) for my old one. I also implemented the easy GCD optimization and use a different pruning algorithm that works in all cases (while the old one deleted possible candidates, it worked with the greedy algorithm).&lt;/p&gt;

&lt;p&gt;The following solution in Ruby passed the Facebook puzzle robot:&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="c1"&gt;#!/usr/bin/ruby&lt;/span&gt;
&lt;span class="c1"&gt;# Usr Bin Crash puzzle&lt;/span&gt;
&lt;span class="c1"&gt;# Kanwei Li, 2009&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;gcd&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;
      &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;b&lt;/span&gt;
    &lt;span class="k"&gt;else&lt;/span&gt;
      &lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
  &lt;span class="n"&gt;a&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="c1"&gt;# Make sure input file exists and read from it&lt;/span&gt;
&lt;span class="n"&gt;filename&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;ARGV&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;
&lt;span class="k"&gt;unless&lt;/span&gt; &lt;span class="n"&gt;filename&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="no"&gt;File&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;exist?&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;filename&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;error: must specify a valid input file&amp;quot;&lt;/span&gt;
  &lt;span class="nb"&gt;exit&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="n"&gt;input&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;File&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;filename&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="vg"&gt;$items&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;[]&lt;/span&gt; &lt;span class="c1"&gt;# Store array of items as a global so we don&amp;#39;t have to pass it around&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;optimize&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;total_weight&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="n"&gt;table&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;[]&lt;/span&gt;
    
  &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;.&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;total_weight&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;each&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;cur_weight&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
    &lt;span class="n"&gt;best&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kp"&gt;nil&lt;/span&gt;
    &lt;span class="vg"&gt;$items&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;each_with_index&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;item&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
      &lt;span class="n"&gt;c&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;item&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;cost&lt;/span&gt;
      &lt;span class="n"&gt;item_weight&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;item&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;weight&lt;/span&gt;
      &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;item_weight&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;=&lt;/span&gt; &lt;span class="n"&gt;cur_weight&lt;/span&gt;
        &lt;span class="n"&gt;c&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="n"&gt;table&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;cur_weight&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;item_weight&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;
      &lt;span class="k"&gt;end&lt;/span&gt;
      &lt;span class="n"&gt;best&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;best&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;nil?&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;best&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
    &lt;span class="n"&gt;table&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;cur_weight&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;best&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
  
  &lt;span class="n"&gt;table&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;total_weight&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="n"&gt;total_weight&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;input&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;gets&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;to_i&lt;/span&gt;

&lt;span class="c1"&gt;# Populate items array&lt;/span&gt;
&lt;span class="no"&gt;Item&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Struct&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:weight&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:cost&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="n"&gt;line&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;input&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;gets&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
  &lt;span class="k"&gt;break&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;line&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;empty?&lt;/span&gt;
  &lt;span class="n"&gt;item&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;weight&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;cost&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;line&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;split&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sr"&gt;/\s+/&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="vg"&gt;$items&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="no"&gt;Item&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;weight&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;to_i&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;cost&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;to_i&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="c1"&gt;# $items.sort! { |a, b| b.weight &amp;lt;=&amp;gt; a.weight }&lt;/span&gt;
&lt;span class="vg"&gt;$items&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;each&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
  &lt;span class="vg"&gt;$items&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;delete_if&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;weight&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;weight&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;weight&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;to_f&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;weight&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;cost&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;cost&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="n"&gt;overall_gcd&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;gcd&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="vg"&gt;$items&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;].&lt;/span&gt;&lt;span class="n"&gt;weight&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;total_weight&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;.&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="vg"&gt;$items&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;size&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;each&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;overall_gcd&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;gcd&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;overall_gcd&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="vg"&gt;$items&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;].&lt;/span&gt;&lt;span class="n"&gt;weight&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="vg"&gt;$items&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;each&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;weight&lt;/span&gt; &lt;span class="o"&gt;/=&lt;/span&gt; &lt;span class="n"&gt;overall_gcd&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="n"&gt;total_weight&lt;/span&gt; &lt;span class="o"&gt;/=&lt;/span&gt; &lt;span class="n"&gt;overall_gcd&lt;/span&gt;

&lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;optimize&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;total_weight&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;
&lt;/pre&gt;
&lt;/div&gt;

&lt;img src="http://feeds.feedburner.com/~r/kanwei/~4/o3uZWABTsNI" height="1" width="1"/&gt;</content>
 <feedburner:origLink>http://kanwei.com/code/2009/03/22/facebook-usrbincrash-revisited.html</feedburner:origLink></entry>
 
 <entry>
   <title>Facebook Jobs Puzzle&amp;mdash;swarm solution in Ruby</title>
   <link href="http://feedproxy.google.com/~r/kanwei/~3/tpP8hyv-lzE/facebook-swarm.html" />
   <updated>2009-03-21T00:00:00-04:00</updated>
   <id>http://kanwei.com/code/2009/03/21/facebook-swarm</id>
   <content type="html">&lt;p&gt;From &lt;a href="http://www.facebook.com/jobs_puzzles/index.php"&gt;Facebook's Job Puzzles page&lt;/a&gt;:&lt;/p&gt;

&lt;blockquote&gt;&lt;p&gt;You are the Zerg Queen in command of the 654195331th legion of Zerg forces, the only side worth playing in StarCraft. The wise Overmind has given you the important task of cleaning up some remote planets for mineral mining operations. Apparently, some pesky Terran forces have decided to set up base defenses in these locations, prior to your arrival. With your limited forces, you must determine which Terran bases to attack. Your Zerg forces on each planet have free movement over that one planet, and may split up to attack any number of Terran bases on that planet. However, your Zerg ground forces have not yet evolved space flight and thus cannot travel from planet to planet to assist each other.&lt;/p&gt;

&lt;p&gt;Odds of victory over a particular Terran base are equal to: &lt;code&gt;P(z,s) = e^(-63s+10)/(e^(-63s+10)+e^(-21z))&lt;/code&gt;... etc&lt;/p&gt;&lt;/blockquote&gt;

&lt;p&gt;This problem is hard. On the surface, it seems like an optimization problem of two variables: minerals vs zerg, and then on top of that, deciding on which bases to attack. The equation above may look daunting, but with some pretty basic pre-calc, can be simplified. Look at the comments in my solution for the steps I took.&lt;/p&gt;

&lt;p&gt;The first problem is deciding whether a base is worth attacking, and how many zerg are needed. That's not the end of the story, as you can actually attack each base with different amounts of zerg to get different amounts of minerals. It's a cluster..bleep. Thank goodness for the exp(), as it drastically limits the possible amount of forces to use for each base. I had to use a trick to make it work for large minerals. Can you spot it and figure out why it works?&lt;/p&gt;

&lt;p&gt;After that, it's just another 0-1 knapsack problem to solve, with thankfully only a very few amount of possibilities to consider.&lt;/p&gt;

&lt;p&gt;For testing, I used forum David's test generator to make &lt;a href="/code/swarm.txt"&gt;this file (4MB)&lt;/a&gt;.&lt;/p&gt;

&lt;pre&gt;
    time ./swarm swarm.txt &amp;gt; out

    real    0m21.126s
    user    0m20.167s
    sys 0m0.107s

    MD5 (out) = 14fc14d34d05d485e1e261a86dd5a499
&lt;/pre&gt;


&lt;p&gt;The following solution in Ruby passed the Facebook puzzle robot:&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="c1"&gt;#!/usr/bin/ruby&lt;/span&gt;
&lt;span class="c1"&gt;# ZERGRUSH&lt;/span&gt;
&lt;span class="c1"&gt;# Kanwei Li, 2009&lt;/span&gt;
&lt;span class="c1"&gt;#&lt;/span&gt;
&lt;span class="c1"&gt;# e^(-63s+10)/(e^(-63s+10)+e^(-21z)) * m &amp;gt;= 1&lt;/span&gt;
&lt;span class="c1"&gt;# m * e^(-63s+10) &amp;gt;= e^(-63s+10) + e^(-21z)&lt;/span&gt;
&lt;span class="c1"&gt;# m * e^(-63s+10) - e^(-63s+10) &amp;gt;= e^(-21z)&lt;/span&gt;
&lt;span class="c1"&gt;# e^(-63s+10) (m-1) &amp;gt;= e^(-21z)&lt;/span&gt;
&lt;span class="c1"&gt;# ln(m-1) + (-63s+10) &amp;gt;= -21z&lt;/span&gt;

&lt;span class="c1"&gt;# e^(-63s+10)/(e^(-63s+10)+e^(-21z)) * m = g&lt;/span&gt;
&lt;span class="c1"&gt;# m * e^(-63s+10) = g(e^(-63s+10) + e^(-21z))&lt;/span&gt;
&lt;span class="c1"&gt;# m * e^(-63s+10) - g*e^(-63s+10) = g*e^(-21z)&lt;/span&gt;
&lt;span class="c1"&gt;# e^(-63s+10) (m-g) = g*e^(-21z)&lt;/span&gt;
&lt;span class="c1"&gt;# ln(m-g) + (-63s+10) = ln(g) - 21z&lt;/span&gt;
&lt;span class="c1"&gt;# ln(g) - ln(m-g) = -63s + 10 + 21z&lt;/span&gt;
&lt;span class="c1"&gt;# g/(m-g) = e^(-63s + 10 + 21z)&lt;/span&gt;
&lt;span class="c1"&gt;# let cc = e^(-63s + 10 + 21z)&lt;/span&gt;
&lt;span class="c1"&gt;# g = (m-g) * cc&lt;/span&gt;
&lt;span class="c1"&gt;# g + g*cc = m*cc&lt;/span&gt;
&lt;span class="c1"&gt;# g(1 + cc) = m*cc&lt;/span&gt;
&lt;span class="c1"&gt;# g = m*cc/(1 + cc)&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;optimize&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ary&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;total&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="o"&gt;[]&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;ary&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;empty?&lt;/span&gt;
  &lt;span class="n"&gt;table&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;[]&lt;/span&gt;
  &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ary&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;size&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;times&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;table&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;[]&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;.total&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;each&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;zerg&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;table&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;][&lt;/span&gt;&lt;span class="n"&gt;zerg&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;.ary&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;size&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;each&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;base&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
    &lt;span class="n"&gt;table&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;base&lt;/span&gt;&lt;span class="o"&gt;][&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;.total&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;each&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;zerg&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
      &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;ary&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;base&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;].&lt;/span&gt;&lt;span class="n"&gt;zerg&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;=&lt;/span&gt; &lt;span class="n"&gt;zerg&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ary&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;base&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;].&lt;/span&gt;&lt;span class="n"&gt;minerals&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;table&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;base&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;][&lt;/span&gt;&lt;span class="n"&gt;zerg&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;ary&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;base&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;].&lt;/span&gt;&lt;span class="n"&gt;zerg&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;table&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;base&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;][&lt;/span&gt;&lt;span class="n"&gt;zerg&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;table&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;base&lt;/span&gt;&lt;span class="o"&gt;][&lt;/span&gt;&lt;span class="n"&gt;zerg&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;ary&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;base&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;].&lt;/span&gt;&lt;span class="n"&gt;minerals&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;table&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;base&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;][&lt;/span&gt;&lt;span class="n"&gt;zerg&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;ary&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;base&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;][&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;]]&lt;/span&gt;
      &lt;span class="k"&gt;else&lt;/span&gt;
        &lt;span class="n"&gt;table&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;base&lt;/span&gt;&lt;span class="o"&gt;][&lt;/span&gt;&lt;span class="n"&gt;zerg&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;table&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;base&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;][&lt;/span&gt;&lt;span class="n"&gt;zerg&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;
      &lt;span class="k"&gt;end&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
  &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;[]&lt;/span&gt;
  &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;k&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;ary&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;size&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;total&lt;/span&gt;
  &lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;k&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;table&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;][&lt;/span&gt;&lt;span class="n"&gt;k&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="n"&gt;table&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;][&lt;/span&gt;&lt;span class="n"&gt;k&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;
      &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;ary&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;
      &lt;span class="n"&gt;k&lt;/span&gt; &lt;span class="o"&gt;-=&lt;/span&gt; &lt;span class="n"&gt;ary&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;].&lt;/span&gt;&lt;span class="n"&gt;zerg&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
    &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;-=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
  &lt;span class="n"&gt;result&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;cartesian_prod&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ary&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="n"&gt;ary&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;inject&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;[[]]&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;old&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;lst&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
    &lt;span class="kp"&gt;new&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;[]&lt;/span&gt;
    &lt;span class="n"&gt;lst&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;each&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="kp"&gt;new&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="n"&gt;old&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;map&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;dup&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt; &lt;span class="p"&gt;}}&lt;/span&gt;
    &lt;span class="kp"&gt;new&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;gain&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;minerals&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;terran&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;zerg&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="n"&gt;n&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;63&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;terran&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;21&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;zerg&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;minerals&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;
  &lt;span class="n"&gt;cc&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Math&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;exp&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;minerals&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;cc&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;cc&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;round&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;zerg_needed_for_feasible&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;minerals&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;terran&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="no"&gt;Math&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;minerals&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;63&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;terran&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;21&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ceil&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;feasible?&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;minerals&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;terran&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;zerg&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kp"&gt;false&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;minerals&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
  &lt;span class="no"&gt;Math&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;minerals&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;63&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;terran&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;21&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;zerg&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;to_f&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="c1"&gt;# Make sure input file exists and read from it&lt;/span&gt;
&lt;span class="n"&gt;filename&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;ARGV&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;
&lt;span class="k"&gt;unless&lt;/span&gt; &lt;span class="n"&gt;filename&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="no"&gt;File&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;exist?&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;filename&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;error: must specify a valid input file&amp;quot;&lt;/span&gt;
  &lt;span class="nb"&gt;exit&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="n"&gt;input&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;File&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;filename&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;num_planets&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;input&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;gets&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;to_i&lt;/span&gt;
&lt;span class="n"&gt;out&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;&amp;quot;&lt;/span&gt;

&lt;span class="no"&gt;Base&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Struct&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:index&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:zerg&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:minerals&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;num_planets&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;times&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
  &lt;span class="n"&gt;bases&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;zerg&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;input&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;gets&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;split&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sr"&gt;/\s+/&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;collect&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;to_i&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="n"&gt;feasible&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;[]&lt;/span&gt;
  &lt;span class="n"&gt;bases&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;times&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
    &lt;span class="n"&gt;terran&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;minerals&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;input&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;gets&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;split&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sr"&gt;/\s+/&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;collect&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;to_i&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;feasible?&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;minerals&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;terran&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;zerg&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="n"&gt;zerg_needed&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;zerg_needed_for_feasible&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;minerals&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;terran&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="n"&gt;last_gain&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kp"&gt;nil&lt;/span&gt;
      &lt;span class="n"&gt;base_ary&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;[]&lt;/span&gt;
      &lt;span class="kp"&gt;loop&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
        &lt;span class="n"&gt;g&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;gain&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;minerals&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;terran&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;zerg_needed&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;break&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;last_gain&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;last_gain&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;g&lt;/span&gt;
        &lt;span class="n"&gt;base_ary&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="no"&gt;Base&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;zerg_needed&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;g&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;last_gain&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;g&lt;/span&gt;
        &lt;span class="n"&gt;zerg_needed&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
      &lt;span class="k"&gt;end&lt;/span&gt;
      &lt;span class="n"&gt;feasible&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;base_ary&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
  &lt;span class="n"&gt;candidates&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;cartesian_prod&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;feasible&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  
  &lt;span class="n"&gt;best_zerg&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;best_minerals&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;best_ary&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kp"&gt;nil&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kp"&gt;nil&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kp"&gt;nil&lt;/span&gt;
  &lt;span class="n"&gt;candidates&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;each&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;cand&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
    &lt;span class="n"&gt;cand&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;cand&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;sort_by&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;zerg&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;minerals&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="n"&gt;cand_ary&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;optimize&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;cand&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;zerg&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;cand_ary&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;sort!&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;index&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;index&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="n"&gt;total_zerg&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;cand_ary&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;inject&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;sum&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;sum&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;zerg&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="n"&gt;total_minerals&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;cand_ary&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;inject&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;sum&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;sum&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;minerals&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;best_minerals&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;nil?&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;total_minerals&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="n"&gt;best_minerals&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="n"&gt;best_zerg&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;best_minerals&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;total_zerg&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;total_minerals&lt;/span&gt;
      &lt;span class="n"&gt;best_ary&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;cand_ary&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
  &lt;span class="n"&gt;out&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;best_zerg&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; &lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;best_minerals&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;
  &lt;span class="n"&gt;out&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;best_ary&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;inject&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;[]&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;ary&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;base&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;ary&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;base&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;index&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;base&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;zerg&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39; &amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="n"&gt;out&lt;/span&gt;
&lt;/pre&gt;
&lt;/div&gt;

&lt;img src="http://feeds.feedburner.com/~r/kanwei/~4/tpP8hyv-lzE" height="1" width="1"/&gt;</content>
 <feedburner:origLink>http://kanwei.com/code/2009/03/21/facebook-swarm.html</feedburner:origLink></entry>
 
 <entry>
   <title>Insertion sort in Motorola 68000 assembly</title>
   <link href="http://feedproxy.google.com/~r/kanwei/~3/GroIH7cDeuA/insertion-sort-assembly.html" />
   <updated>2009-02-18T00:00:00-05:00</updated>
   <id>http://kanwei.com/code/2009/02/18/insertion-sort-assembly</id>
   <content type="html">&lt;p&gt;I had to manually compile an insertion algorithm from C to Motorola 68K assembly for class. The * symbol denotes a comment in assembly. I  kept the C code as comments and wrote the corresponding assembly beneath.&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;* Compiled by Kanwei Li - 11/29/05

* isort - insertion sort

* This program uses the insertionsort algorithm to sort an array 
* of structures containing integer, character and short fields. 
* The integer field of each structure is the primary sort key. 
* Array elements with equal integer keys are further sorted by 
* the character field. The short field is not used for sorting.

* CS255 Assembly Language
* Emory Math/CS

    xdef    start, end
    xdef    for_start, for_exit, while_start, while_exit, while_pass
    xdef    i, j, v, a

*#define N 7
N:      equ 7

********************
* TYPE DEFINITIONS *
********************

mys_i_off:  equ 0
mys_c_off:  equ 4
mys_s_off:  equ 6
mys_size:   equ 8

*struct mystruct {
*   int i;
*   char c;
*   short s;
*};

********
* CODE *
********

*void main()
*

start:
    
    move.l  #1, i

for_start:
    nop        * nop after non-breakpoint labels as a temporary fix
    
*   for (i=1; i&amp;lt;N; i++) = while(i&amp;lt;N) {
    move.l  i, d0
    cmp.l   #N, d0
    bge     for_exit
    
*       v = a[i];
    lea     a, a0
    muls.w  #mys_size, d0
    adda.l  d0, a0
    move.l  a0, v

*       We store v in registers to prevent clobbering
    move.l  (mys_i_off, a0), d3 * d3 = v.i
    move.b  (mys_c_off, a0), d4 * d4 = v.c
    move.w  (mys_s_off, a0), d5 * d5 = v.s

    
*       j = i-1;
    move.l  i, d0
    sub.l   #1, d0
    move.l  d0, j

while_start:
    nop
    
*       while (a &amp;amp;&amp;amp; (b || (c &amp;amp;&amp;amp; d)))
*       while ((j &amp;gt;= 0) 
    move.l  j, d0
    cmp.l   #0, d0
    blt     while_exit 

*               &amp;amp;&amp;amp; ((a[j].i &amp;gt; v.i) 
    lea     a, a0
    move.l  j, d1   *d1 = j offset
    muls.w  #mys_size, d1
    move.l  (mys_i_off, a0, d1.l), d0
    cmp.l   d3, d0              * d3 = v.i
    bgt     while_pass
    
*                   || ((a[j].i == v.i)
    bne     while_exit

*                       &amp;amp;&amp;amp; (a[j].c &amp;gt; v.c)))) {
    move.b  (mys_c_off, a0, d1.l), d0
    cmp.b   d4, d0              * d4 = v.c
    ble     while_exit

while_pass:
    nop
    
*           a[j+1] = a[j];
    lea     a, a0
    move.l  j, d1   *d1 = j offset
    muls.w  #mys_size, d1
    
    move.l  d1, d2  *d2 = j+1
    add.l   #mys_size, d2

    move.l  (mys_i_off, a0, d1.l), d0
    move.l  d0, (mys_i_off, a0, d2.l)
    
    move.b  (mys_c_off, a0, d1.l), d0
    move.b  d0, (mys_c_off, a0, d2.l)
    
    
    move.w  (mys_s_off, a0, d1.l), d0
    move.w  d0, (mys_s_off, a0, d2.l)
    
    
*           j--;
    move.l  j, d0
    sub.l   #1, d0
    move.l  d0, j
    bra     while_start

*       }
while_exit:
    nop

*       a[j+1] = v;


    lea     a, a0
    move.l  j, d1
    muls.w  #mys_size, d1
    add.l   #mys_size, d1
    
    move.l  d3, (mys_i_off, a0, d1.l)
    move.b  d4, (mys_c_off, a0, d1.l)
    move.w  d5, (mys_s_off, a0, d1.l)

* i++
    move.l  i, d0
    add.l   #1, d0
    move.l  d0, i
    bra     for_start
    
*   }

for_exit:

end:
    nop
    nop
    
    org $4000
    
***************
* GLOBAL DATA *
***************

*struct mystruct a[N] = {
*   {100, &amp;#39;Z&amp;#39;, 19},
*   {12, &amp;#39;Z&amp;#39;, 7},
*   {12, &amp;#39;Y&amp;#39;, 201},
*   {-7, &amp;#39;A&amp;#39;, 101},
*   {12, &amp;#39;L&amp;#39;, -7},
*   {12, &amp;#39;M&amp;#39;, 20},
*   {87, &amp;#39;X&amp;#39;, -87}
*};
    
a:
    dc.l    100
    dc.w    &amp;#39;Z&amp;#39;
    dc.w    19
    
    dc.l    12
    dc.w    &amp;#39;Z&amp;#39;
    dc.w    7
    
    dc.l    12
    dc.w    &amp;#39;Y&amp;#39;
    dc.w    201
    
    dc.l    -7
    dc.w    &amp;#39;A&amp;#39;
    dc.w    101
    
    dc.l    12
    dc.w    &amp;#39;L&amp;#39;
    dc.w    -7
    
    dc.l    12
    dc.w    &amp;#39;M&amp;#39;
    dc.w    20
    
    dc.l    87
    dc.w    &amp;#39;X&amp;#39;
    dc.w    -87
    
    
*struct mystruct v;
v:  ds.l    2

*int i, j;
i:  ds.l    1
j:  ds.l    1


    end

* This is the expected output.
* i=-7 c=&amp;#39;A&amp;#39; s=101  1090519141
* i=12 c=&amp;#39;L&amp;#39; s=-7   1275133945
* i=12 c=&amp;#39;M&amp;#39; s=20   1291845652
* i=12 c=&amp;#39;Y&amp;#39; s=201  1493172425
* i=12 c=&amp;#39;Z&amp;#39; s=7    1509949447
* i=87 c=&amp;#39;X&amp;#39; s=-87  1476460457
* i=100 c=&amp;#39;Z&amp;#39; s=19  1509949459
&lt;/pre&gt;
&lt;/div&gt;

&lt;img src="http://feeds.feedburner.com/~r/kanwei/~4/GroIH7cDeuA" height="1" width="1"/&gt;</content>
 <feedburner:origLink>http://kanwei.com/code/2009/02/18/insertion-sort-assembly.html</feedburner:origLink></entry>
 
 <entry>
   <title>Facebook Jobs Puzzle&amp;mdash;smallworld solution in Ruby</title>
   <link href="http://feedproxy.google.com/~r/kanwei/~3/fy2507Ug38E/facebook-smallworld.html" />
   <updated>2009-02-18T00:00:00-05:00</updated>
   <id>http://kanwei.com/code/2009/02/18/facebook-smallworld</id>
   <content type="html">&lt;p&gt;From &lt;a href="http://www.facebook.com/jobs_puzzles/index.php"&gt;Facebook's Job Puzzles page&lt;/a&gt;:&lt;/p&gt;

&lt;blockquote&gt;&lt;p&gt;As a popular engineer, you know many people in your home city. While traveling around town, visiting your friends, you realize it would be really handy to have a program that tells you which of your friends are closest based upon which friend you are currently visiting.&lt;/p&gt;

&lt;p&gt;Being an engineer who is interested in writing software that is useful to everyone, you decide to write a general solution to your quandary. Each of your friends lives at a unique latitude and longitude. For the purposes of this program, the world is flat, and the latitude and longitude are for all intents and purposes Cartesian coordinates on a flat plane. For example, in our flat world, lat 45, long -179 is not as close to lat 45, long 179 when compared to lat 45, long 170.&lt;/p&gt;

&lt;p&gt;Write a program that takes a single argument on the command line. This argument must be a file name which contains the input data. Your program should output the nearest three other friends for each friend in the list. You are virtually a celebrity and your friend list can be astoundingly huge; your program must have a running time of faster than O(n^2) and be robust and resource efficient.&lt;/p&gt;&lt;/blockquote&gt;

&lt;p&gt;The naive algorithm is extremely simple but won't get you anywhere as Facebook will run your code on a huge dataset and an O(n^2) solution won't cut it. I did some research and concluded that the best solution would use a &lt;a href="http://en.wikipedia.org/wiki/Kd-tree"&gt;kd-tree&lt;/a&gt;. The time complexity with this data structure is O(n log n). Implementing it was not too hard, although most reference implementations I found did not support querying for more than one nearest neighbor (we need 3). I really liked the data structure, so I generalized it and plopped it into my &lt;a href="http://github.com/kanwei/algorithms/blob/91665f9bf35537b3e274d6d1618e6d2a227a2e7c/lib/containers/kd_tree.rb"&gt;Algorithms and Containers library&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;For testing, I used this &lt;a href="/code/smallworld.txt"&gt;randomly generated file with 10000 points&lt;/a&gt;. It took less than 5 seconds to solve.&lt;/p&gt;

&lt;p&gt;The following solution in Ruby passed the Facebook puzzle robot:&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="c1"&gt;#!/usr/bin/env ruby&lt;/span&gt;
&lt;span class="c1"&gt;# Small world puzzle&lt;/span&gt;
&lt;span class="c1"&gt;# Kanwei Li, 2009&lt;/span&gt;

&lt;span class="c1"&gt;# Make sure input file exists and read from it&lt;/span&gt;
&lt;span class="n"&gt;filename&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;ARGV&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;
&lt;span class="k"&gt;unless&lt;/span&gt; &lt;span class="n"&gt;filename&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="no"&gt;File&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;exist?&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;filename&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;error: must specify a valid input file&amp;quot;&lt;/span&gt;
  &lt;span class="nb"&gt;exit&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="n"&gt;input&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;File&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;filename&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="vg"&gt;$points&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;[]&lt;/span&gt; &lt;span class="c1"&gt;# Store array of points as a global so we don&amp;#39;t have to pass it around&lt;/span&gt;

&lt;span class="c1"&gt;# Populate points array&lt;/span&gt;
&lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="n"&gt;line&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;input&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;gets&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
  &lt;span class="k"&gt;break&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;line&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;empty?&lt;/span&gt;
  &lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;line&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;split&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sr"&gt;/\s+/&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="vg"&gt;$points&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;to_i&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;to_f&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;to_f&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="no"&gt;Node&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Struct&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:coords&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:left&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:right&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# Build a kd-tree&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;build_tree&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;points&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;depth&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;points&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;empty?&lt;/span&gt;
  
  &lt;span class="n"&gt;axis&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;depth&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
  
  &lt;span class="n"&gt;points&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;sort!&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;axis&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;axis&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="n"&gt;median&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;points&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;size&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;
  
  &lt;span class="n"&gt;node&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Node&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;points&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;median&lt;/span&gt;&lt;span class="o"&gt;][&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;points&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;median&lt;/span&gt;&lt;span class="o"&gt;][&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;.&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kp"&gt;nil&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kp"&gt;nil&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="n"&gt;node&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;left&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;build_tree&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;points&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;.&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;median&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;depth&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="n"&gt;node&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;right&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;build_tree&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;points&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;median&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;.&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;depth&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;node&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="c1"&gt;# Euclidian distanced, squared, between a node and target coords&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;distance2&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;node&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;target&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kp"&gt;nil&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;node&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;nil?&lt;/span&gt; &lt;span class="ow"&gt;or&lt;/span&gt; &lt;span class="n"&gt;target&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;nil?&lt;/span&gt;
  &lt;span class="n"&gt;c&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;node&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;coords&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;target&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="n"&gt;d&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;node&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;coords&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;target&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="n"&gt;c&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;d&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;d&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="c1"&gt;# Update array of nearest elements if necessary&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;check_nearest&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;nearest&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;node&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;target&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="n"&gt;d&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;distance2&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;node&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;target&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; 
  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;nearest&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;size&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="n"&gt;d&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;nearest&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;last&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;
    &lt;span class="n"&gt;nearest&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;pop&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;nearest&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;size&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;
    &lt;span class="n"&gt;nearest&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;d&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;node&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;
    &lt;span class="n"&gt;nearest&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;sort!&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
  &lt;span class="n"&gt;nearest&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="vg"&gt;$nearest&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;[]&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;nearest&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;node&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;target&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;depth&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="n"&gt;axis&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;depth&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;
  
  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;node&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;left&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;nil?&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;node&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;right&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;nil?&lt;/span&gt; &lt;span class="c1"&gt;# Leaf node&lt;/span&gt;
    &lt;span class="vg"&gt;$nearest&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;check_nearest&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="vg"&gt;$nearest&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;node&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;target&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
  
  &lt;span class="c1"&gt;# Go down the nearest split&lt;/span&gt;
  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;node&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;right&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;nil?&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;node&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;left&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;target&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;axis&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;=&lt;/span&gt; &lt;span class="n"&gt;node&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;coords&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;axis&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;nearer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;node&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;left&lt;/span&gt;
    &lt;span class="n"&gt;further&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;node&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;right&lt;/span&gt;
  &lt;span class="k"&gt;else&lt;/span&gt;
    &lt;span class="n"&gt;nearer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;node&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;right&lt;/span&gt;
    &lt;span class="n"&gt;further&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;node&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;left&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
  &lt;span class="n"&gt;nearest&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;nearer&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;target&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;depth&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  
  &lt;span class="c1"&gt;# See if we have to check other side&lt;/span&gt;
  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;further&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="vg"&gt;$nearest&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;size&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;target&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;axis&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;node&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;coords&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;axis&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="vg"&gt;$nearest&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;last&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;
      &lt;span class="n"&gt;nearest&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;further&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;target&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;depth&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
  
  &lt;span class="vg"&gt;$nearest&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;check_nearest&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="vg"&gt;$nearest&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;node&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;target&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="c1"&gt;# puts &amp;quot;end: #{node.id}\t#{distance2(node, target)}&amp;quot;&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="n"&gt;root&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;build_tree&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="vg"&gt;$points&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="vg"&gt;$points&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;sort&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;each&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;point&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
  &lt;span class="vg"&gt;$nearest&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;[]&lt;/span&gt;
  &lt;span class="n"&gt;nearest_3&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;nearest&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;root&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;point&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;.&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;point&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; &lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;nearest_3&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;.&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;].&lt;/span&gt;&lt;span class="n"&gt;collect&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;.join(&amp;#39;,&amp;#39;)}&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/pre&gt;
&lt;/div&gt;

&lt;img src="http://feeds.feedburner.com/~r/kanwei/~4/fy2507Ug38E" height="1" width="1"/&gt;</content>
 <feedburner:origLink>http://kanwei.com/code/2009/02/18/facebook-smallworld.html</feedburner:origLink></entry>
 
 <entry>
   <title>Facebook Jobs Puzzle&amp;mdash;usrbincrash solution in Ruby</title>
   <link href="http://feedproxy.google.com/~r/kanwei/~3/u3euAjoyeqM/facebook-usrbincrash.html" />
   <updated>2009-02-17T00:00:00-05:00</updated>
   <id>http://kanwei.com/code/2009/02/17/facebook-usrbincrash</id>
   <content type="html">&lt;p&gt;From &lt;a href="http://www.facebook.com/jobs_puzzles/index.php"&gt;Facebook's Job Puzzles page&lt;/a&gt;:&lt;/p&gt;

&lt;blockquote&gt;&lt;p&gt;You are on a cargo plane full of commercial goods when the pilot announces that the plane is short on fuel. Unless cargo is ejected from the plane, you will run out of fuel and crash. The pilot provides you with the number of pounds of weight that must be ejected from the plane. Fortunately, the manifest of the plane is both completely accurate, digitized, and you are a programmer of some repute. Unfortunately, your boss is going to be extremely unhappy, and wants you to exactly minimize the losses to the absolute minimum possible without crashing the plane. The manifest does not contain the exact quantities of every type of good, because you have so many on board. You may assume that you will not run out of any good in the course of saving the plane. You also realize this kind of program could be handy to others who find themselves in similar situations.&lt;/p&gt;

&lt;p&gt;Write a program that takes a single argument on the command line. This argument must be a file name, which contains the input data. The program should output to standard out the minimum losses your boss will incur from your ejection of goods (see below). Your program will be tested against several manifests of several crashing planes; each with different data. Additionally, your program must be fast, and give the correct answer.&lt;/p&gt;&lt;/blockquote&gt;

&lt;p&gt;This puzzle is interesting in that there are many ways to approach it. It's a modified Knapsack problem: we are trying
to go over a certain weight while minimizing the cost. There is no limit to how many times each object can be used, making the problem
easier in terms of complexity.&lt;/p&gt;

&lt;p&gt;I originally solved it very quickly using a naive recursive approach. While correct, it was very inefficient and would blow the stack
when any large weight was used as input, even if the problem was easy.&lt;/p&gt;

&lt;p&gt;My final solution used the following algorithm:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Sort objects by weight/cost, higher ratios (most efficient) first.&lt;/li&gt;
&lt;li&gt;Delete objects that will never be used, which are those that are less efficient and weigh more than a more efficient object.&lt;/li&gt;
&lt;li&gt;Keep using the most efficient object until you equal or go over the target weight. If you hit it spot on, return the cost.&lt;/li&gt;
&lt;li&gt;If you go over, subtract the weight and recursively repeat the step above with the next most efficient object to determine if less cost can be achieved.&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;The following solution in Ruby passed the Facebook puzzle robot:&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="c1"&gt;#!/usr/bin/env ruby&lt;/span&gt;
&lt;span class="c1"&gt;# Usr Bin Crash puzzle&lt;/span&gt;
&lt;span class="c1"&gt;# Kanwei Li, 2009&lt;/span&gt;

&lt;span class="c1"&gt;# From memoize gem&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;memoize&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;name&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
 &lt;span class="n"&gt;cache&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
 &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;class&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt;&lt;span class="nb"&gt;self&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nb"&gt;self&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;end&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;send&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:define_method&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;name&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|*&lt;/span&gt;&lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
   &lt;span class="n"&gt;cache&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;super&lt;/span&gt; &lt;span class="k"&gt;unless&lt;/span&gt; &lt;span class="n"&gt;cache&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;has_key?&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
   &lt;span class="n"&gt;cache&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;
 &lt;span class="k"&gt;end&lt;/span&gt;
 &lt;span class="n"&gt;cache&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="c1"&gt;# Make sure input file exists and read from it&lt;/span&gt;
&lt;span class="n"&gt;filename&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;ARGV&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;
&lt;span class="k"&gt;unless&lt;/span&gt; &lt;span class="n"&gt;filename&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="no"&gt;File&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;exist?&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;filename&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;error: must specify a valid input file&amp;quot;&lt;/span&gt;
  &lt;span class="nb"&gt;exit&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="n"&gt;input&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;File&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;filename&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="vg"&gt;$items&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;[]&lt;/span&gt; &lt;span class="c1"&gt;# Store array of items as a global so we don&amp;#39;t have to pass it around&lt;/span&gt;

&lt;span class="c1"&gt;# Recursive is clean but blows stack on large inputs!&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;optimize&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;weight&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;weight&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;

  &lt;span class="n"&gt;best&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kp"&gt;nil&lt;/span&gt;
  &lt;span class="vg"&gt;$items&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;each&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;item&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
    &lt;span class="n"&gt;c&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;optimize&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;weight&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;item&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;weight&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;item&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;cost&lt;/span&gt;
    &lt;span class="n"&gt;best&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;best&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;nil?&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;best&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
  &lt;span class="n"&gt;best&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="n"&gt;memoize&lt;/span&gt; &lt;span class="ss"&gt;:optimize&lt;/span&gt;

&lt;span class="c1"&gt;# Finally, something that works, somewhat ugly though =\&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;optimize3&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;weight&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;cost&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;items&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="vg"&gt;$items&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;cost&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;weight&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="n"&gt;items&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;empty?&lt;/span&gt;
  &lt;span class="c1"&gt;# puts &amp;quot;#{weight}\t#{cost}\t#{items.collect{|i| i.weight}.join(&amp;#39; &amp;#39;)}&amp;quot;&lt;/span&gt;
  &lt;span class="n"&gt;same_ratio&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;items&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;find_all&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ratio&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;items&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;].&lt;/span&gt;&lt;span class="n"&gt;ratio&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="n"&gt;global_best&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kp"&gt;nil&lt;/span&gt;
  &lt;span class="n"&gt;same_ratio&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;size&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;times&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;weight&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="n"&gt;items&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="o"&gt;].&lt;/span&gt;&lt;span class="n"&gt;weight&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;items&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="o"&gt;].&lt;/span&gt;&lt;span class="n"&gt;cost&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;weight&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="n"&gt;items&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="o"&gt;].&lt;/span&gt;&lt;span class="n"&gt;weight&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;cost&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
    
    &lt;span class="n"&gt;best&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="n"&gt;items&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="o"&gt;].&lt;/span&gt;&lt;span class="n"&gt;cost&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;weight&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="n"&gt;items&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="o"&gt;].&lt;/span&gt;&lt;span class="n"&gt;weight&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;cost&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kp"&gt;nil&lt;/span&gt;
    
    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;items&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;items&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="o"&gt;]]&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;each&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;item&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
      &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
        &lt;span class="n"&gt;c&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;optimize3&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;weight&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="n"&gt;items&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="o"&gt;].&lt;/span&gt;&lt;span class="n"&gt;weight&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;items&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="o"&gt;].&lt;/span&gt;&lt;span class="n"&gt;cost&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;weight&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="n"&gt;items&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="o"&gt;].&lt;/span&gt;&lt;span class="n"&gt;weight&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;cost&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;items&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;items&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="o"&gt;]]&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="k"&gt;else&lt;/span&gt;
        &lt;span class="n"&gt;c&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;optimize3&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;weight&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;items&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="o"&gt;].&lt;/span&gt;&lt;span class="n"&gt;weight&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;items&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="o"&gt;].&lt;/span&gt;&lt;span class="n"&gt;cost&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;cost&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;items&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="k"&gt;end&lt;/span&gt;
      &lt;span class="n"&gt;best&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;best&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;nil?&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;best&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
    &lt;span class="n"&gt;global_best&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;best&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;best&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;global_best&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;nil?&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="n"&gt;best&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;global_best&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
  &lt;span class="n"&gt;global_best&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="n"&gt;memoize&lt;/span&gt; &lt;span class="ss"&gt;:optimize3&lt;/span&gt;

&lt;span class="n"&gt;total_weight&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;input&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;gets&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;to_i&lt;/span&gt;

&lt;span class="c1"&gt;# Populate items array&lt;/span&gt;
&lt;span class="no"&gt;Item&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Struct&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:weight&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:cost&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:ratio&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="n"&gt;line&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;input&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;gets&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
  &lt;span class="k"&gt;break&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;line&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;empty?&lt;/span&gt;
  &lt;span class="n"&gt;item&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;weight&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;cost&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;line&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;split&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sr"&gt;/\s+/&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="vg"&gt;$items&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="no"&gt;Item&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;weight&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;to_i&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;cost&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;to_i&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;weight&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;to_f&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="n"&gt;cost&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;to_f&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="vg"&gt;$items&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="vg"&gt;$items&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;sort_by&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ratio&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;weight&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;reverse&lt;/span&gt; &lt;span class="c1"&gt;# Larger ratios first&lt;/span&gt;

&lt;span class="c1"&gt;# Some pruning of redundant items&lt;/span&gt;
&lt;span class="vg"&gt;$items&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;each&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
  &lt;span class="vg"&gt;$items&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;delete_if&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;weight&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;weight&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ratio&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ratio&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;optimize3&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;total_weight&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;
&lt;/pre&gt;
&lt;/div&gt;

&lt;img src="http://feeds.feedburner.com/~r/kanwei/~4/u3euAjoyeqM" height="1" width="1"/&gt;</content>
 <feedburner:origLink>http://kanwei.com/code/2009/02/17/facebook-usrbincrash.html</feedburner:origLink></entry>
 
 <entry>
   <title>New website (Finally!)</title>
   <link href="http://feedproxy.google.com/~r/kanwei/~3/WYE_Mp68Dlw/new-website.html" />
   <updated>2009-01-17T00:00:00-05:00</updated>
   <id>http://kanwei.com/2009/01/17/new-website</id>
   <content type="html">&lt;p&gt;After years of putting off completing this website due to a lack of satisfaction with blogging tools, I have finally found a solution that I'm happy with. Out with Wordpress, in with Jekyll.&lt;/p&gt;

&lt;p&gt;Content Management Systems and blogging engines are a pain if you're a programmer/web developer. With Wordpress, I was typing my posts inside a browser, which is pretty bad since you don't get the power of a real text editor, and also risk losing all your work if something happens to the browser window. I also had to upload pictures and documents using a wizard which created   folders all over the place without coherent structure.&lt;/p&gt;

&lt;p&gt;Another major problem is the constant security threats that can compromise your entire website if you're attacked. I think I was upgrading Wordpress about once a month, which is slightly ridiculous for something as simple as a blog.&lt;/p&gt;

&lt;p&gt;Anyways, I've now switched to a static content solution, where I write posts in my text editor and then compile everything to HTML that I then upload. No PHP, no security issues. Perfection!&lt;/p&gt;
&lt;img src="http://feeds.feedburner.com/~r/kanwei/~4/WYE_Mp68Dlw" height="1" width="1"/&gt;</content>
 <feedburner:origLink>http://kanwei.com/2009/01/17/new-website.html</feedburner:origLink></entry>
 
 <entry>
   <title>Dancing For a Beginning Lead</title>
   <link href="http://feedproxy.google.com/~r/kanwei/~3/FNHNT9ykjLI/dancing-beginning-lead.html" />
   <updated>2009-01-11T00:00:00-05:00</updated>
   <id>http://kanwei.com/2009/01/11/dancing-beginning-lead</id>
   <content type="html">&lt;p&gt;Being a lead is tough stuff. Dancing is like a team sport, except with different teammates every dance. Learning to build instant chemistry can be as hard as rocket science, especially for rocket scientists.&lt;/p&gt;

&lt;p&gt;Let's break down a typical swing dance. Leads have to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Find a dance partner&lt;/li&gt;
&lt;li&gt;Navigate the dance floor to find open space&lt;/li&gt;
&lt;li&gt;Find the beat of the music&lt;/li&gt;
&lt;li&gt;Figure out what kind of song this is (swing chorus, 12-bar blues, 16-bar blues)&lt;/li&gt;
&lt;li&gt;Continually think up of sequence of moves that fit the music&lt;/li&gt;
&lt;li&gt;Figure out when the breaks are coming and what to do&lt;/li&gt;
&lt;li&gt;Make sure partner isn't running into something&lt;/li&gt;
&lt;li&gt;Make sure no one is running into you&lt;/li&gt;
&lt;li&gt;Give room for partner to play in&lt;/li&gt;
&lt;li&gt;Execute the moves with grace, style, and precision&lt;/li&gt;
&lt;li&gt;Look like you know what you're doing&lt;/li&gt;
&lt;li&gt;Have fun (or fake it)&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;Whereas follows have to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Wait for a dance&lt;/li&gt;
&lt;li&gt;Follow&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;Ok, so this &lt;em&gt;might&lt;/em&gt; just be a little biased.&lt;/p&gt;

&lt;p&gt;Other subtle stuff includes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Getting a good connection with partner, even if you've never danced before&lt;/li&gt;
&lt;li&gt;Figuring out what level to dance at to match partner&lt;/li&gt;
&lt;li&gt;Compensating for your mistakes and her mistakes&lt;/li&gt;
&lt;li&gt;Adjusting to the partner's style&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;If we delve into the mechanics, it gets even more complicated. Tension, momentum, force, compression, dynamic equilibrium, torque, these are all things that good dancers must know. They might not know these terms in the mathematical or physical context, but they definitely know them on an intuitive level and use them to improve their dancing. They also have to listen to the music, and come up with appropriate moves.&lt;/p&gt;

&lt;p&gt;All of this is very complicated and really hard. I will believe in artificial intelligence the day that I see a robot spontaneously dancing to music with a partner. It's so hard that I would settle just to see a computer spit out a coherent sequence of moves given a streaming music file it's never analyzed before (letting the computer first learn swing music structure by letting it analyze other swing songs). If the day comes where I witness this, I will steal the machine and take credit for it.&lt;/p&gt;

&lt;p&gt;As if the complexity of dancing wasn't enough, leads usually bear most of the responsibility for a bad dance. This can create frustration and fear of failure, especially in the initial stages, preventing them from advancing their dancing careers. This is in contrast to solo sports or music instruments, where you can practice in your room by yourself before revealing your honed skills to the world. You actually have to dance with others to improve at dancing.&lt;/p&gt;

&lt;p&gt;All I can say is: keep encouraging beginner leads! Even the smallest compliment or encouragement makes a difference.&lt;/p&gt;
&lt;img src="http://feeds.feedburner.com/~r/kanwei/~4/FNHNT9ykjLI" height="1" width="1"/&gt;</content>
 <feedburner:origLink>http://kanwei.com/2009/01/11/dancing-beginning-lead.html</feedburner:origLink></entry>
 
 <entry>
   <title>Lindy Focus 2008 Review</title>
   <link href="http://feedproxy.google.com/~r/kanwei/~3/epEv8lDU-bk/lindy-focus-review.html" />
   <updated>2009-01-10T00:00:00-05:00</updated>
   <id>http://kanwei.com/2009/01/10/lindy-focus-review</id>
   <content type="html">&lt;p&gt;Well, I would like to tell myself that I originally signed up for Lindy
Focus because of my love for dancing, but this would be misleading. In
fact, the most appealing aspect when I signed up was getting to live
in a hotel room for a week. I love staying in hotels, as they provide
the comfort and feeling of taking a vacation without the actual
travelling.&lt;/p&gt;

&lt;p&gt;When the day came to leave, I got a phone call from Alex and got my
things ready in about 30 minutes. We picked up Cari on the way, and I
embarassed myself by making more bathroom stops than everyone else
combined.&lt;/p&gt;

&lt;p&gt;The instructors gave a demo that night, and you could instantly tell
they were the real deal. A quick look at their competition records
only formalizes how good they looked on the floor. I was getting
really pumped up to take classes from them.&lt;/p&gt;

&lt;p&gt;The next day, all the dancers were assigned groups based on their
dancing experience and level. Each group would take classes together
for the rest of the week.&lt;/p&gt;

&lt;p&gt;I personally thought the classes were good, since I managed to learn
something in every one of them. Some of the many aspects of swing
dancing that were covered included musicality, connection, styling,
new moves, old moves rediscovered, and different styles, like Balboa
and blues. There was something for everyone (except West Coast Swing).&lt;/p&gt;

&lt;p&gt;At night, the social dance floor provided plenty of opportunities to
practice what was learned during the day. People also just hung out,
and many friendships were formed. There were many demos and
competitions sprinkled in during the night, providing plenty of fuel
for inspiration.&lt;/p&gt;

&lt;p&gt;The event's environment was so engrossing that it would make the Emory
bubble jealous. Food lost most of its meaning except for its necessity
in facilitating more dancing. Seeing the sun rise at 6am was a gentle
hint that it might be good idea to head to bed. There were
velociraptor competitions. For a week, it was all about having fun.&lt;/p&gt;

&lt;p&gt;I would recommend the trip for everyone even remotely interested in
swing dancing. Good dancing is contagious and your dacing will improve
greatly. You will meet all sorts of interesting people, and you will
have plenty of memories to write about, like I am right now.&lt;/p&gt;

&lt;p&gt;The best moment of the whole trip happened on the day before we left
for home. We were supposed to check out at noon the next day, so we
had plenty of time for some late night dancing action. Matt asked me
what time my flight was, since he had offered to give me a ride, and I
said 2pm. The drive back to Atlanta would take more than 4 hours, and
it meant that we would have to wake up early. Matt didn't say
anything, but his face betrayed a look of shock and contempt. 10
seconds later, his expression unchanged and now staring a spot on the
wall right next to me, I realized that my physical safety was at risk,
so I finally revealed that I was actually leaving from Asheville
airport.&lt;/p&gt;
&lt;img src="http://feeds.feedburner.com/~r/kanwei/~4/epEv8lDU-bk" height="1" width="1"/&gt;</content>
 <feedburner:origLink>http://kanwei.com/2009/01/10/lindy-focus-review.html</feedburner:origLink></entry>
 
 <entry>
   <title>Lindy Focus 2008 Notes</title>
   <link href="http://feedproxy.google.com/~r/kanwei/~3/RZbMCOd-SNU/lindy-focus-notes.html" />
   <updated>2009-01-05T00:00:00-05:00</updated>
   <id>http://kanwei.com/2009/01/05/lindy-focus-notes</id>
   <content type="html">&lt;!-- Notes from my time at Lindy Focus VII --&gt;


&lt;h2&gt;Day 1: Arrival&lt;/h2&gt;

&lt;p&gt;Came up in the minivan with the girls... ended up singing "I'm a
barbie girl".&lt;/p&gt;

&lt;p&gt;Did some dancing that night and checked out Andrew Thigpen's solo
microphone dance.&lt;/p&gt;

&lt;h2&gt;Day 2: Administrative stuff&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Placement sessions:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;We did drills with Evita Arce and Nathan Bugh.. basically weeding out the
people who they didn't think should have been in level 2. It was
some pretty basic stuff like swingout to lindy-circle, swingout
with outside turn, swingout with inside turn... then they got
creative and made us do jumps and stuff that clearly none of us
were capable of doing. We then attempted to do some stuff that
the level 3's were doing, but quickly realized that we were still
in level 2.&lt;/p&gt;

&lt;p&gt;A couple people moved up and down but they were few in between.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Class: Nathan Bugh &amp;amp; Evita Arce&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;So apparently a pre-requisite of being a good dance instructor is
to be hilarious. I often wondered if Lindy Focus was an improv
comedy show with dancing as the theme, with some dance
instruction as a side bonus.&lt;/p&gt;

&lt;p&gt;Nathan Bugh and Evita Arce started off the show with stuff I can't
remember, except that it was funny. As for dancing, they
explained that you can do stuff that goes out of tempo and out of
sync with the music, and showed us one sequence which went:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Tuck turn&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Tuck turn, hold both hands and then let go of left hand so you
end up with lead's right holding follow's left, in a very open
stance&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Rock step follow, then gently pull and get out of the way as
follow turns and rolls neatly into your right arm&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Follow walks forward and lead rotates in place&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Find some space and stop so the follow turns out into open
position&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Finish with a darkside swingout/kick hold swingout&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;At least try to do the last parts in tempo with the music.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Blues Elective: Bill Borgida &amp;amp; Mike (the girl whose parents were clearly
confused) Legett&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;We did some travelling across the room in bluesy fashion (slow,
sad, with melanchony). Keep knees bent and lead with body so the
follow can feel it. Leave room in between for baby Jesus. I don't
think I'm old enough for these jokes.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Dance: Boilermaker Jazz Band (not Boilermakers)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The Boilermakers had an awesome bass player who would do his own
thing in between songs and even jammed on a Fender electric bass
when his double bass broke. You could tell he was having fun
because he looked high half the time.&lt;/p&gt;

&lt;h2&gt;Day 3: Getting into it&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Class: Dave Madison &amp;amp; Ursula Ledergerber&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Dave Madison made fun of Ursula Ledergerber for being Swiss, and managed to squeeze
in a lesson on sugar pushes in the process. They emphasized the
usage of the whole body to do the pushing instead of the
arms. When the follow comes in, absorb her momentum with equal
distribution in both hands. We did drills with sugar pushes
ending with a cross-hand tuck turn. T-Rex was king of the jungle
and a crappy dancer. Swinkle-Sweinkle (something hilariously
Swiss-German)&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Class: Andrew Sutton&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Musicality class where he played samples of different music and
we solo danced to them, adjusting to the mood. Feeling/looking
like an idiot was part of the process. He showed us that you can
pretty much dance any style to any music with adjustments: case
in point was him dancing Charleston to St. James Infirmary by
taking slow steps instead of the usual high-energy kick steps.&lt;/p&gt;

&lt;p&gt;Emphasized dancing to the music instead of dancing to the
moves. Looks better and you don't have to think as hard if you
let the music move you.&lt;/p&gt;

&lt;p&gt;We also went over the concept of the X, which is the amount of
force in the connection so that nothing happens. Since all
dancers seem to have scientific backgrounds, he could've just
called it the "force necessarily to maintain dynamic equilibrium"
instead of a mysterious letter. You can do your own solo thing as
long as you keep the X constant so your follow doesn't think
you're trying to go somewhere.&lt;/p&gt;

&lt;p&gt;Also talked about follows being able to lead parts of the dance,
especially for stylistic stuff.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Blues Elective: Dave Madison &amp;amp; Ursula Ledergerber&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;We did some pulsing and learned a basic Blues step, which
consists of shifting weight between left and right feet moving
your core in a diagonal line, pulsing the entire time.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Dance: Boilermakers again&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Feet start to hurt after 2am&lt;/p&gt;

&lt;h2&gt;Day 4: "We're halfway there" -Bon Jovi&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Class: Bobby White &amp;amp; Kate Hedin&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Tandem Charleston class. To get into tandem from closed:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Tuck turn (kick instead of triple step). Big arm motion on the
turn is an important signal&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Kick and move to the right, using your momentum to pull follow
into tandem position. Switch hands so that your right hand
catches follow's right hand (don't grab forearms), and then get
follow's left hand and rock step, followed by the usual
Charleston.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;One move you can do is to let go of left hand and push follow
away around 3 so that follow ends up facing you on 4, then bring
follow back into tandem by simply holding on, since you're going
backwards to finish the Charleston.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;Another move is to do push away on 3 again but kicking to the right so
that you end up in the cross handed Charleston mode. I tried it with
Bobby and he commented that you can really let the tension build in
the hands by twisting into the kicks. Also, kick down into the ground
instead of out.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Class: Marty Klempner &amp;amp; Kelly Arsenault&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Learned a new move to do between swingouts: basically sliding
your feet to the right, then to the left, ending with a "and two"
step, followed by a swingout. Keep leading it if your follow
doesn't catch on the first time because she will get it the
second time unless she's asleep or out to get you. Can try
tricking follow but this was not recommended for personal safety.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Pure Balboa Elective: Marty Klempner &amp;amp; Kelly Arsenault&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Learned the basic hold-step and step-hold. In the former, you do
1-2-hold-4 5-6-hold-8 and in the latter, you do 1-2- step -
hold (pulse in the ground) 5-6-step-hold&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Blues Elective: Dave Madison &amp;amp; Ursula Ledergerber&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Practiced moving around the room by taking bigger steps. Pre-empt
said steps by shifting body weight a little lower as a prompt.&lt;/p&gt;

&lt;p&gt;Went over the different kinds of connection you can have: Sleepy
kitten (pretty much nothing), regular, and ninja (a lot of
connection, useful for moving around a lot). Connection should
come from the body and not the shoulders, nor by sticking out
your bottom. I'm pretty sure Dave Madison is still laughing at how he
managed to turn "sleepy kitten" into dancing vocab now stuck in
people's heads.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Dance: Christabel and the Jons&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Great band from Tennessee. Bought their CD. Slower country feel
was a welcome break from the faster stuff by the
Boilermakers. Danced to songs about food, especially mashed
potatoes. Like dancing, you can sing about anything if you're
convicted enough.&lt;/p&gt;

&lt;h2&gt;Day 5: Feet really hurt&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Class: Emily Hoffberg &amp;amp; Juan Villafa�e&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Learned sailor walk/kicks:&lt;/p&gt;

&lt;p&gt;Start in open, two hand connection: rock step and bring follow
in with straight left arm and loose right arm so that you're
looking past follow's right shoulder, now rotate follow in place
so that you're back to back and use your left hand to keep the
connection. Now use kick steps to walk in a circle until you get
bored, in which case you can go back to open by extending your
left arm.&lt;/p&gt;

&lt;p&gt;Learned points with finger pointing:&lt;/p&gt;

&lt;p&gt;A personality move where after a swingout (or whatever really), you
point your left foot up, and then wag your finger at your partner as
if they killed a kitten. Can also drop the hand while looking
backward, then wagging again. Finish with "and step".&lt;/p&gt;

&lt;p&gt;Spent the next class working on basics, such as rock stepping
properly by gently pressing into the palm of follow's palm. Emily
emphasized that everything a follow does should be led and not
telegraphed or guessed.&lt;/p&gt;

&lt;p&gt;Worked on triple steps, which should be very clear (lead from
core instead of from shoulders). Also, the triple steps should be
uneven, with "one, and two" instead of an even "one two three".&lt;/p&gt;

&lt;p&gt;They also emphasized not calling the follow in until beat 2 on
swingouts, since you can build up more tension and make it more
springy. Can even rock step the follow, wait until 3, and still
swingout (practice required)&lt;/p&gt;

&lt;p&gt;Did some swingouts with Emily after class. She feels light and
responsive.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Bal-Swing Class: Bobby White and Kate Hedin&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Worked with the step-hold basic to add new moves. One of them was
the turnaround, where you turned in place by swiveling clockwise
on the step hold, going as far as you want, then finishing with
regular footwork.&lt;/p&gt;

&lt;p&gt;Also did lolly kicks where the lead rotates around the follow,
twisting hips and alternatively kicking outward and inward.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Blues Elective: Bill Borgida &amp;amp; Mike Legett&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;More work on the basic step, this time leading steps by squishing
a bug in the direction you want to go, then actually stepping
there.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Dance: Russ Wilson Swingtet&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Don't remember anything except Andrew Thigpen dancing Charleston
with someone's baby&lt;/p&gt;

&lt;h2&gt;Day 6: Last day (New Year's Eve)&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Class: Todd Yannacone &amp;amp; Kelly Arsenault&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Learned the Texas Tommy where you switch hands behind follow's
back from lead's left hand to right hand, trying not to break
follow in the process. Can finish the move by staying with the
cross-hand hold, or switching back to the left hand again (a lot
of work just to go back to the starting position!)&lt;/p&gt;

&lt;p&gt;This move can be used from closed (via tuck turn) or
open (through swingout).&lt;/p&gt;

&lt;p&gt;Also went into a Charleston position by doing a tuck turn Texas
Tommy so that follow ends up behind and to the left of the
lead. Can then do regular Charleston, in a staggered formation.&lt;/p&gt;

&lt;p&gt;Dinner: Went to Hibachi grill, ate stuff made by non-Japanese
chefs, still delicious&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Dance: Firecracker Jazz Band&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Toasted champagne to ring in the New Year&lt;/p&gt;

&lt;h2&gt;Things I learned:&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;You can dance with instructors!&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;You can win velociraptor competitions by pretending to be a
chicken&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Foot pain from dancing follows a bell curve&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Andrew Thigpen loves microphones, and microphones love Andrew Thigpen&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;UCF mass produces dancers&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;img src="http://feeds.feedburner.com/~r/kanwei/~4/RZbMCOd-SNU" height="1" width="1"/&gt;</content>
 <feedburner:origLink>http://kanwei.com/2009/01/05/lindy-focus-notes.html</feedburner:origLink></entry>
 
 <entry>
   <title>Why Dogfighting Isn't Just A Violent Hobby</title>
   <link href="http://feedproxy.google.com/~r/kanwei/~3/aEy3dE9ouJU/dogfighting.html" />
   <updated>2008-08-27T00:00:00-04:00</updated>
   <id>http://kanwei.com/2008/08/27/dogfighting</id>
   <content type="html">&lt;p&gt;When I first read the Michael Vick headlines on dogfighting, I really didn&amp;#8217;t know why it was such a big deal. I thought of it like cockfighting, which is legal and popular in many countries.&lt;/p&gt;
&lt;p&gt;Dogfighting is a felony in the United States. According to Wikipedia, it used to be legal back in the colonial days, but is now illegal due to its violent nature. It is interesting how much more pacifist society has become. Even bullfighting, practiced for centuries, is getting a bad rap in Europe.&lt;/p&gt;
&lt;p&gt;Is dogfighting really any different than other violent treatment of animals? We kill millions of animals everyday for food, fur, and fun. Big game hunting is legal and widely practiced. Animals kill each other without remorse.&lt;/p&gt;
&lt;p&gt;Could we be biased by our culture, where dogs are kept as pets and considered our best friends?&lt;/p&gt;
&lt;p&gt;I thought about this and realized that the difference is in intent. Bullfighting is as much a sign of respect for the bull as it is for the matador. Hunting is something that the human race has always done for survival, and recreational hunting can be seen as a tribute to that instinct. Animals kill each other instinctively for survival.&lt;/p&gt;
&lt;p&gt;Dogfighting is different. It involves breeding dogs for aggressive traits by abusing them and rewarding them for violence. They are no longer dogs, instead becoming fiendish tools through which gamblers and often insecure men attempt to prove their prowess.&lt;/p&gt;
&lt;p&gt;Related: &lt;a href="http://www.cnn.com/2007/US/law/08/27/deschanel.commentary/index.html"&gt;A &lt;span class="caps"&gt;CNN&lt;/span&gt; commentary on dogfighting&lt;/a&gt;.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/kanwei/~4/aEy3dE9ouJU" height="1" width="1"/&gt;</content>
 <feedburner:origLink>http://kanwei.com/2008/08/27/dogfighting.html</feedburner:origLink></entry>
 
 <entry>
   <title>Physical Activity</title>
   <link href="http://feedproxy.google.com/~r/kanwei/~3/NeN1Pi47e3U/physical-activity.html" />
   <updated>2008-04-30T00:00:00-04:00</updated>
   <id>http://kanwei.com/2008/04/30/physical-activity</id>
   <content type="html">&lt;p&gt;Once in a while, I can feel pretty down. Things that don&amp;#8217;t usually bother me, start bothering me. I don&amp;#8217;t get excited about working to become a billionaire anymore. I get second doubts about things I&amp;#8217;m confidant about. When it gets bad enough, I drop everything I&amp;#8217;m doing, put on some my sneakers (or Crocs!) and go for a run.&lt;/p&gt;
&lt;p&gt;I stopped regular physical activity after elementary school and paid the price in middle school and high school. Being super-flabby is by far the worst experience I&amp;#8217;ve had so far. No matter how good the other aspects of my life were, I was limited by my weight.&lt;/p&gt;
&lt;p&gt;For being a smart guy, it took me a pretty long time to figure out that being flabby isn&amp;#8217;t cool, and even longer to realize that I could do something about it. For my 17th birthday, I bought a first-generation iPod and made a commitment to a slimmer future. I loaded up some 80&amp;#8217;s music and went running.&lt;/p&gt;
&lt;p&gt;Looking back, it&amp;#8217;s pretty funny to think about how bad I was when I started running. Let&amp;#8217;s look at the route I ran:&lt;/p&gt;
&lt;p&gt;&lt;iframe src="http://www.dr2ooo.com/tools/maps/maps.php?zoom=16&amp;ll=42.351979,-71.246638&amp;" width="400" height="266"&gt;&lt;/iframe&gt;&lt;/p&gt;
&lt;p&gt;I ran the Freeman-Staniford-Lexington loop. It&amp;#8217;s exactly 0.7 miles per loop. When I started out, I could barely run half of one loop without stopping for air. Everyday, I would run 2 loops, a whopping 1.4 miles, in about half an hour! That&amp;#8217;s pretty slow.&lt;/p&gt;
&lt;p&gt;Luckily, your human body does not care how comically slow you&amp;#8217;re running. The weight started going away and I soon felt like a young Octavian, ready to take on the world. As other formerly flabby people will tell you, it felt great to be rid of the shackles around the belly, and did much for self-esteem.&lt;/p&gt;
&lt;p&gt;Scientists and parents will try to trick you into exercising by saying how good it is for you, how exercise releases epinephrine, which makes you feel good, etcetera. Getting a natural high is definitely a good reason to exercise. However, a better reason is so that you don&amp;#8217;t become flabby. Because being flabby sucks, just the fact that one is working on not becoming flabby should make anyone&amp;#8217;s day.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/kanwei/~4/NeN1Pi47e3U" height="1" width="1"/&gt;</content>
 <feedburner:origLink>http://kanwei.com/2008/04/30/physical-activity.html</feedburner:origLink></entry>
 
 <entry>
   <title>Accepted to the 2008 Google Summer of Code</title>
   <link href="http://feedproxy.google.com/~r/kanwei/~3/iREVZyoDW9g/accepted-to-google-summer-of-code.html" />
   <updated>2008-04-22T00:00:00-04:00</updated>
   <id>http://kanwei.com/2008/04/22/accepted-to-google-summer-of-code</id>
   <content type="html">&lt;p&gt;&lt;img src="/images/rubycentral.jpg" /&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Update: &lt;a href="http://github.com/kanwei/algorithms/tree/master"&gt;Project is now hosted on github&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;I got accepted to the 2008 Google Summer of Code program. It&amp;#8217;s a Google initiative to pay programmers to work on open source software projects. I&amp;#8217;ll be updating my blog more this summer.&lt;/p&gt;
&lt;p&gt;I will be writing a Ruby library to implement various algorithms and data structures so that they do not have to be re-implemented in other projects. My submitted proposal is as follows:&lt;/p&gt;
&lt;p&gt;Using the right data structure or algorithm for the situation is an important aspect of programming. In computer science literature, many data structures and algorithms have been researched and extensively documented. However, there is still no standard library in Ruby implementing useful structures and algorithms like Splay Trees, Red/Black Trees, tries, graphs, different sorting algorithms, etc. This project will create such a library with documentation on when to use a particular structure/algorithm. It will also come with a benchmark suite to compare performance in different situations.&lt;/p&gt;
&lt;p&gt;By leveraging the flexibility of Ruby’s duck typing, the structures and algorithms can be used on all classes of objects as long as a few methods are defined, much like the Enumerable mix-in. The library will be written in Ruby so that it can be used by all the different Ruby implementations, but will also be implemented in C and Java for performance.&lt;/p&gt;
&lt;p&gt;Possible data structures and algorithms:&lt;/p&gt;
&lt;ul&gt;
	&lt;li&gt;Trees (AVLTree, SplayTree, Red/Black Tree)&lt;/li&gt;
	&lt;li&gt;Heaps&lt;/li&gt;
	&lt;li&gt;Tries (Radix Tree, Suffix Tree)&lt;/li&gt;
	&lt;li&gt;Graphs (Adjacency List, Kruskal’s Algorithm, Djikstra’s Algorithm)&lt;/li&gt;
	&lt;li&gt;Sorting (Mergesort, Quicksort, Radix Sort, Insertion Sort)&lt;/li&gt;
	&lt;li&gt;Searching (Knuth-Morris-Pratt, Breadth-first tree search, depth-first tree search)&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Motivation:&lt;/h2&gt;
&lt;p&gt;To create a fast ruby library of common data structures and algorithms so that they do not have to be re-implemented for other projects.&lt;/p&gt;
&lt;h2&gt;Organization:&lt;/h2&gt;
&lt;ul&gt;
	&lt;li&gt;The data structures part of the library will be implemented as classes to be instantiated.&lt;/li&gt;
	&lt;li&gt;The sorting algorithms will be implemented as mix-ins, much like the Enumerable and Comparable libraries that require the user to define #each and #&amp;lt;=&amp;gt; respectively in order to get additional methods. The search methods could be added to built-in structures like arrays and strings, but this may cause conflicts with existing code and this must be considered.&lt;/li&gt;
	&lt;li&gt;Algorithms related to certain data structures, such as Graph searches, will be implemented for the appropriate structure.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Reference:&lt;/h2&gt;
&lt;p&gt;The primary literature referenced will be Robert Sedgewick&amp;#8217;s Algorithms (Parts 1 to 5), as it has both code examples and proofs for code complexity. I have used this book in many classes and it is a definitive resource for algorithms and data structures. For homework, I have implemented many of the structures and algorithms in Java, and have experience in writing benchmarks to test for different cases.&lt;/p&gt;
&lt;h2&gt;Implementation:&lt;/h2&gt;
&lt;p&gt;I plan to first write the entire library in Ruby and then implement it in C and Java for performance. Data structures and algorithms are low enough level that this is necessary. I have experience in both of the latter languages and should have no problem finishing over summer.&lt;/p&gt;
&lt;p&gt;A benchmark suite will be created in Ruby (probably using RSpec) to demonstrate the best, average, and worst case running times for each algorithm and structure.&lt;/p&gt;
&lt;h2&gt;Documentation:&lt;/h2&gt;
&lt;p&gt;A key aspect of the project will be to provide documentation with real-life code examples to demonstrate the usage of the algorithms and structures. For example, the documentation entry for &lt;span class="caps"&gt;LSD&lt;/span&gt; radix sort will say that it quickly sorts numbers and strings, and will list the Big O complexity to be linear. A benchmark comparing the results with that of the Enumerable#sort will be shown, and hopefully the radix sort will be faster as it is O(n) and not O(n log n).&lt;/p&gt;
&lt;p&gt;Explaining data structures will be trickier, as experience and theoretical background is needed to choose the right data structure for the problem. For example, many real world problems can be solved in terms of graphs. I will write up some realistic examples to demonstrate the use of trees, heaps and graphs, the main structures to be implemented. As with the algorithms, the documentation will provide benchmarks and Big O complexity.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/kanwei/~4/iREVZyoDW9g" height="1" width="1"/&gt;</content>
 <feedburner:origLink>http://kanwei.com/2008/04/22/accepted-to-google-summer-of-code.html</feedburner:origLink></entry>
 
 <entry>
   <title>Ralph Nader Speaks at Emory</title>
   <link href="http://feedproxy.google.com/~r/kanwei/~3/880PPfycH0Y/ralph-nader-at-emory.html" />
   <updated>2008-02-20T00:00:00-05:00</updated>
   <id>http://kanwei.com/2008/02/20/ralph-nader-at-emory</id>
   <content type="html">&lt;p&gt;&lt;img src="/images/nader.jpg" /&gt;&lt;/p&gt;
&lt;p&gt;Ralph Nader gave a fascinating talk at Emory tonight. He never mentioned his previous achievements, of which there are many, such as running for President four times (in 1992, 1996, 2000 and 2004) and writing the important book, &lt;em&gt;Unsafe at Any Speed&lt;/em&gt; that led to a revolution in car safety. Instead, he dove right into talking about personal freedom and consumer rights.&lt;/p&gt;
&lt;p&gt;Mr. Nader differentiated personal freedom from civic freedom. He explained that personal freedom included things like being able to freely marry, purchase goods, and other things on an individual level. These are liberties that exist in many dictatorships as well, not just democracies.&lt;/p&gt;
&lt;p&gt;Civic freedom is different. How many individuals in America feel like they can change monetary policy, or change the course of the Iraq War? How many people have recently used the courtroom? The fact is that most people feel powerless when dealing with things at a higher than personal level.&lt;/p&gt;
&lt;p&gt;He argued that while American universities offer classes in the arts and sciences, very few have a class on civics and how to be an effective citizen. He suggested that students petition their universities for a class in civics.&lt;/p&gt;
&lt;p&gt;The other major topic of his speech was on corporate fraud. Even in law school, corporate fraud is rarely talked about, and only after major scandals such as Enron have people started to pay attention. Corporations like Exxon Mobil and Walmart make billions of dollars, while many of their employees can barely afford to raise their family. Mr. Nader talked about corporations as an artificial entity instead of targeting the actual people working for them.&lt;/p&gt;
&lt;p&gt;He briefly touched on trade with China, arguing that it was not really &amp;#8220;free trade.&amp;#8221; Products imported from China have been found contaminated with all kinds of toxins and made headline news. This has put thousands of consumers at risk, including vulnerable ones like children.&lt;/p&gt;
&lt;p&gt;There were a few memorable lines to remember. &amp;#8220;If you get turned on by politics, politics will turn on you.&amp;#8221; &amp;#8220;If you know and don&amp;#8217;t do, you don&amp;#8217;t know.&amp;#8221; These two phrases effectively summarized his plea for citizens to get active in civics and politics.&lt;/p&gt;
&lt;p&gt;On current politics, he was critical of the Bush administration for removing personal liberties and expanding the power of the Executive Office. On party politics, he argued that the Democrats and Republicans are getting increasingly similar in that they now pick very few issues as contention points, such as abortion. However, people are interested and involved in many more issues that the two parties kind of ignore and do not differentiate between, such as the use of genetically modified crops, and the Federal Reserve.&lt;/p&gt;
&lt;p&gt;When he was asked by a member of the audience about the 2000 election and his spoiler status, he became impassioned and argued that many other things could have led to a Gore victory and that he cannot be blamed. He ended by saying that while smaller parties may not be electable, they are key in helping guide the larger parties to the right path.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/kanwei/~4/880PPfycH0Y" height="1" width="1"/&gt;</content>
 <feedburner:origLink>http://kanwei.com/2008/02/20/ralph-nader-at-emory.html</feedburner:origLink></entry>
 
 <entry>
   <title>My Experiences as a Collegiate Rower</title>
   <link href="http://feedproxy.google.com/~r/kanwei/~3/PCTHX8IhcP0/rowing-experiences.html" />
   <updated>2008-02-18T00:00:00-05:00</updated>
   <id>http://kanwei.com/2008/02/18/rowing-experiences</id>
   <content type="html">&lt;p&gt;I rowed in &lt;a href="http://www.rathburn.net/rowing/traits.html" title="Rower Personality Traits"&gt;bow seat&lt;/a&gt; for Emory Crew.&lt;/p&gt;

&lt;p&gt;Stephen Hawking was once a coxswain for Oxford College. Since he was super smart, he chose to be a coxswain instead of a rower.&lt;/p&gt;

&lt;p&gt;I wasn't so smart. I signed up for crew my sophomore year with no idea what I was getting into. It seemed like a good idea at the time. Enjoying mornings rowing on tranquil water? Check. Getting into the best shape of my life? Check. Joining an elite white man's sport? Check. Looking back, I think there was some false advertising and selective omissions in the flyers.&lt;/p&gt;

&lt;p&gt;And so there I was, sitting on a rowing ergometer, having never played a sport since dodgeball in elementary school (which I dominated, by the way.) I was flanked by guys who looked much tougher and fitter than me. Head Coach Bryce Carlson gave us a quick lesson to get us started. "Hang from the catch", "drive with the legs", "feel the connection." The essence of the whole sport in three easy-to-remember quotes? I was starting to like this. I quickly changed my mind twenty minutes later when I couldn’t feel my legs and wobbled home like a drunk chicken.&lt;/p&gt;

&lt;p&gt;The thing about nerds is that they get obsessive about their hobbies. Crew became one of mine. I was terrible when I first started; on the first fitness test I was slower than everybody, including girls on the women's team who weighed half of what I did. Through hard work I ended up being almost as fast as my 6'2 "french explosion" buddy Jim, and consistently beat my other 6'2 "stereotypical tall skinny white lightweight" buddy Jared. our squad proceeded to do well at our competitions.&lt;/p&gt;

&lt;p&gt;Racing at the Head of the Charles and rowing on the river that I used to frequent as a high school student was the highlight of my short career that was hampered by lower back problems.&lt;/p&gt;

&lt;p&gt;So why did I row? I like to think that it was "to be the best that I can be", or to prove that chubby asians could become good athletes, or that rowing makes a great allegory to life, or to finally become a jock (utterly failed at that.) The truth was that I was probably just addicted to the sport. I got my daily fix micro-tearing my muscles on the erg. The pain of rowing gives the mind a certain tranquility as all your worries, fears, doubts and insecurities are drowned by burning sensations radiating through all your limbs. The lingering high afterwards is well worth it. As all addicts know, your body acclimates to stimulation and you need more just to feel the same way, so I pulled harder and harder. Getting faster was just a byproduct.&lt;/p&gt;

&lt;p&gt;Also, I now get to tell people that I woke up at 4 a.m. a couple times a week for two years, which is pretty cool.&lt;/p&gt;
&lt;img src="http://feeds.feedburner.com/~r/kanwei/~4/PCTHX8IhcP0" height="1" width="1"/&gt;</content>
 <feedburner:origLink>http://kanwei.com/2008/02/18/rowing-experiences.html</feedburner:origLink></entry>
 
 <entry>
   <title>Philosophers and Marriage</title>
   <link href="http://feedproxy.google.com/~r/kanwei/~3/HMa7CrYk6GY/philosophers-and-marriage.html" />
   <updated>2008-01-10T00:00:00-05:00</updated>
   <id>http://kanwei.com/2008/01/10/philosophers-and-marriage</id>
   <content type="html">&lt;h1&gt;Why do Philosophers Not Get Married?&lt;/h1&gt;

&lt;!-- Just an observation. --&gt;


&lt;p&gt;I took an introductory class to Western philosophy last year. I did some research on the personal lives of some famous philosophers.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Immanuel Kant – Never married.&lt;/li&gt;
&lt;li&gt;Friedrich Nietzsche – Never married.&lt;/li&gt;
&lt;li&gt;René Descartes – Never married. Illegitimate daughter.&lt;/li&gt;
&lt;li&gt;David Hume – Never married.&lt;/li&gt;
&lt;li&gt;John Locke – Never married.&lt;/li&gt;
&lt;li&gt;Thomas Aquinas – Never married.&lt;/li&gt;
&lt;li&gt;Gottfried Leibniz – Never married.&lt;/li&gt;
&lt;li&gt;Baruch Spinoza – Never married.&lt;/li&gt;
&lt;li&gt;Jean-Paul Sartre – Never married.&lt;/li&gt;
&lt;li&gt;Arthur Schopenhauer – Never married. "Marrying means, to grasp blindfold into a sack hoping to find out an eel out of an assembly of snakes." (Kinky guy, apparently.)&lt;/li&gt;
&lt;li&gt;Jean-Jacques Rousseau - Never married. Illegitimate children.&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;On the other side:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;John Stuart Mill - married Harriet Taylor after 21 years of an intimate friendship.&lt;/li&gt;
&lt;li&gt;Hegel - married Marie Helena Susanna von Tucher&lt;/li&gt;
&lt;li&gt;Francis Bacon - married Alice Barnham&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;Prominent scientists were not spared:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Isaac Newton – Never married.&lt;/li&gt;
&lt;li&gt;Gottfried Leibniz – Never married.&lt;/li&gt;
&lt;li&gt;Alfred Nobel – Never married.&lt;/li&gt;
&lt;li&gt;Einstein - Married cousin!?&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;These are some of the biggest rock stars of the Western world, and some of the smartest people to ever live. Although a few were religious figures and were not allowed to marry, why didn't those who could, do so and continue their legacy? Did their intelligence allow them to figure out something about life that most of us haven't?&lt;/p&gt;

&lt;p&gt;Yes, I've read the articles about the positive correlation between intelligence and social ineptitude, lack of friends, depression, and generally everything bad about life. But even all of that can't cause you not to have a special someone. These guys were bigshots. They made the choice not to get married. Were there no women up to their standards? No time for mushy relationship stuff? Wait, I got it. They chose abstinence because they couldn't practice safe sex since contraception had not been invented. Either that, or I give up.&lt;/p&gt;
&lt;img src="http://feeds.feedburner.com/~r/kanwei/~4/HMa7CrYk6GY" height="1" width="1"/&gt;</content>
 <feedburner:origLink>http://kanwei.com/2008/01/10/philosophers-and-marriage.html</feedburner:origLink></entry>
 
 <entry>
   <title>10 Things to Know About France</title>
   <link href="http://feedproxy.google.com/~r/kanwei/~3/WTpOsusJ3cA/10-things-about-france.html" />
   <updated>2007-06-28T00:00:00-04:00</updated>
   <id>http://kanwei.com/2007/06/28/10-things-about-france</id>
   <content type="html">&lt;p&gt;&lt;strong&gt;1. Stuff is expensive.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;The US dollar isn&amp;#8217;t doing so hot. I mentally multiply all prices in euros by 1.35 (by 2 in England) to get the dollar equivalent. Everything here (even wine!) is more expensive than in the US, save chocolate and specialty cheese.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;2. People kiss a lot&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;You kiss everybody. On my first day at work, I broke my all-time kissing record in a single day. Ok, so it&amp;#8217;s only cheek kissing, and you do it twice, one on each cheek so the other doesn&amp;#8217;t get jealous. In Switzerland they do it three times so it sucks for one cheek.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;3. Smoking is still cool&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;A lot more people (scientific: higher proportion of people) smoke here than in the US. People don&amp;#8217;t look down on you and tell you it&amp;#8217;s bad for your health. There&amp;#8217;s actually a &lt;span class="caps"&gt;GIANT&lt;/span&gt; label that says &amp;#8220;&lt;span class="caps"&gt;SMOKING&lt;/span&gt; &lt;span class="caps"&gt;KILLS&lt;/span&gt; &lt;span class="caps"&gt;YOU&lt;/span&gt;&amp;#8221; instead of the discreet label on American packs. It just proves that smokers know the risks and do it anyways.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;4. Lunch break is ridiculously long&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;The primary investigators at my lab usually have lunch by themselves, but the rest of us (4-5) go to the cafeteria together. It&amp;#8217;s only 2.75 euros. There is never any alcohol and the food is always better than the &lt;span class="caps"&gt;DUC&lt;/span&gt; at Emory (although it&amp;#8217;s also sponsored by Sodexho, hilarious). After lunch, we &lt;span class="caps"&gt;ALWAYS&lt;/span&gt; have coffee and everybody meets up to chat in the lobby.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;5. Everyone is addicted to coffee&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;They got me hooked too. There&amp;#8217;s a coffee machine that dispenses 20 different varieties for 40 cents. Tastes better than Starbucks and is 5 times cheaper.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;6. Football is life&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Football (soccer) is more of a religion here than a sport. There&amp;#8217;s always a bunch of people playing outside. The good players are amazing to watch and hard to catch up to. However, they&amp;#8217;re usually small and quick and I can get away knocking others around with my bulky body. When a big game is on TV, just about &lt;span class="caps"&gt;EVERYBODY&lt;/span&gt; watches, usually at bars and restaurants.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;7. Kebabs are the French version of cheeseburgers&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Döner kebab shops are more popular here than Waffle House in the American South. A kebab is basically a sandwich using meat carved from a giant block of meat rotating on an oven. Lettuce and tomatoes are standard, just like a cheeseburger, except that kebabs are much tastier and possibly healthier for your body.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;8. People love American music&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;It&amp;#8217;s funny how much every Western country&amp;#8217;s youth are influenced by American culture. Marilyn Manson, Maroon 5, Nelly Furtado, Justin Timberlake, and rappers I don&amp;#8217;t know are hugely popular here.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;9. Foreign students are cool&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Bordeaux has 60,000 students and a &lt;span class="caps"&gt;LOT&lt;/span&gt; of them are ethnically foreign. I hear from friends that racism is sometimes found in the classroom, but not rampant. France has been divided on the issue of immigration for a long time.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;10. France is 10 times better when you&amp;#8217;re paid to be there!&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;I would like to thank Emory&amp;#8217;s &lt;span class="caps"&gt;IRES&lt;/span&gt; program for such a wonderful experience!&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/kanwei/~4/WTpOsusJ3cA" height="1" width="1"/&gt;</content>
 <feedburner:origLink>http://kanwei.com/2007/06/28/10-things-about-france.html</feedburner:origLink></entry>
 
 <entry>
   <title>Reporting in Bordeaux, France</title>
   <link href="http://feedproxy.google.com/~r/kanwei/~3/nxgjJ0BmohU/reporting-from-bordeaux.html" />
   <updated>2007-05-23T00:00:00-04:00</updated>
   <id>http://kanwei.com/2007/05/23/reporting-from-bordeaux</id>
   <content type="html">&lt;p&gt;&lt;strong&gt;I&amp;#8217;m doing classified research in France. I&amp;#8217;ll share what I can here, but do also &lt;a href="http://emoryresearchabroad.blogspot.com"&gt;check out the cool work that my fellow Emory students are doing&lt;/a&gt; as well.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;My name is Kanwei and I&amp;#8217;m an alcoholic.&lt;/p&gt;
&lt;p&gt;Well, not really. Quite the opposite actually, but I&amp;#8217;ll talk about that another day. I&amp;#8217;m writing at 9pm from the bench outside the cafeteria (closed) which is next to the library (also closed). Has Emory spoiled me to the point that I expect every university to provide food and shelter 24/7? Why is there no Internet in my dorm? How do French students get any work done? Am I really complaining on a blog that will be read by my benefactors? (benefactors: no, I&amp;#8217;m not really complaining, and thanks for the support)&lt;/p&gt;
&lt;p&gt;You see, I arrived at the dorms on Friday at around noon. The previous day was a national holiday, and they forgot to tell me that in France, when Thursday is a holiday, Friday is naturally a holiday too. Duh. I was supposed to speak with the &lt;span class="caps"&gt;RHD&lt;/span&gt; of the dorms (on holiday) and ended up having to convince them that oui, je suis American, non, je ne suis pas un idiote qui n&amp;#8217;a pas ses papiers, et oui, j&amp;#8217;aime le football. I got to my room and instinctively looked for the ethernet plug. Nope. So I was stuck in my room, no Internet, no phone, and everyone was on holiday. What did I do? Go downtown, of course.&lt;/p&gt;
&lt;p&gt;Since I didn&amp;#8217;t feel like spending more euros on transportation (1.30€) because the exchange is now 0.7 €/&lt;span class="caps"&gt;USD&lt;/span&gt;, I walked along the tram tracks into the city. There, I found everyone that I had previously mentioned were on vacation. The streets were narrow and were absolutely packed. I had a good time looking at people I&amp;#8217;d never met before (everyone) as I passed them. French people are taller than Americans on average, it seems. The city center was pretty nice, with an esplanade. I was pretty tired though so I left early. I&amp;#8217;ll come back with the camera another day.&lt;/p&gt;
&lt;p&gt;When I got back to the dorms, I met some of my neighbors. Yassine (Moroccan) was one of them, and I played Pro Evolution Soccer 6 (best football game ever) with him and his friends. It&amp;#8217;s weird because I&amp;#8217;d actually played this exact game back home (weird huh) and so I actually won a couple matches. We&amp;#8217;re still friends to this day.&lt;/p&gt;
&lt;p&gt;So anyways, I start work tomorrow and I&amp;#8217;m still outside the cafeteria. It&amp;#8217;s now 10pm and getting cold. Talk to you again soon, mes amis.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/kanwei/~4/nxgjJ0BmohU" height="1" width="1"/&gt;</content>
 <feedburner:origLink>http://kanwei.com/2007/05/23/reporting-from-bordeaux.html</feedburner:origLink></entry>
 
 <entry>
   <title>Ten Ways Being a Geek Makes You Less Attractive</title>
   <link href="http://feedproxy.google.com/~r/kanwei/~3/qOOzQjFgnkw/geeks-less-attractive.html" />
   <updated>2007-04-01T00:00:00-04:00</updated>
   <id>http://kanwei.com/2007/04/01/geeks-less-attractive</id>
   <content type="html">&lt;p&gt;One of my friends showed me this article titled &lt;a href="http://mingle2.com/blog/view/10-ways-being-a-geek-makes-you-more-attractive"&gt;Ten Ways Being a Geek Makes You More Attractive&lt;/a&gt;. It left me very confused. It compelled me to do the right thing: to debunk these crazy accusations.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;1. You&amp;#8217;re probably very smart.&lt;/strong&gt;&lt;br /&gt;
This guy has obviously never been a geek. Intelligence isn&amp;#8217;t attractive; muscles are. Knowing Pi to 314 digits: No. Six-packs: Yes. Both: No.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;2. It&amp;#8217;s hip to be geek&lt;/strong&gt;&lt;br /&gt;
Geeks don&amp;#8217;t like other people. It&amp;#8217;s why they dress so badly. Repelling others means more time to code. They just got lucky that T-shirts and jeans are currently &amp;agrave; la mode.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;3. You geek out on more than just your computer&lt;/strong&gt;&lt;br /&gt;
Geeks also geek out on Star Trek collections, Warhammer figurines, and Pokemon decks.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;4. Geek humor is the best humor.&lt;/strong&gt;&lt;br /&gt;
The only requirement is that you have to be of equal geekity to understand the jokes. They go on the lines of: There are 10 kinds of people in the world: those who are attractive and those who aren&amp;#8217;t. (If you get this, you are truly a geek.)&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;5. You listen to good music.&lt;/strong&gt;&lt;br /&gt;
They listen to good music while the guy with the guitar next door is getting busy.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;6. You make good money.&lt;/strong&gt;&lt;br /&gt;
More money for computer parts, Star Trek collections, Warhammer figurines, and Pokemon decks! In all seriousness, geeks like girls who don&amp;#8217;t care about money, which is exactly why they fail.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;7. You fix stuff.&lt;/strong&gt;&lt;br /&gt;
For free. That makes them slightly worse than servants. Some genuinely want to help, most have ulterior motives.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;8. You&amp;#8217;ve got your own stuff going on.&lt;/strong&gt;&lt;br /&gt;
Computer parts, Star Trek collections, Warhammer figurines, and Pokemon decks. Dude, everyone has stuff going on, not just geeks.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;9. You&amp;#8217;re very articulate.&lt;/strong&gt;&lt;br /&gt;
Last time I checked, many bloggers can&amp;#8217;t tell the difference between its and it&amp;#8217;s, their and they&amp;#8217;re, your and you&amp;#8217;re, then and than. The worst part is that no one actually calls people out on these flagrant errors and so the Internet is further polluted with bad grammar on a daily basis.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;10. You&amp;#8217;re passionate.&lt;/strong&gt;&lt;br /&gt;
Computer parts, Star Trek collections, Warhammer figurines, and Pokemon decks. The geek&amp;#8217;s downfall? Thinking he&amp;#8217;s better than everyone else.&lt;/p&gt;
&lt;p&gt;Geeks despise being attractive, and most of them have gone to great lengths (most of their lifetimes) to make sure that it never happens, so please don&amp;#8217;t take that away from them.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/kanwei/~4/qOOzQjFgnkw" height="1" width="1"/&gt;</content>
 <feedburner:origLink>http://kanwei.com/2007/04/01/geeks-less-attractive.html</feedburner:origLink></entry>
 
 <entry>
   <title>One person reads this blog, and statistically, it's not you</title>
   <link href="http://feedproxy.google.com/~r/kanwei/~3/lwS1VoXB8Y4/one-person-reads-this.html" />
   <updated>2007-03-01T00:00:00-05:00</updated>
   <id>http://kanwei.com/2007/03/01/one-person-reads-this</id>
   <content type="html">&lt;p&gt;Eric Schmidt, &lt;span class="caps"&gt;CEO&lt;/span&gt; of Google, Apple board member, former &lt;span class="caps"&gt;CEO&lt;/span&gt; of Sun Microsystems, multi-billionaire, nerd-hero and good friend of mine [citation needed], made this joke at a conference:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Most blogs have precisely one reader&amp;mdash;the blogger themself.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;I think he was making fun of me. It&amp;#8217;s not just a joke; it&amp;#8217;s true most of the time. No one knows how many blogs there are. If you count a myspace profile as blog, then there are at least tens of millions. Facebook has also allowed blogging using their Notes module. If I had to guess, I would have to say that there are about two hundred million blogs worldwide, or about 3% of the world population. Of those, I&amp;#8217;d say only a quarter of them are regularly updated.&lt;/p&gt;
&lt;p&gt;So what makes these 50 million people think that their opinion is important enough to let the whole world know about them? I mean, when was the last time you published your diary? (Except those celebrities who seem to publish their sex lives in video format once a year)&lt;/p&gt;
&lt;p&gt;Fame? Attention? Vanity? To show that you exist? Probably all of the above.&lt;/p&gt;
&lt;p&gt;The best forum poster I&amp;#8217;ve ever encountered published his thoughts as dialogues with himself. He would tell a story, often referring to himself in the third person. It would usually star a misled young man, presumably his old self, seeking advice from a mentor, presumably his new self. It was one of the most effective form of textual communication that I&amp;#8217;ve experienced. He wasn&amp;#8217;t telling you what you should be doing; he showed you his mistakes and what he learned so that you might not repeat them. I think that this is a great format for blog writing.&lt;/p&gt;
&lt;p&gt;When I write something here, it&amp;#8217;s usually a dialogue with myself; a snapshot of what I&amp;#8217;m thinking of at the time. When I go back and revisit my past writings, I always wonder how I managed to write such crappy stuff, and then refactor the text. My writing slowly improves over time, and one day all these articles will become masterpieces.&lt;/p&gt;
&lt;p&gt;You will get more out of blogging if you simply write for yourself.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/kanwei/~4/lwS1VoXB8Y4" height="1" width="1"/&gt;</content>
 <feedburner:origLink>http://kanwei.com/2007/03/01/one-person-reads-this.html</feedburner:origLink></entry>
 
 <entry>
   <title>I am the Official Kanwei of the World</title>
   <link href="http://feedproxy.google.com/~r/kanwei/~3/uNS99yrFfHQ/official-kanwei.html" />
   <updated>2006-11-15T00:00:00-05:00</updated>
   <id>http://kanwei.com/2006/11/15/official-kanwei</id>
   <content type="html">&lt;p&gt;Not to brag or anything, but venerable Google ranks me as the #1 Kanwei on the Internet. So does Yahoo. And Ask.com. &lt;span class="caps"&gt;AND&lt;/span&gt; &lt;span class="caps"&gt;MSN&lt;/span&gt;.&lt;span class="caps"&gt;COM&lt;/span&gt;! (Finally!)&lt;/p&gt;
&lt;p&gt;I feel a great achievement in being the #1 Kanwei. It means that anyone who knows my name (and can spell it properly, however unlikely) can instantly find me on the net. It gives me a huge ego boost. How many people can say, &amp;#8220;Just google my name, and feel pretty lucky.&amp;#8221; Boom.&lt;/p&gt;
&lt;p&gt;It reminds me about how I got this domain in the first place. Back in the day, when I was a young lad, domain names were monopolized by Network Solutions, and cost $70/year. Then one day they let other companies sell domains, and prices dropped to about $8/year. That&amp;#8217;s when I got on the bandwagon and staked my flag in the fertile ground of the Internet. Kanwei.com. However, that would only be the beginning of my cyberland adventures.&lt;/p&gt;
&lt;p&gt;It was sophomore year of my high school career. I had put up an anagram game of the 42 presidents, as well a bunch of mindmaps that I made for Honors Chemistry class, on my website. Things were good. Then one day, I forgot to renew my domain. The next day, it was owned by Commies!&lt;/p&gt;
&lt;p&gt;You see, my name may be unique in the Western world (I&amp;#8217;ll give you my firstborn if you find some non-asian guy called Kanwei), but in Asia, with its near endless number of people, impossible probabilities become very possible (I am told this is now called Chinese arithmetic). In fact, a Chinese company had backordered the domain, almost as if they knew I would forget to renew. Their mind-reading machine must finally be operational. For a full year, I had to live in shame as my domain belonged to a company that made, among other things, &lt;span class="caps"&gt;USB&lt;/span&gt; cables. How embarrassing.&lt;/p&gt;
&lt;p&gt;Never one to take defeat, I planned my revenge. I used the same tactic that they had used on me. In a year, precisely on March 5, 2004, I had the name back. Wrestled back from the clutches of the enemy. They sent me an email (in Chinese too, ha!) asking me if they could buy it from me. Yeah right. They ended up with kanwei.cn, which is what they should have used in the first place. People have to realize that Americans are better than everyone else (no longer correct as of 2009), and thus should have the privilege of being the only ones allowed to use .com&amp;#8217;s. In a small way, I have done my part.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/kanwei/~4/uNS99yrFfHQ" height="1" width="1"/&gt;</content>
 <feedburner:origLink>http://kanwei.com/2006/11/15/official-kanwei.html</feedburner:origLink></entry>
 
 <entry>
   <title>Expensive College Textbooks</title>
   <link href="http://feedproxy.google.com/~r/kanwei/~3/BZZXGtXbabg/expensive-textbooks.html" />
   <updated>2006-09-06T00:00:00-04:00</updated>
   <id>http://kanwei.com/2006/09/06/expensive-textbooks</id>
   <content type="html">&lt;p&gt;Why are college textbooks so expensive? Is it the premium, glossy paper and the hard cover? Is it to pay the distinguished authors who spend years researching and writing on their subjects? Maybe the fact that college students can afford anything?&lt;/p&gt;
&lt;p&gt;I used to have no idea why, but after taking Microeconomics 101 last semester, I now have a better understanding. College textbooks are very inelastic goods, meaning that the higher they are priced, the more money publishers make, because it&amp;#8217;s more of a necessity than a luxury. There are no true alternatives for college textbooks. They&amp;#8217;re chosen by professors, and you have to buy them! Because of this, publishers and bookstores can charge more.&lt;/p&gt;
&lt;p&gt;College bookstores are usually on-campus monopolies. They set the price higher in return for convenience of access. Recently, more people have been shopping online, and while bookstores will not go the way of the Dodo anytime soon, they should face some pretty strong pressures to lower prices. The major downside of shopping online is the hassle of having to search for the book and wait for the delivery, but I believe more people will be willing to do this as online bookstores have matured and made the process easier.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/kanwei/~4/BZZXGtXbabg" height="1" width="1"/&gt;</content>
 <feedburner:origLink>http://kanwei.com/2006/09/06/expensive-textbooks.html</feedburner:origLink></entry>
 
 <entry>
   <title>Civilization is Addictive</title>
   <link href="http://feedproxy.google.com/~r/kanwei/~3/eOAHbMb4H-w/civilization-addiction.html" />
   <updated>2006-04-28T00:00:00-04:00</updated>
   <id>http://kanwei.com/2006/04/28/civilization-addiction</id>
   <content type="html">&lt;p&gt;Civilization is ridiculously addictive. Careers have been lost, relationships ended, hours disappeared, all because someone decided that with one more turn, they could crush the Greek in a quick display of tactical brilliance. An hour later, the same person is pondering how one turn became thirty, and looking over at the clock, realizes it&amp;#8217;s way past bedtime.&lt;/p&gt;
&lt;p&gt;Ok, so maybe I exaggerated a little, but anyone who&amp;#8217;s ever played a Civilization game can probably relate to this story. Why is this computer game so addictive? For starters, it gives you a sense of power, control and responsibility. It&amp;#8217;s up to you to guide your people to greatness, mainly through military conquest, and if that fails, through winning the space race. If you&amp;#8217;re really bad at the game, there&amp;#8217;s always the diplomatic victory to shoot for, but be warned that you will be ridiculed by all your opponents when you win (even those who voted for you.)&lt;/p&gt;
&lt;p&gt;For many, the Civ addiction is on and off. Like most drugs, withdrawal symptoms can present themselves in many forms, including fantasizing about accumulating stockpiles of ICBMs to nuke into outer space the next civilization who cancels its Open Borders agreement with you. However, once those fantasies have been realized through hours of pure bliss, real life can proceed normally until one day, many months later, the Civilization icon on the desktop beckons to be double-clicked on. The call is heeded, and somewhere, Sid Meier is smiling.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/kanwei/~4/eOAHbMb4H-w" height="1" width="1"/&gt;</content>
 <feedburner:origLink>http://kanwei.com/2006/04/28/civilization-addiction.html</feedburner:origLink></entry>
 
 <entry>
   <title>Compulsory Voting</title>
   <link href="http://feedproxy.google.com/~r/kanwei/~3/h7kDhlwuAeg/compulsory-voting.html" />
   <updated>2006-02-28T00:00:00-05:00</updated>
   <id>http://kanwei.com/2006/02/28/compulsory-voting</id>
   <content type="html">&lt;p&gt;Voter turnout in America is one of the lowest in first-world democratic countries. According to Wilson and DeIulio, 47.2% of the voting-age population voted and 63.4% of registered voters voted in the 1996-2001 elections&lt;sup&gt;1&lt;/sup&gt;. Since a democracy is supposed to reflect the opinion of voters, low turnout can be seen as a problem. If less than half of people vote, it is difficult to argue that everyone is represented, and one could even argue that democracy has failed in this country. However, this is clearly not the case, and it is hard to argue that compulsory voting will be helpful to this country.&lt;/p&gt;
&lt;p&gt;The benefit of compulsory voting is that everyone will technically be represented, realizing the ideal of democracy. One argument as to why turnout is so low is that it is tedious for Americans to register to vote, since it requires filling out paperwork and keeping updated records. Also, there have historically been many obstacles for certain people to vote, such as African Americans and women. The grandfather clause, literacy tests, poll taxes, and intimidation were all used to keep eligible African Americans from registering to vote. Making voting compulsory and automatically registering all eligible citizens, like how it’s done in some European countries, will once and for all solve these problems.&lt;/p&gt;
&lt;p&gt;However, low turnout cannot be explained by how difficult it is to register. Even after making the process easier with the motor-voter law in 1993, and the passing of the Voting Rights Act of 1965, there is not much evidence that turnout has increased, even though there are more registered voters&lt;sup&gt;1&lt;/sup&gt;. One possible reason for the low turnout in national elections is that because of the winner-takes-all system, some voters feel like they don’t need to vote, as their state historically always goes to the same party. A person in Massachusetts can safely assume that the Democratic Party will win, and someone in Texas can assume that the Republican Party will win. Also, Americans separately elect every government official, as opposed to many European countries where one vote is used to determine a much larger outcome. Another reason is that there are many other ways of being politically active that can have more impact than voting, such as holding public demonstrations. For example, King’s March on Washington had much more impact than votes could ever convey.&lt;/p&gt;
&lt;p&gt;There are too many fundamental problems in compulsory voting that will ensure it does not happen in America. First and most importantly, it is unconstitutional to force people to vote. The founding fathers wanted to ensure that government not intrude on personal liberties, and the right to vote, or not to vote, is one of those liberties. Second, forcing people to vote would be detrimental as some people simply do not care about politics, and do not know much about the candidates. They would vote blindly, or worse, randomly. For example, a demagogue could receive votes simply because people have heard of his name, and being forced to vote, put his name on the ballot on Election Day, not knowing any of his credentials or beliefs.&lt;/p&gt;
&lt;p&gt;In conclusion, compulsory voting is not good for America. Low turnout is not a problem as voting is designed to be voluntary, and voting is not the only means of political representation and expression. The system is fine as it is and should be left alone.&lt;br /&gt;
&lt;p id="fn1"&gt;&lt;sup&gt;1&lt;/sup&gt; James Q. Wilson and John J. DiIulio, Jr. &lt;em&gt;American Government: The Essentials&lt;/em&gt;. 9th ed. Boston: Houghton Mifflin Company, 2004, p. 132-133&lt;/p&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/kanwei/~4/h7kDhlwuAeg" height="1" width="1"/&gt;</content>
 <feedburner:origLink>http://kanwei.com/2006/02/28/compulsory-voting.html</feedburner:origLink></entry>
 
 <entry>
   <title>The Girlfriend Problem</title>
   <link href="http://feedproxy.google.com/~r/kanwei/~3/LJQqGEbyePE/the-girlfriend-problem.html" />
   <updated>2005-09-25T00:00:00-04:00</updated>
   <id>http://kanwei.com/2005/09/25/the-girlfriend-problem</id>
   <content type="html">&lt;p&gt;In the society I live in, attracting the opposite sex is an important aspect of a young man&amp;#8217;s life. There is great peer pressure to not only have a girlfriend, but to have her be a looker as well. Since there are only so many hot girls, this is a problem for many guys.&lt;/p&gt;
&lt;p&gt;The obvious solution is to tell yourself that your peers are wrong about a lot of things and that this is one of them, but everyone knows that this is a copout.&lt;/p&gt;
&lt;p&gt;Another solution is to get a plainer looking girlfriend and say that it&amp;#8217;s what&amp;#8217;s inside that matters, but deep down you really want that other girl; you know, the one who smells like jungle gardenia and makes you wish you were a little more handsome.&lt;/p&gt;
&lt;p&gt;A clever solution would be to act like a pimp and not have a girlfriend, since everybody know pimps have too many girls around to commit to one. Problem solved, but who are you kidding?&lt;/p&gt;
&lt;p&gt;As you have probably figured out, the best way to solve this problem is to actually get a hot girlfriend. There are great risks involved, including rejection, embarrassment, permanent loss of self-esteem, and being joke fodder for all her friends for months to come. If you decide the benefits outweigh the risks, proceed to make your move! If honesty is a concern, refrain from using too much alcohol, and don&amp;#8217;t tell her you have a terminal disease. Remember, if that dumb fat guy can land one, so can you!&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/kanwei/~4/LJQqGEbyePE" height="1" width="1"/&gt;</content>
 <feedburner:origLink>http://kanwei.com/2005/09/25/the-girlfriend-problem.html</feedburner:origLink></entry>
 
 
</feed>
