{"id":693,"date":"2015-04-15T19:06:08","date_gmt":"2015-04-15T13:36:08","guid":{"rendered":"http:\/\/smritiweb.com\/navin\/?p=693"},"modified":"2015-04-15T19:22:01","modified_gmt":"2015-04-15T13:52:01","slug":"which-programming-language-to-use-to-solve-the-singapore-math-problem","status":"publish","type":"post","link":"https:\/\/smritiweb.com\/navin\/technology\/which-programming-language-to-use-to-solve-the-singapore-math-problem","title":{"rendered":"Which Programming Language to use to solve the Singapore Math problem"},"content":{"rendered":"<p>Being a programmer means that every once in a while, instead of doing real work, you spend time writing a completely pointless program just for fun. Which is how I ended up writing a Prolog program to solve the <a href=\"http:\/\/www.nytimes.com\/2015\/04\/15\/science\/a-math-problem-from-singapore-goes-viral-when-is-cheryls-birthday.html\">Singapore Math Problem<\/a> that has recently gone viral on the internet.<\/p>\n<p>This is <a href=\"http:\/\/punetech.com\/amit\">Amit Paranjape<\/a>&#8216;s fault. He asked me, &#8220;Isn&#8217;t solving this problem simply a question of creating sets of dates that satisfy the various conditions, and then intersecting them until you&#8217;re left with just one date? Wouldn&#8217;t it be easy to write a program to solve this program automatically?&#8221; And he went on to ask, &#8220;Isn&#8217;t there already some high level programming language where such set constraints can be described at a high level, and the program solves the problem for you?&#8221;<\/p>\n<p>Turns out, there is. The <a href=\"http:\/\/www.learnprolognow.org\/\">Prolog programming language<\/a> is a general purpose programming language that allows us to specify high level predicates that must be true of your data, and then it automatically figures out which pieces of data satisfy all your constraints. It&#8217;s a rather different kind of programming language.<\/p>\n<p>So, I couldn&#8217;t resist. Like many other computer science graduates, I learnt a little about Prolog during my undergraduate studies, and then proceeded to never encounter it anywhere in my real life. But here was a problem that seemed like it would be fun to solve using Prolog. The fact that I actually don&#8217;t know Prolog isn&#8217;t something that I let bother me.<\/p>\n<p>So, I spent a few hours downloading a Prolog compiler, learning the basics of the language, and solving the problem.<\/p>\n<p>And, indeed, Prolog is a good language to solve the problem. The solution is below. If you don&#8217;t know anything about Prolog, you might still be able to make some sense of the program by doing the following: Any statement of the form &#8220;<code>abc(x,y).<\/code>&#8221; should be read as: <em>the property <code>abc<\/code> is true for <code>x<\/code> and <code>y<\/code>.<\/em> And any statement of the form &#8220;<code>pqr(X) :- abc(X,Y), jkl(Y,Z).<\/code>&#8221; should be read as: <em>the property <code>pqr<\/code> is true for any <code>X<\/code> if <code>abc<\/code> is true for that <code>X<\/code> and some <code>Y<\/code>, and <code>jkl<\/code> is true for that <code>Y<\/code> and some <code>Z<\/code>.<\/em> And the statements involving <code>setof<\/code> are simply trying to count the number of elements satisfying some property.<\/p>\n<p>Here&#8217;s the solution:<\/p>\n<div class=\"codehilite\" style=\"background: #f8f8f8\">\n<pre style=\"line-height: 125%\"><span style=\"color: #408080; font-style: italic\">% This is the original data that Cheryl gave<\/span>\n<span style=\"color: #0000FF\">birthday_candidate<\/span>(<span style=\"color: #BA2121\">may<\/span>, <span style=\"color: #666666\">15<\/span>).\n<span style=\"color: #0000FF\">birthday_candidate<\/span>(<span style=\"color: #BA2121\">may<\/span>, <span style=\"color: #666666\">16<\/span>).\n<span style=\"color: #0000FF\">birthday_candidate<\/span>(<span style=\"color: #BA2121\">may<\/span>, <span style=\"color: #666666\">19<\/span>).\n<span style=\"color: #0000FF\">birthday_candidate<\/span>(<span style=\"color: #BA2121\">june<\/span>, <span style=\"color: #666666\">17<\/span>).\n<span style=\"color: #0000FF\">birthday_candidate<\/span>(<span style=\"color: #BA2121\">june<\/span>, <span style=\"color: #666666\">18<\/span>).\n<span style=\"color: #0000FF\">birthday_candidate<\/span>(<span style=\"color: #BA2121\">july<\/span>, <span style=\"color: #666666\">14<\/span>).\n<span style=\"color: #0000FF\">birthday_candidate<\/span>(<span style=\"color: #BA2121\">july<\/span>, <span style=\"color: #666666\">16<\/span>).\n<span style=\"color: #0000FF\">birthday_candidate<\/span>(<span style=\"color: #BA2121\">august<\/span>, <span style=\"color: #666666\">14<\/span>).\n<span style=\"color: #0000FF\">birthday_candidate<\/span>(<span style=\"color: #BA2121\">august<\/span>, <span style=\"color: #666666\">15<\/span>).\n<span style=\"color: #0000FF\">birthday_candidate<\/span>(<span style=\"color: #BA2121\">august<\/span>, <span style=\"color: #666666\">17<\/span>).\n\n<span style=\"color: #408080; font-style: italic\">% Now for some helper functions<\/span>\n<span style=\"color: #408080; font-style: italic\">% Any list that has more than one <\/span>\n<span style=\"color: #408080; font-style: italic\">% entry is ambiguous<\/span>\n<span style=\"color: #0000FF\">is_ambiguous<\/span>(<span style=\"color: #19177C\">List<\/span>) :- \n    <span style=\"color: #0000FF\">length<\/span>(<span style=\"color: #19177C\">List<\/span>, <span style=\"color: #19177C\">Len<\/span>), <span style=\"color: #19177C\">Len<\/span><span style=\"color: #666666\">&gt;1<\/span>.\n<span style=\"color: #408080; font-style: italic\">% Any list that has exactly one <\/span>\n<span style=\"color: #408080; font-style: italic\">% entry is not ambiguous<\/span>\n<span style=\"color: #0000FF\">is_not_ambiguous<\/span>(<span style=\"color: #19177C\">List<\/span>) :- \n    <span style=\"color: #0000FF\">length<\/span>(<span style=\"color: #19177C\">List<\/span>, <span style=\"color: #666666\">1<\/span>).\n\n<span style=\"color: #408080; font-style: italic\">% These will be true only for a <\/span>\n<span style=\"color: #408080; font-style: italic\">% Month or Date in the original list<\/span>\n<span style=\"color: #0000FF\">candidate_month<\/span>(<span style=\"color: #19177C\">Mon<\/span>) :- \n    <span style=\"color: #0000FF\">birthday_candidate<\/span>(<span style=\"color: #19177C\">Mon<\/span>, <span style=\"color: #008000; font-weight: bold\">_<\/span>). \n<span style=\"color: #0000FF\">candidate_date<\/span>(<span style=\"color: #19177C\">Date<\/span>) :- \n    <span style=\"color: #0000FF\">birthday_candidate<\/span>(<span style=\"color: #008000; font-weight: bold\">_<\/span>, <span style=\"color: #19177C\">Date<\/span>).\n\n<span style=\"color: #408080; font-style: italic\">% If you&#39;re given a month, and there <\/span>\n<span style=\"color: #408080; font-style: italic\">% are multiple candidate dates <\/span>\n<span style=\"color: #408080; font-style: italic\">% in that month, then you don&#39;t <\/span>\n<span style=\"color: #408080; font-style: italic\">% have enough information to<\/span>\n<span style=\"color: #408080; font-style: italic\">% deduce the birthday.<\/span>\n<span style=\"color: #408080; font-style: italic\">% Same thing for dates.<\/span>\n<span style=\"color: #0000FF\">month_is_ambiguous<\/span>(<span style=\"color: #19177C\">Mon<\/span>) :- \n    <span style=\"color: #0000FF\">candidate_month<\/span>(<span style=\"color: #19177C\">Mon<\/span>), \n    <span style=\"color: #0000FF\">setof<\/span>(<span style=\"color: #19177C\">D<\/span>,<span style=\"color: #0000FF\">birthday_candidate<\/span>(<span style=\"color: #19177C\">Mon<\/span>,<span style=\"color: #19177C\">D<\/span>),<span style=\"color: #19177C\">L<\/span>), \n    <span style=\"color: #0000FF\">is_ambiguous<\/span>(<span style=\"color: #19177C\">L<\/span>).\n<span style=\"color: #0000FF\">date_is_ambiguous<\/span>(<span style=\"color: #19177C\">Date<\/span>) :- \n    <span style=\"color: #0000FF\">candidate_date<\/span>(<span style=\"color: #19177C\">Date<\/span>),\n    <span style=\"color: #0000FF\">setof<\/span>(<span style=\"color: #19177C\">M<\/span>,<span style=\"color: #0000FF\">birthday_candidate<\/span>(<span style=\"color: #19177C\">M<\/span>, <span style=\"color: #19177C\">Date<\/span>), <span style=\"color: #19177C\">L<\/span>),\n    <span style=\"color: #0000FF\">is_ambiguous<\/span>(<span style=\"color: #19177C\">L<\/span>).\n\n\n<span style=\"color: #408080; font-style: italic\">% Albert&#39;s first deduction<\/span>\n<span style=\"color: #408080; font-style: italic\">% The month that Albert has <\/span>\n<span style=\"color: #408080; font-style: italic\">% been told is ambiguous, because he <\/span>\n<span style=\"color: #408080; font-style: italic\">% couldn&#39;t figure out the birthday<\/span>\n<span style=\"color: #0000FF\">albert_month_is_ambiguous<\/span>(<span style=\"color: #19177C\">Mon<\/span>) :- \n    <span style=\"color: #0000FF\">candidate_month<\/span>(<span style=\"color: #19177C\">Mon<\/span>), \n    <span style=\"color: #0000FF\">month_is_ambiguous<\/span>(<span style=\"color: #19177C\">Mon<\/span>).\n\n<span style=\"color: #408080; font-style: italic\">% In addition, Albert knows that <\/span>\n<span style=\"color: #408080; font-style: italic\">% Barnard doesn&#39;t know.<\/span>\n<span style=\"color: #408080; font-style: italic\">% Meaning that each date that he can <\/span>\n<span style=\"color: #408080; font-style: italic\">% deduce is ambiguous for Bernard<\/span>\n<span style=\"color: #0000FF\">albert_knows_bernard_doesnt_know<\/span>(<span style=\"color: #19177C\">Mon<\/span>) :- \n    <span style=\"color: #0000FF\">albert_month_is_ambiguous<\/span>(<span style=\"color: #19177C\">Mon<\/span>), \n    <span style=\"color: #0000FF\">forall<\/span>(<span style=\"color: #0000FF\">birthday_candidate<\/span>(<span style=\"color: #19177C\">Mon<\/span>,<span style=\"color: #19177C\">D<\/span>),\n    <span style=\"color: #0000FF\">date_is_ambiguous<\/span>(<span style=\"color: #19177C\">D<\/span>)).\n\n<span style=\"color: #408080; font-style: italic\">% Bernard&#39;s first deduction<\/span>\n\n<span style=\"color: #408080; font-style: italic\">% The date Bernard has been told is ambiguous,<\/span>\n<span style=\"color: #408080; font-style: italic\">% did could not figure out the birthday.<\/span>\n<span style=\"color: #0000FF\">bernard_date_is_ambiguous<\/span>(<span style=\"color: #19177C\">Date<\/span>) :- \n    <span style=\"color: #0000FF\">candidate_date<\/span>(<span style=\"color: #19177C\">Date<\/span>),\n    <span style=\"color: #0000FF\">date_is_ambiguous<\/span>(<span style=\"color: #19177C\">Date<\/span>).\n\n<span style=\"color: #408080; font-style: italic\">% After hearing what Albert said, <\/span>\n<span style=\"color: #408080; font-style: italic\">% Bernard&#39;s database is constrained by <\/span>\n<span style=\"color: #408080; font-style: italic\">% the results of albert_knows_bernard_doesnt_know<\/span>\n<span style=\"color: #0000FF\">bernard_constrained<\/span>(<span style=\"color: #19177C\">Mon<\/span>,<span style=\"color: #19177C\">Date<\/span>) :- \n    <span style=\"color: #0000FF\">bernard_date_is_ambiguous<\/span>(<span style=\"color: #19177C\">Date<\/span>),\n    <span style=\"color: #0000FF\">albert_knows_bernard_doesnt_know<\/span>(<span style=\"color: #19177C\">Mon<\/span>),\n    <span style=\"color: #0000FF\">birthday_candidate<\/span>(<span style=\"color: #19177C\">Mon<\/span>,<span style=\"color: #19177C\">Date<\/span>).\n\n<span style=\"color: #408080; font-style: italic\">% But then, Bernard said that he <\/span>\n<span style=\"color: #408080; font-style: italic\">% now knows the birthday; which means <\/span>\n<span style=\"color: #408080; font-style: italic\">% that Month isn&#39;t ambiguous for him<\/span>\n<span style=\"color: #0000FF\">bernard_now_knows<\/span>(<span style=\"color: #19177C\">Date<\/span>) :- \n    <span style=\"color: #0000FF\">setof<\/span>(<span style=\"color: #19177C\">M<\/span>, <span style=\"color: #0000FF\">bernard_constrained<\/span>(<span style=\"color: #19177C\">M<\/span>, <span style=\"color: #19177C\">Date<\/span>), <span style=\"color: #19177C\">Mx<\/span>),\n    <span style=\"color: #0000FF\">is_not_ambiguous<\/span>(<span style=\"color: #19177C\">Mx<\/span>).\n\n<span style=\"color: #408080; font-style: italic\">% Albert&#39;s second deduction<\/span>\n\n<span style=\"color: #408080; font-style: italic\">% After hearing that Bernard now knows <\/span>\n<span style=\"color: #408080; font-style: italic\">% the birthday, Albert&#39;s database is <\/span>\n<span style=\"color: #408080; font-style: italic\">% constrained by the results of bernard_now_knows<\/span>\n<span style=\"color: #0000FF\">albert_constrained<\/span>(<span style=\"color: #19177C\">Mon<\/span>,<span style=\"color: #19177C\">Date<\/span>) :- \n    <span style=\"color: #0000FF\">bernard_now_knows<\/span>(<span style=\"color: #19177C\">Date<\/span>),\n    <span style=\"color: #0000FF\">albert_knows_bernard_doesnt_know<\/span>(<span style=\"color: #19177C\">Mon<\/span>),\n    <span style=\"color: #0000FF\">birthday_candidate<\/span>(<span style=\"color: #19177C\">Mon<\/span>,<span style=\"color: #19177C\">Date<\/span>).\n\n<span style=\"color: #408080; font-style: italic\">% And Albert said that he now knows. <\/span>\n<span style=\"color: #408080; font-style: italic\">% Which means Month isn&#39;t ambiguous <\/span>\n<span style=\"color: #408080; font-style: italic\">% for him<\/span>\n<span style=\"color: #0000FF\">albert_now_knows<\/span>(<span style=\"color: #19177C\">Mon<\/span>) :- \n    <span style=\"color: #0000FF\">setof<\/span>(<span style=\"color: #19177C\">D<\/span>, <span style=\"color: #0000FF\">albert_constrained<\/span>(<span style=\"color: #19177C\">Mon<\/span>, <span style=\"color: #19177C\">D<\/span>), <span style=\"color: #19177C\">Dx<\/span>),\n    <span style=\"color: #0000FF\">is_not_ambiguous<\/span>(<span style=\"color: #19177C\">Dx<\/span>).\n\n\n<span style=\"color: #408080; font-style: italic\">% Final answer: take results of <\/span>\n<span style=\"color: #408080; font-style: italic\">% albert_constrained and further constrain it <\/span>\n<span style=\"color: #408080; font-style: italic\">% by the fact that albert_now_knows<\/span>\n<span style=\"color: #408080; font-style: italic\">% and we get a single final answer.<\/span>\n<span style=\"color: #0000FF\">final_answer<\/span>(<span style=\"color: #19177C\">Mon<\/span>,<span style=\"color: #19177C\">Date<\/span>) :- \n    <span style=\"color: #0000FF\">albert_constrained<\/span>(<span style=\"color: #19177C\">Mon<\/span>, <span style=\"color: #19177C\">Date<\/span>),\n    <span style=\"color: #0000FF\">albert_now_knows<\/span>(<span style=\"color: #19177C\">Mon<\/span>).\n<\/pre>\n<\/div>\n<p><\/font><\/p>\n<h3>Notes<\/h3>\n<ul>\n<li>The answer is 16 July, in case you were wondering.<\/li>\n<li>Considering that this is probably the second Prolog program that I&#8217;ve ever written, I&#8217;m sure it is a terrible program. In fact there are lots of ways in which the program can be improved, but, I have real work to do. So this quick-n-dirty program will have to do.<\/li>\n<li>In fact, there exist theorem provers (like <a href=\"https:\/\/coq.inria.fr\/\">Coq<\/a>) that are even more ideal for this job. But those are far too specialized, and I did not want to learn a theorem prover just to solve this problem.<\/li>\n<li>Which brings me to the question, why did I even bother doing this in Prolog? Considering that Prolog has not been, and will probably never be used in any serious programming work that I do, why bother? The more generalized version of this question is this: if there is a non-standard programming language (like Haskell, Lisp, Erlang, O&#8217;Caml) whose use in industry is uncommon, should you, as a serious programmer, with real work to be done and real deadlines, learn them in your free time? The motivated reader is encouraged to leave a comment below with the answer. Or, if you don&#8217;t know the answer and want my answer, please <a href=\"mailto:navin@smriti.com\">send me an email<\/a>.<\/li>\n<\/ul>\n<p>And, <a href=\"http:\/\/www.nytimes.com\/2015\/04\/15\/science\/a-math-problem-from-singapore-goes-viral-when-is-cheryls-birthday.html\">here&#8217;s a link to the original problem<\/a> if you feel like solving it yourself. And here is <a href=\"http:\/\/en.wikipedia.org\/wiki\/Impossible_Puzzle\">another problem<\/a> and <a href=\"http:\/\/rec-puzzles.org\/index.php\/Same%20Street\">yetanudder problem<\/a> that require similar type of thinking to solve.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Being a programmer means that every once in a while, instead of doing real work, you spend time writing a completely pointless program just for fun. Which is how I ended up writing a Prolog program to solve the Singapore Math Problem that has recently gone viral on the internet. This is Amit Paranjape&#8216;s fault. &hellip; <a href=\"https:\/\/smritiweb.com\/navin\/technology\/which-programming-language-to-use-to-solve-the-singapore-math-problem\" class=\"more-link\">Continue reading <span class=\"screen-reader-text\">Which Programming Language to use to solve the Singapore Math problem<\/span><\/a><\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_monsterinsights_skip_tracking":false,"_monsterinsights_sitenote_active":false,"_monsterinsights_sitenote_note":"","_monsterinsights_sitenote_category":0},"categories":[7],"tags":[92,184,88],"_links":{"self":[{"href":"https:\/\/smritiweb.com\/navin\/wp-json\/wp\/v2\/posts\/693"}],"collection":[{"href":"https:\/\/smritiweb.com\/navin\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/smritiweb.com\/navin\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/smritiweb.com\/navin\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/smritiweb.com\/navin\/wp-json\/wp\/v2\/comments?post=693"}],"version-history":[{"count":8,"href":"https:\/\/smritiweb.com\/navin\/wp-json\/wp\/v2\/posts\/693\/revisions"}],"predecessor-version":[{"id":701,"href":"https:\/\/smritiweb.com\/navin\/wp-json\/wp\/v2\/posts\/693\/revisions\/701"}],"wp:attachment":[{"href":"https:\/\/smritiweb.com\/navin\/wp-json\/wp\/v2\/media?parent=693"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/smritiweb.com\/navin\/wp-json\/wp\/v2\/categories?post=693"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/smritiweb.com\/navin\/wp-json\/wp\/v2\/tags?post=693"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}