{"id":214,"date":"2010-06-19T19:36:59","date_gmt":"2010-06-20T00:36:59","guid":{"rendered":"http:\/\/factormystic.net\/blog\/?p=214"},"modified":"2010-06-19T19:36:59","modified_gmt":"2010-06-20T00:36:59","slug":"project-euler-in-fsharp-problem-1","status":"publish","type":"post","link":"https:\/\/factormystic.net\/blog\/project-euler-in-fsharp-problem-1","title":{"rendered":"Project Euler in F#: Problem 1"},"content":{"rendered":"<h2>About Project Euler<\/h2>\n<p>I&#8217;ve wanted to take a crack at Project Euler for some time now. If you&#8217;re not\u00a0familiar, it&#8217;s basically a list of mathematical problems. From the site:<\/p>\n<blockquote><p>Project Euler is a series of challenging mathematical\/computer programming problems that will require more than just mathematical insights to solve. Although mathematics will help you arrive at elegant and efficient methods, the use of a computer and programming skills will be required to solve most problems.<\/p>\n<p>The motivation for starting Project Euler, and its continuation, is to provide a platform for the inquiring mind to delve into unfamiliar areas and learn new concepts in a fun and recreational context.<\/p><\/blockquote>\n<p>And they <a href=\"http:\/\/projecteuler.net\/index.php?section=scores\">keep score<\/a>! In\u00a0addition, I&#8217;ve also been looking for an excuse to learn F#. In truth, I&#8217;ve wanted to get down and dirty with some functional language, to learn the principles and hopefully become a better programmer. I chose F#\u00a0because\u00a0it&#8217;s part of Visual Studio (starting with 2010), and I&#8217;m already handy with .NET, so in theory that will lower the barrier to entry just a little bit. At the very least, it allows me to dodge the hassle of installing another interpreter or\u00a0environment\u00a0on my system.<\/p>\n<h2>Blogging It<\/h2>\n<p>As I continue though Project Euler, I&#8217;ll be posting my solutions here on my site under <a href=\"http:\/\/factormystic.net\/projects\/code\">http:\/\/factormystic.net\/projects\/code<\/a>, and you can also check my progress by looking at my <a href=\"http:\/\/projecteuler.net\/index.php?section=profile&amp;profile=factormystic\">Project Euler profile<\/a> and I look forward to your mocking laughter\u00a0gentle guidance as I fumble around in F#.<\/p>\n<h2>On to Problem 1<\/h2>\n<blockquote><p>If we list all the natural numbers below 10 that are multiples of 3 or 5, we get 3, 5, 6 and 9. The sum of these multiples is 23.<br \/>\nFind the sum of all the multiples of 3 or 5 below 1000.<\/p><\/blockquote>\n<p>Straightforward enough, and easy to form a mental model around the problem. But how to implement this in F#? For a quick language primer, I skimmed <a href=\"http:\/\/msdn.microsoft.com\/en-us\/magazine\/ee336127.aspx\">An Introduction to Functional Programming for .NET Developers<\/a> and noticed a few things I might need:<\/p>\n<ul>\n<li>An add function<br \/>\n<span style=\"font-family: Consolas, Monaco, 'Courier New', Courier, monospace; line-height: 18px; font-size: 12px; white-space: pre;\">let add x y = x + y<br \/>\n<\/span><\/li>\n<li>Sequence syntax and list comprehension<br \/>\n<span style=\"font-family: Consolas, Monaco, 'Courier New', Courier, monospace; line-height: 18px; font-size: 12px; white-space: pre;\">let numbers = {0..10}<br \/>\n<\/span><\/li>\n<li>Modulo and ternary operators<br \/>\n<span style=\"font-family: Consolas, Monaco, 'Courier New', Courier, monospace; line-height: 18px; font-size: 12px; white-space: pre;\">string result = x % 2 == 0 ? &#8220;yes&#8221; : &#8220;no&#8221;;<\/span><\/li>\n<\/ul>\n<h2>The Thinking<\/h2>\n<p>The thinking is this: sequences could be used to build a list of integers 1 to 1000; I could use modulo to get multiples of 3 and 5 (<a href=\"http:\/\/imranontech.com\/2007\/01\/24\/using-fizzbuzz-to-find-developers-who-grok-coding\/\">think <\/a><a href=\"http:\/\/dotnetpad.net\/FizzBuzz\/\">FizzBuzz<\/a>), and somehow use that add function to get the sum. Reading the documentation for <a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/dd233209.aspx\">sequence expressions<\/a> turned out to be quite rewarding (!), as you can embed a filter on a sequence when you\u00a0declare\u00a0it:<\/p>\n<p>[sourcecode]let multiples = seq { for i in 1 .. 1000 do if i % 3 = 0 || i % 5 = 0 then yield i }[\/sourcecode]<\/p>\n<p>Yield is already a familiar concept from C#, from using Enumerables. In fact, from the documentation:<\/p>\n<blockquote><p>Sequences are represented by the\u00a0seq&lt;&#8216;T&gt;\u00a0type, which is an alias for IEnumerable&lt;T&gt;. Therefore, any .NET Framework type that implements\u00a0System.IEnumerable can be used as a sequence. The\u00a0Seq module provides support for manipulations involving sequences.<\/p><\/blockquote>\n<p>Thus our F# is roughly analogous to something like<br \/>\n[sourcecode]public static IEnumerable GiveMults()<br \/>\n{<br \/>\nforeach (int i in Enumerable.Range(1, 1000))<br \/>\nif (i % 3 == 0 || i % 5 == 0)<br \/>\nyield return i;<br \/>\n}[\/sourcecode]<\/p>\n<p>Now that we have our sequence of natural numbers, let&#8217;s figure out how to sum them up. I have the add function I grabbed from the article, and while poking around with the Seq module, I noticed a reduce function, which can apply an accumulator. That would give us<\/p>\n<p>[sourcecode]<br \/>\nlet multiples = seq { for i in 1 .. 1000 do if i % 3 = 0 || i % 5 = 0 then yield i }<br \/>\nlet add x y = x + y<br \/>\nlet result= Seq.reduce add multiples<br \/>\nprintfn &#8220;%A&#8221; result<br \/>\n[\/sourcecode]<br \/>\n(Side note: <a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/ee370560.aspx\">printfn<\/a> is how we can write to stdout, much like Console.Writeline. The &#8220;%A&#8221; stuff works like string.Format parameters- %A indicates &#8220;Formats any value, printed with the default layout settings.&#8221; In the case of a sequence, that means printing the first few values)<\/p>\n<p>&#8230;and that code does indeed sum the multiples, as you would expect. But there is a better way. After all, we should expect something as simple as adding up a list to be built in already, and we do have our Seq module functions available.<\/p>\n<p>Indeed, there is a Seq.sum function that does exactly what we&#8217;re seeking to do, sum a sequence. Rewritten, we have:<br \/>\n[sourcecode]<br \/>\nlet result\u00a0= seq { for i in 1 .. 1000 do if i % 3 = 0 || i % 5 = 0 then yield i }<br \/>\nlet total = Seq.sum result<br \/>\nprintfn &#8220;%A&#8221; total<br \/>\n[\/sourcecode]<br \/>\nAnd this prints an answer, but that answer is WRONG. See the bug? The original problem stated that we&#8217;re to &#8220;sum of all the multiples of 3 or 5 <strong>below<\/strong> 1000&#8243;, but the list comprehension syntax (1..1000) is <strong>inclusive<\/strong>. Thus, our answer includes 1000, which is evenly divisible by 5, and is summed into the final total. The fix is simple, just write 1..999:<\/p>\n<h2>My Solution<\/h2>\n<p>[sourcecode]<br \/>\nlet multiples = seq { for i in 1 .. 999 do if i % 3 = 0 || i % 5 = 0 then yield i }<br \/>\nlet result = Seq.sum multiples<br \/>\nprintfn &#8220;%A&#8221; result<br \/>\n[\/sourcecode]<\/p>\n<p>Bingo.<br \/>\nProject Euler Problem 1: <strong>Answered<\/strong><\/p>\n<h2>Further Reading<\/h2>\n<ul>\n<li><a href=\"http:\/\/msdn.microsoft.com\/en-us\/magazine\/ee336127.aspx\">An Introduction to Functional Programming for .NET Developers<\/a><\/li>\n<li><a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/dd233209.aspx\">Sequences<\/a><\/li>\n<li><a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/ee370560.aspx\">Core.Printf Module<\/a><\/li>\n<\/ul>\n<h2>A Post Script<\/h2>\n<p>For the code golf crew:<br \/>\n[sourcecode]printfn &#8220;%A&#8221; (Seq.sum (seq { for i in 1 .. 999 do if i % 3 = 0 || i % 5 = 0 then yield i }))[\/sourcecode]<\/p>\n","protected":false},"excerpt":{"rendered":"<p>About Project Euler I&#8217;ve wanted to take a crack at Project Euler for some time now. If you&#8217;re not\u00a0familiar, it&#8217;s basically a list of mathematical problems. From the site: Project Euler is a series of challenging mathematical\/computer programming problems that will require more than just mathematical insights to solve. Although mathematics will help you arrive [&hellip;]<\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[26,25],"tags":[],"class_list":["post-214","post","type-post","status-publish","format-standard","hentry","category-f-sharp","category-project-euler"],"_links":{"self":[{"href":"https:\/\/factormystic.net\/blog\/wp-json\/wp\/v2\/posts\/214","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/factormystic.net\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/factormystic.net\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/factormystic.net\/blog\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/factormystic.net\/blog\/wp-json\/wp\/v2\/comments?post=214"}],"version-history":[{"count":29,"href":"https:\/\/factormystic.net\/blog\/wp-json\/wp\/v2\/posts\/214\/revisions"}],"predecessor-version":[{"id":262,"href":"https:\/\/factormystic.net\/blog\/wp-json\/wp\/v2\/posts\/214\/revisions\/262"}],"wp:attachment":[{"href":"https:\/\/factormystic.net\/blog\/wp-json\/wp\/v2\/media?parent=214"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/factormystic.net\/blog\/wp-json\/wp\/v2\/categories?post=214"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/factormystic.net\/blog\/wp-json\/wp\/v2\/tags?post=214"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}