<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Stefano Ricciardi &#187; algorithm</title>
	<atom:link href="http://stefanoricciardi.com/tag/algorithm/feed/" rel="self" type="application/rss+xml" />
	<link>http://stefanoricciardi.com</link>
	<description>On Software Development and Thereabouts</description>
	<lastBuildDate>Thu, 02 Sep 2010 15:01:11 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.1</generator>
		<item>
		<title>Project Euler Problem 9 in F#</title>
		<link>http://stefanoricciardi.com/2010/08/25/project-euler-problem-9-in-f/</link>
		<comments>http://stefanoricciardi.com/2010/08/25/project-euler-problem-9-in-f/#comments</comments>
		<pubDate>Wed, 25 Aug 2010 15:33:02 +0000</pubDate>
		<dc:creator>stefanoricciardi</dc:creator>
				<category><![CDATA[.NET]]></category>
		<category><![CDATA[F#]]></category>
		<category><![CDATA[algorithm]]></category>
		<category><![CDATA[Euler Problems]]></category>
		<category><![CDATA[functional]]></category>

		<guid isPermaLink="false">http://stefanoricciardi.com/?p=1079</guid>
		<description><![CDATA[Project Euler Problem 9 introduces the interesting mathematical concept of Pythagorean Triple. Let&#8217;s have a look at the question: A Pythagorean triplet is a set of three natural numbers, a &#60; b &#60; c, for which, a&#178; + b&#178; = c&#178; For example, 3&#178; + 4&#178; = 9 + 16 = 25 = 5&#178;. There [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fstefanoricciardi.com%2F2010%2F08%2F25%2Fproject-euler-problem-9-in-f%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fstefanoricciardi.com%2F2010%2F08%2F25%2Fproject-euler-problem-9-in-f%2F&amp;style=normal" height="61" width="50" /><br />
			</a>
		</div>
<p><a href="http://projecteuler.net/index.php?section=problems&#038;id=9">Project Euler Problem 9</a> introduces the interesting mathematical concept of <a href="http://en.wikipedia.org/wiki/Pythagorean_triple">Pythagorean Triple</a>.  Let&#8217;s have a look at the question:</p>
<blockquote><p>
A Pythagorean triplet is a set of three natural numbers, a &lt; b &lt; c, for which,<br />
a&sup2; + b&sup2; = c&sup2;</p>
<p>For example, 3&sup2; + 4&sup2; = 9 + 16 = 25 = 5&sup2;.</p>
<p>There exists exactly one Pythagorean triplet for which a + b + c = 1000.<br />
Find the product abc.
</p></blockquote>
<p>As usual, I first show my solution and then comment on the approach:</p>
<pre class="brush:fsharp">
#light

// generate triplets using Euclid's Formula
let pythagorean_triplets top =
    [ for m in 1 .. top do
          for n in 1 .. m-1 do
          let a = m*m-n*n
          let b = 2*m*n
          let c = m*m+n*n
          yield [a;b;c] ]

// multiply all the values of a list
let multiply_list list =
    List.fold (fun acc elem -&gt; acc*elem) 1 list

// find a triplet where the sum of values
// is equal to a given number
let find_triplet_with_sum sum =
    pythagorean_triplets sum
    |&gt; List.find (fun [a;b;c] -&gt; a+b+c=sum)

let problem_9 () =
    find_triplet_with_sum 1000
    |&gt; multiply_list
</pre>
<p>Let&#8217;s go through the solution step by step:</p>
<ul>
<li>The first function, <code>pythagorean_triplets</code> uses <a href="http://en.wikipedia.org/wiki/Pythagorean_triple#Generating_a_triple">Euclid&#8217;s Formula</a> to enumerate all possible Pytagorean Triplets up to a given threshold. The formula can be summarized like this:<br />
<cite>a = m&sup2; &#8211; n&sup2;, b = 2mn, c = m&sup2; + n&sup2;,  where m and n are positive integers with m &gt; n.</cite></p>
<p>It&#8217;s interesting to note that each item of the list is itself a <em>list</em> of three numbers. I could have generated a tuple, but since in the end I need to multiply all the 3 values together, the list was more straightfoward to use.
</li>
<li><code>multiply_list</code> is just a convenience function to multiply all the elements of a list together</li>
<li><code>find_triplet_with_sum</code> does the heavy work of generating the actual triplets picking the first one where the sum is equal to a given value.</li>
<li> At the end I just put the pieces together and solve the problem. </li>
</ul>
<p>One caveat: Euclid&#8217;s Formula does not generate <em>all</em> Pytagorean Triplets(there are other formulas that do). I can say that I have been lucky that it generated the one requested by the Project&#8217;s Euler problem. The code above might not work if the goal is changed to find a triplet with a different product.</p>
<p><a href="../../tag/euler-problems/">See all  Project Euler problems solutions</a>.</p>
<p><a href="http://www.dotnetkicks.com/kick/?url=http://stefanoricciardi.com/2010/08/25/project-euler-problem-9-in-f/"><img src="http://www.dotnetkicks.com/Services/Images/KickItImageGenerator.ashx?url=http://stefanoricciardi.com/2010/08/25/project-euler-problem-9-in-f/" border="0" alt="kick it on DotNetKicks.com" /></a></p>
<p><a rev="vote-for" href="http://dotnetshoutout.com/Project-Euler-Problem-9-in-F-Stefano-Ricciardi"><img alt="Shout it" src="http://dotnetshoutout.com/image.axd?url=http%3A%2F%2Fstefanoricciardi.com%2F2010%2F08%2F25%2Fproject-euler-problem-9-in-f%2F" style="border:0px"/></a></p>
]]></content:encoded>
			<wfw:commentRss>http://stefanoricciardi.com/2010/08/25/project-euler-problem-9-in-f/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Project Euler Problem 8 in F#</title>
		<link>http://stefanoricciardi.com/2010/08/17/project-euler-problem-8-in-f/</link>
		<comments>http://stefanoricciardi.com/2010/08/17/project-euler-problem-8-in-f/#comments</comments>
		<pubDate>Tue, 17 Aug 2010 21:04:43 +0000</pubDate>
		<dc:creator>stefanoricciardi</dc:creator>
				<category><![CDATA[.NET]]></category>
		<category><![CDATA[F#]]></category>
		<category><![CDATA[algorithm]]></category>
		<category><![CDATA[Euler Problems]]></category>
		<category><![CDATA[functional]]></category>

		<guid isPermaLink="false">http://stefanoricciardi.com/?p=1044</guid>
		<description><![CDATA[After two easy problems, it&#8217;s now time for Problem 8. At first, this problem also seemed to me more complex than it really is. Let&#8217;s have a look at the question: Find the greatest product of five consecutive digits in the 1000-digit number. 73167176531330624919225119674426574742355349194934 96983520312774506326239578318016984801869478851843 85861560789112949495459501737958331952853208805511 12540698747158523863050715693290963295227443043557 66896648950445244523161731856403098711121722383113 62229893423380308135336276614282806444486645238749 30358907296290491560440772390713810515859307960866 70172427121883998797908792274921901699720888093776 65727333001053367881220235421809751254540594752243 52584907711670556013604839586446706324415722155397 53697817977846174064955149290862569321978468622482 83972241375657056057490261407972968652414535100474 [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fstefanoricciardi.com%2F2010%2F08%2F17%2Fproject-euler-problem-8-in-f%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fstefanoricciardi.com%2F2010%2F08%2F17%2Fproject-euler-problem-8-in-f%2F&amp;style=normal" height="61" width="50" /><br />
			</a>
		</div>
<p>After <a href="http://stefanoricciardi.com/2010/08/16/project-euler-problem-6-and-7-in-f/">two easy problems</a>, it&#8217;s now time for Problem 8. </p>
<p>At first, this problem also seemed to me more complex than it really is.  Let&#8217;s have a look at the question:</p>
<blockquote><p>
Find the greatest product of five consecutive digits in the 1000-digit number.</p>
<p>73167176531330624919225119674426574742355349194934<br />
96983520312774506326239578318016984801869478851843<br />
85861560789112949495459501737958331952853208805511<br />
12540698747158523863050715693290963295227443043557<br />
66896648950445244523161731856403098711121722383113<br />
62229893423380308135336276614282806444486645238749<br />
30358907296290491560440772390713810515859307960866<br />
70172427121883998797908792274921901699720888093776<br />
65727333001053367881220235421809751254540594752243<br />
52584907711670556013604839586446706324415722155397<br />
53697817977846174064955149290862569321978468622482<br />
83972241375657056057490261407972968652414535100474<br />
82166370484403199890008895243450658541227588666881<br />
16427171479924442928230863465674813919123162824586<br />
17866458359124566529476545682848912883142607690042<br />
24219022671055626321111109370544217506941658960408<br />
07198403850962455444362981230987879927244284909188<br />
84580156166097919133875499200524063689912560717606<br />
05886116467109405077541002256983155200055935729725<br />
71636269561882670428252483600823257530420752963450
</p></blockquote>
<p>So, basically what we need to do is: </p>
<ul>
<li>consider all chunks of this list of numbers that can be created by taking 5 consecutive digits from the beginning till the end (there will be <em>n-5</em> chunks if <em>n</em> is the number of digits in the list)</li>
<li>for each chunk, multiply all the digits together (that&#8217;s <em>n-1</em> products per chunk)</li>
<li>pick the value corresponding to the greatest product.</li>
</ul>
<p>At first I have considered resolving an easier problem first, like: find the chunk whose <em>sum</em> is bigger and then calculate that product. Assuming that sum is cheaper to calculate than product (and it is), we would have had <em>(n-5) * (n-1)</em> sums and just 1 product. However you can easily find examples where the sum of the digits is the same while the product is different: e.g. <em>4 + 5 = 7 + 2 = 9</em> but <em>4 * 5 = 20 > 7 * 2 = 14</em>. Therefore that was a dead end.</p>
<p>A more mathematically sound approach to find the chunk giving the highest product might have been to first locate the chunk with the highest sum of <em>logarithms</em> of each digit and then calculate the corresponding product. However, a quick test revealed that logarithm is <em>way</em> slower than product.</p>
<p>Finally, a couple of micro-optimizations that occurred to me.</p>
<ul>
<li>You can skip all chunks containing at least one 0 (trivially, the product will be zero)</li>
<li>You don&#8217;t really have to multiply all the digits for each chunk (that is <em>(n-5) * (n-1)</em> products): once you have computed the product of the first chunk, the product of the next chunk would be the product of the previous chunk <em>times</em> the sixth digit <em>divided</em> by the first digit, and so on for subsequent chunks.
</ul>
<p>Eventually, I did not try to implement these two things, since brute force, which I am about to show you, is so quick that it&#8217;s wasn&#8217;t really worth it:</p>
<pre class="brush:fsharp">
#light

let digits = [| 7; 3; 1; 6; 7; 1; 7; 6; 5; 3; 1; 3; 3; 0; 6; 2; 4; 9;
    1; 9; 2; 2; 5; 1; 1; 9; 6; 7; 4; 4; 2; 6; 5; 7; 4; 7; 4; 2; 3; 5;
    5; 3; 4; 9; 1; 9; 4; 9; 3; 4; 9; 6; 9; 8; 3; 5; 2; 0; 3; 1; 2; 7;
    7; 4; 5; 0; 6; 3; 2; 6; 2; 3; 9; 5; 7; 8; 3; 1; 8; 0; 1; 6; 9; 8;
    4; 8; 0; 1; 8; 6; 9; 4; 7; 8; 8; 5; 1; 8; 4; 3; 8; 5; 8; 6; 1; 5;
    6; 0; 7; 8; 9; 1; 1; 2; 9; 4; 9; 4; 9; 5; 4; 5; 9; 5; 0; 1; 7; 3;
    7; 9; 5; 8; 3; 3; 1; 9; 5; 2; 8; 5; 3; 2; 0; 8; 8; 0; 5; 5; 1; 1;
    1; 2; 5; 4; 0; 6; 9; 8; 7; 4; 7; 1; 5; 8; 5; 2; 3; 8; 6; 3; 0; 5;
    0; 7; 1; 5; 6; 9; 3; 2; 9; 0; 9; 6; 3; 2; 9; 5; 2; 2; 7; 4; 4; 3;
    0; 4; 3; 5; 5; 7; 6; 6; 8; 9; 6; 6; 4; 8; 9; 5; 0; 4; 4; 5; 2; 4;
    4; 5; 2; 3; 1; 6; 1; 7; 3; 1; 8; 5; 6; 4; 0; 3; 0; 9; 8; 7; 1; 1;
    1; 2; 1; 7; 2; 2; 3; 8; 3; 1; 1; 3; 6; 2; 2; 2; 9; 8; 9; 3; 4; 2;
    3; 3; 8; 0; 3; 0; 8; 1; 3; 5; 3; 3; 6; 2; 7; 6; 6; 1; 4; 2; 8; 2;
    8; 0; 6; 4; 4; 4; 4; 8; 6; 6; 4; 5; 2; 3; 8; 7; 4; 9; 3; 0; 3; 5;
    8; 9; 0; 7; 2; 9; 6; 2; 9; 0; 4; 9; 1; 5; 6; 0; 4; 4; 0; 7; 7; 2;
    3; 9; 0; 7; 1; 3; 8; 1; 0; 5; 1; 5; 8; 5; 9; 3; 0; 7; 9; 6; 0; 8;
    6; 6; 7; 0; 1; 7; 2; 4; 2; 7; 1; 2; 1; 8; 8; 3; 9; 9; 8; 7; 9; 7;
    9; 0; 8; 7; 9; 2; 2; 7; 4; 9; 2; 1; 9; 0; 1; 6; 9; 9; 7; 2; 0; 8;
    8; 8; 0; 9; 3; 7; 7; 6; 6; 5; 7; 2; 7; 3; 3; 3; 0; 0; 1; 0; 5; 3;
    3; 6; 7; 8; 8; 1; 2; 2; 0; 2; 3; 5; 4; 2; 1; 8; 0; 9; 7; 5; 1; 2;
    5; 4; 5; 4; 0; 5; 9; 4; 7; 5; 2; 2; 4; 3; 5; 2; 5; 8; 4; 9; 0; 7;
    7; 1; 1; 6; 7; 0; 5; 5; 6; 0; 1; 3; 6; 0; 4; 8; 3; 9; 5; 8; 6; 4;
    4; 6; 7; 0; 6; 3; 2; 4; 4; 1; 5; 7; 2; 2; 1; 5; 5; 3; 9; 7; 5; 3;
    6; 9; 7; 8; 1; 7; 9; 7; 7; 8; 4; 6; 1; 7; 4; 0; 6; 4; 9; 5; 5; 1;
    4; 9; 2; 9; 0; 8; 6; 2; 5; 6; 9; 3; 2; 1; 9; 7; 8; 4; 6; 8; 6; 2;
    2; 4; 8; 2; 8; 3; 9; 7; 2; 2; 4; 1; 3; 7; 5; 6; 5; 7; 0; 5; 6; 0;
    5; 7; 4; 9; 0; 2; 6; 1; 4; 0; 7; 9; 7; 2; 9; 6; 8; 6; 5; 2; 4; 1;
    4; 5; 3; 5; 1; 0; 0; 4; 7; 4; 8; 2; 1; 6; 6; 3; 7; 0; 4; 8; 4; 4;
    0; 3; 1; 9; 9; 8; 9; 0; 0; 0; 8; 8; 9; 5; 2; 4; 3; 4; 5; 0; 6; 5;
    8; 5; 4; 1; 2; 2; 7; 5; 8; 8; 6; 6; 6; 8; 8; 1; 1; 6; 4; 2; 7; 1;
    7; 1; 4; 7; 9; 9; 2; 4; 4; 4; 2; 9; 2; 8; 2; 3; 0; 8; 6; 3; 4; 6;
    5; 6; 7; 4; 8; 1; 3; 9; 1; 9; 1; 2; 3; 1; 6; 2; 8; 2; 4; 5; 8; 6;
    1; 7; 8; 6; 6; 4; 5; 8; 3; 5; 9; 1; 2; 4; 5; 6; 6; 5; 2; 9; 4; 7;
    6; 5; 4; 5; 6; 8; 2; 8; 4; 8; 9; 1; 2; 8; 8; 3; 1; 4; 2; 6; 0; 7;
    6; 9; 0; 0; 4; 2; 2; 4; 2; 1; 9; 0; 2; 2; 6; 7; 1; 0; 5; 5; 6; 2;
    6; 3; 2; 1; 1; 1; 1; 1; 0; 9; 3; 7; 0; 5; 4; 4; 2; 1; 7; 5; 0; 6;
    9; 4; 1; 6; 5; 8; 9; 6; 0; 4; 0; 8; 0; 7; 1; 9; 8; 4; 0; 3; 8; 5;
    0; 9; 6; 2; 4; 5; 5; 4; 4; 4; 3; 6; 2; 9; 8; 1; 2; 3; 0; 9; 8; 7;
    8; 7; 9; 9; 2; 7; 2; 4; 4; 2; 8; 4; 9; 0; 9; 1; 8; 8; 8; 4; 5; 8;
    0; 1; 5; 6; 1; 6; 6; 0; 9; 7; 9; 1; 9; 1; 3; 3; 8; 7; 5; 4; 9; 9;
    2; 0; 0; 5; 2; 4; 0; 6; 3; 6; 8; 9; 9; 1; 2; 5; 6; 0; 7; 1; 7; 6;
    0; 6; 0; 5; 8; 8; 6; 1; 1; 6; 4; 6; 7; 1; 0; 9; 4; 0; 5; 0; 7; 7;
    5; 4; 1; 0; 0; 2; 2; 5; 6; 9; 8; 3; 1; 5; 5; 2; 0; 0; 0; 5; 5; 9;
    3; 5; 7; 2; 9; 7; 2; 5; 7; 1; 6; 3; 6; 2; 6; 9; 5; 6; 1; 8; 8; 2;
    6; 7; 0; 4; 2; 8; 2; 5; 2; 4; 8; 3; 6; 0; 0; 8; 2; 3; 2; 5; 7; 5;
    3; 0; 4; 2; 0; 7; 5; 2; 9; 6; 3; 4; 5; 0|]

let calculate_max_chunk_product chunk_size =
    seq {
        for i in 0 .. (Array.length digits - chunk_size) do
            let chunk = Array.sub digits i chunk_size
            yield Array.fold (fun acc elem -> acc * elem) 1 chunk
        }
    |> Seq.max

let problem_8 () =
    calculate_max_chunk_product 5
</pre>
<p>As you can see, we are generating a sequence of products and then pick the maximum value. Each product is created by first taking a chunk of the array (using the <code>Array.sub</code>) and then using <code>Array.fold</code> to compute the product of all elements in the chunk.</p>
<p>Again, I have tried to keep the imperative part to a minimum and I was able to get by without using any mutable variable.</p>
<p><a href="../../tag/euler-problems/">See all  Project Euler problems solutions</a>.</p>
<p><a href="http://www.dotnetkicks.com/kick/?url=http://stefanoricciardi.com/2010/08/17/project-euler-problem-8-in-f/"><img src="http://www.dotnetkicks.com/Services/Images/KickItImageGenerator.ashx?url=http://stefanoricciardi.com/2010/08/17/project-euler-problem-8-in-f/" border="0" alt="kick it on DotNetKicks.com" /></a> </p>
<p><a rev="vote-for" href="http://dotnetshoutout.com/Project-Euler-Problem-8-in-F-Stefano-Ricciardi"><img alt="Shout it" src="http://dotnetshoutout.com/image.axd?url=http%3A%2F%2Fstefanoricciardi.com%2F2010%2F08%2F17%2Fproject-euler-problem-8-in-f%2F" style="border:0px"/></a></p>
]]></content:encoded>
			<wfw:commentRss>http://stefanoricciardi.com/2010/08/17/project-euler-problem-8-in-f/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Project Euler Problem 6 and 7 in F#</title>
		<link>http://stefanoricciardi.com/2010/08/16/project-euler-problem-6-and-7-in-f/</link>
		<comments>http://stefanoricciardi.com/2010/08/16/project-euler-problem-6-and-7-in-f/#comments</comments>
		<pubDate>Mon, 16 Aug 2010 07:03:10 +0000</pubDate>
		<dc:creator>stefanoricciardi</dc:creator>
				<category><![CDATA[.NET]]></category>
		<category><![CDATA[F#]]></category>
		<category><![CDATA[algorithm]]></category>
		<category><![CDATA[Euler Problems]]></category>
		<category><![CDATA[functional]]></category>

		<guid isPermaLink="false">http://stefanoricciardi.com/?p=1018</guid>
		<description><![CDATA[Project Euler problem 6 is one of the easiest that I have encountered so far. Also, Problem 7 is quite easy to solve once you have a function for prime numbers (something we did in Problem 3). Therefore, in this post I give 2 problems for the price of 1! Problem 6 Let&#8217;s have a [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fstefanoricciardi.com%2F2010%2F08%2F16%2Fproject-euler-problem-6-and-7-in-f%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fstefanoricciardi.com%2F2010%2F08%2F16%2Fproject-euler-problem-6-and-7-in-f%2F&amp;style=normal" height="61" width="50" /><br />
			</a>
		</div>
<p>Project Euler problem 6 is one of the easiest that I have encountered so far. Also, Problem 7 is quite easy to solve once you have a function for prime numbers (something we did in <a href="http://stefanoricciardi.com/2010/07/01/project-euler-problem-3-in-f/">Problem 3</a>). Therefore, in this post I give 2 problems for the price of 1! <img src='http://stefanoricciardi.com/blog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<h2>Problem 6</h2>
<p>Let&#8217;s have a look at the question for Problem 6:</p>
<blockquote><p>
The sum of the squares of the first ten natural numbers is,</p>
<p>1&sup2; + 2&sup2; + &#8230; + 10&sup2; = 385<br />
The square of the sum of the first ten natural numbers is,</p>
<p>(1 + 2 + &#8230; + 10)&sup2; = 55&sup2; = 3025</p>
<p>Hence the difference between the sum of the squares of the first ten natural numbers and the square of the sum is 3025 &#8211; 385 = 2640.</p>
<p>Find the difference between the sum of the squares of the first one hundred natural numbers and the square of the sum.
</p></blockquote>
<p>There are a few tricks to calculate the sum of the squares (see for example <a href="http://">here</a>). However, given the limited size of the problem at hand, brute-force is perfectly fine: it shows once more the elegance of a declarative solution.</p>
<pre class="brush: fsharp">
#light
open System

let square x = x * x

// a&sup2; + b&sup2;  + ... + z&sup2;
let sum_of_square max =
    Seq.unfold (fun x -> if x > max then None else Some(x*x, x+1)) 1
    |> Seq.sum

// (a +b + ... + z)&sup2;
let square_of_sum max =
    {1 .. max}
    |> Seq.sum
    |> square

let problem_6 max =
    square_of_sum(max) - sum_of_square(max)
</pre>
<h2>Problem 7</h2>
<blockquote><p>
By listing the first six prime numbers: 2, 3, 5, 7, 11, and 13, we can see that the 6th prime is 13.</p>
<p>What is the 10001st prime number?
</p></blockquote>
<p>As I mentioned in the introduction, this one is fairly easy once you know how to tell whether a given number is prime or not. We did that exercise in <a href="http://stefanoricciardi.com/2010/07/01/project-euler-problem-3-in-f/">Problem 3</a>. </p>
<p>There&#8217;s a catch though: this time we are <i>counting</i> the prime numbers. In the test we did in <a href="http://stefanoricciardi.com/2010/07/01/project-euler-problem-3-in-f/">Problem 3</a> there was a small error that in that context was irrelevant: the test returned <code>true</code> also for 0 and 1, which strictly speaking are not prime numbers (2 is considered to be the first prime number).</p>
<p>For this reason, I have modified the code of <code>is_prime</code> a bit so that the first prime will be 2, the second 3, and so on as appropriate.</p>
<pre class="brush: fsharp">
#light
open System

let is_prime x =
    let rec check i =
        x &gt; 1L &amp;&amp;
       (double i &gt; sqrt (double x) || (x % i &lt;&gt; 0L &#038;&#038; check (i + 1L)))
    check 2L                 

let sequence_of_first_n_primes n =
    Seq.initInfinite (fun x -&gt; int64 x)
    |&gt; Seq.filter is_prime
    |&gt; Seq.take n
    |&gt; Seq.max
</pre>
<p>Ok&#8230; break time is over. <a href="http://projecteuler.net/index.php?section=problems&#038;id=8">Problem 8</a> looks a bit more challenging. See you when I have got a nice solution for that.</p>
<p><a href="../../tag/euler-problems/">See all  Project Euler problems solutions</a>.</p>
<p><a href="http://www.dotnetkicks.com/kick/?url=http://stefanoricciardi.com/2010/08/16/project-euler-problem-6-and-7-in-f/"><img src="http://www.dotnetkicks.com/Services/Images/KickItImageGenerator.ashx?url=http://stefanoricciardi.com/2010/08/16/project-euler-problem-6-and-7-in-f/" border="0" alt="kick it on DotNetKicks.com" /></a></p>
<p><a rev="vote-for" href="http://dotnetshoutout.com/Project-Euler-Problem-6-and-7-in-F-Stefano-Ricciardi"><img alt="Shout it" src="http://dotnetshoutout.com/image.axd?url=http%3A%2F%2Fstefanoricciardi.com%2F2010%2F08%2F16%2Fproject-euler-problem-6-and-7-in-f%2F" style="border:0px"/></a></p>
]]></content:encoded>
			<wfw:commentRss>http://stefanoricciardi.com/2010/08/16/project-euler-problem-6-and-7-in-f/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Project Euler Problem 5 in F#</title>
		<link>http://stefanoricciardi.com/2010/08/12/project-euler-problem-5-in-f/</link>
		<comments>http://stefanoricciardi.com/2010/08/12/project-euler-problem-5-in-f/#comments</comments>
		<pubDate>Thu, 12 Aug 2010 20:35:53 +0000</pubDate>
		<dc:creator>stefanoricciardi</dc:creator>
				<category><![CDATA[.NET]]></category>
		<category><![CDATA[F#]]></category>
		<category><![CDATA[algorithm]]></category>
		<category><![CDATA[Euler Problems]]></category>

		<guid isPermaLink="false">http://stefanoricciardi.com/?p=988</guid>
		<description><![CDATA[Yet another episode in my attempts to solve Project Euler problems. Enter problem number 5: 2520 is the smallest number that can be divided by each of the numbers from 1 to 10 without any remainder. What is the smallest positive number that is evenly divisible by all of the numbers from 1 to 20? [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fstefanoricciardi.com%2F2010%2F08%2F12%2Fproject-euler-problem-5-in-f%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fstefanoricciardi.com%2F2010%2F08%2F12%2Fproject-euler-problem-5-in-f%2F&amp;style=normal" height="61" width="50" /><br />
			</a>
		</div>
<p>Yet another episode in <a href="http://stefanoricciardi.com/tag/euler-problems/">my attempts to solve Project Euler problems</a>.</p>
<p>Enter problem number 5:</p>
<blockquote><p>2520 is the smallest number that can be divided by each of the numbers from 1 to 10 without any remainder.</p>
<p>What is the smallest positive number that is evenly divisible by all of the numbers from 1 to 20?
</p></blockquote>
<p>I&#8217;ll first show you my solution and then explain the bits:</p>
<pre class="brush: fsharp">
#light

// greatest common divisor (Euclid Algorithm)
let rec gcd (a:int64, b:int64) =
    match b with
       | x when x = 0L -&gt; a
       | _ -&gt; gcd (b, a % b)

// least common divisor
let rec lcm (a:int64, b:int64) =
    (a * b) / gcd (a,b)

// least common divisor for a list of numbers
let rec lcmlist (list: int64 list) =
    match list with
        | [] -&gt; 1L
        | [a] -&gt;  a
        | [a;b] -&gt;  lcm(a,b)
        | h::t  -&gt;  lcm(h, lcmlist t)

// utility to generate a list of all integers
// up to a certain number
let generateListTo top =
    let l = [for i in 1L .. int64 top -&gt;  i]
    l

let resolveProblem5 =
    generateListTo 20 |&gt;  lcmlist</pre>
<p>The first thing to realize when reading this problem is that what is really being asked is<br />
the <a href="http://en.wikipedia.org/wiki/Least_common_multiple">least common multiple</a> (<em>lcm</em> from now on) of a list of numbers (in particular, the numbers from 1 to 20 included).</p>
<p>There&#8217;s a straightforward way to compute the <em>lcm</em>, by using the <a href="http://en.wikipedia.org/wiki/Greatest_common_divisor">greatest common divisor</a> (<em>gcd</em>), as follows:</p>
<p><a href="http://stefanoricciardi.com/blog/wp-content/uploads/2010/08/lcm.png"><img class="alignnone size-full wp-image-1007" title="Least Common Multiple" src="http://stefanoricciardi.com/blog/wp-content/uploads/2010/08/lcm.png" alt="Least Common Multiple" width="309" height="77" /></a></p>
<p>As for the <em>gcd</em> itself, it can be easily implemented using the <a href="http://en.wikipedia.org/wiki/Euclidean_algorithm">Euclid Algorithm</a>.</p>
<p>The last piece of the puzzle comes when you realize how calculating the <em>lcd</em> of a set of numbers can be reduced to calculating <em>lcd</em>s pair-wise in the following fashion:</p>
<p><a href="http://stefanoricciardi.com/blog/wp-content/uploads/2010/08/lcmlist.png"><img class="alignnone size-full wp-image-1008" title="Lcm on a list of numbers" src="http://stefanoricciardi.com/blog/wp-content/uploads/2010/08/lcmlist.png" alt="Lcm on a list of numbers" width="567" height="62" /></a></p>
<p>For example, given the numbers 3, 4, 14, and 18, their <em>lcm </em>would be computed in the following way:</p>
<p><a href="http://stefanoricciardi.com/blog/wp-content/uploads/2010/08/lcmlistexample.png"><img class="alignnone size-full wp-image-1006" title="Least Common Multiple=" src="http://stefanoricciardi.com/blog/wp-content/uploads/2010/08/lcmlistexample.png" alt="Least Common Multiple=" width="446" height="168" /></a></p>
<p>As you can see, the algorithm lends itself beautifully to recursion and such is the solution that I have provided. </p>
<p><a href="../../tag/euler-problems/">See all  Project Euler problems solutions</a>.</p>
<p><a href="http://www.dotnetkicks.com/kick/?url=http://stefanoricciardi.com/2010/08/12/project-euler-problem-5-in-f/"><img src="http://www.dotnetkicks.com/Services/Images/KickItImageGenerator.ashx?url=http://stefanoricciardi.com/2010/08/12/project-euler-problem-5-in-f/" border="0" alt="kick it on DotNetKicks.com" /></a></p>
<p><a rev="vote-for" href="http://dotnetshoutout.com/Project-Euler-Problem-5-in-F-Stefano-Ricciardi"><img alt="Shout it" src="http://dotnetshoutout.com/image.axd?url=http%3A%2F%2Fstefanoricciardi.com%2F2010%2F08%2F12%2Fproject-euler-problem-5-in-f%2F" style="border:0px"/></a></p>
]]></content:encoded>
			<wfw:commentRss>http://stefanoricciardi.com/2010/08/12/project-euler-problem-5-in-f/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Project Euler Problem 4 in F#</title>
		<link>http://stefanoricciardi.com/2010/08/05/project-euler-problem-4-in-f/</link>
		<comments>http://stefanoricciardi.com/2010/08/05/project-euler-problem-4-in-f/#comments</comments>
		<pubDate>Thu, 05 Aug 2010 11:49:37 +0000</pubDate>
		<dc:creator>stefanoricciardi</dc:creator>
				<category><![CDATA[.NET]]></category>
		<category><![CDATA[F#]]></category>
		<category><![CDATA[algorithm]]></category>
		<category><![CDATA[Euler Problems]]></category>
		<category><![CDATA[functional]]></category>

		<guid isPermaLink="false">http://stefanoricciardi.com/?p=968</guid>
		<description><![CDATA[Project Euler problem number 4 asks the following: A palindromic number reads the same both ways. The largest palindrome made from the product of two 2-digit numbers is 9009 = 91 × 99. Find the largest palindrome made from the product of two 3-digit numbers. Here follows my solution: #light open System let rec is_palindromic [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fstefanoricciardi.com%2F2010%2F08%2F05%2Fproject-euler-problem-4-in-f%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fstefanoricciardi.com%2F2010%2F08%2F05%2Fproject-euler-problem-4-in-f%2F&amp;style=normal" height="61" width="50" /><br />
			</a>
		</div>
<p><a href="http://projecteuler.net/index.php?section=problems&#038;id=4">Project Euler problem number 4</a> asks the following:</p>
<blockquote><p>
A palindromic number reads the same both ways. The largest palindrome made from the product of two 2-digit numbers is 9009 = 91 × 99.</p>
<p>Find the largest palindrome made from the product of two 3-digit numbers.
</p></blockquote>
<p>Here follows my solution:</p>
<pre class="brush: fsharp">
#light

open System

let rec is_palindromic (a:string) =
    let length = a.Length;
    match a with
        | &quot;&quot;  -&gt; true
        | x -> match length with
                 | 1 -&gt; true
                 | _ -&gt; x.[0] = x.[length-1] &#038;&#038;
                       is_palindromic (x.Substring(1,(length - 2)))

let max_palindrome =
    let numbers = seq {
        for i in 100 .. 999 do
            for j in 100 .. 999 do
                if is_palindromic(Convert.ToString(i*j)) then yield (i*j) }
    Seq.max numbers
</pre>
<p>A few considerations:</p>
<ul>
<li>I first define a general recursive function to determine whether a given string is a palindrome.
<p>I basically check the first and last characters of the string; if they are the same I continue with the second and second last, and so on until I either found a pair of chars that do not match or there&#8217;s only one char or none left.</p>
<p> Alternatively, I could have reversed the string and compared the original and reversed strings for equality; however that would have been not just more work than actually needed by the algorithm, but less useful as an excercise in learning F#.
</li>
<li> The actual algorithm uses brute force to test for palindromicity (neologism?) all the numbers that can be composed multiplying together 3 digits numbers (those from 100 to 999), picking the highest one. Again, as in a previous <a href="http://stefanoricciardi.com/2010/07/01/project-euler-problem-3-in-f/">problem</a>, I am using <a href="http://en.wikipedia.org/wiki/List_comprehension#F.23">comprehension</a> to generate a list of candidates.
</li>
</ul>
<p><a href="http://stefanoricciardi.com/tag/euler-problems/">See all Project Euler problems solutions</a>.</p>
<p><a href="http://www.dotnetkicks.com/kick/?url=http://stefanoricciardi.com/2010/08/05/project-euler-problem-4-in-f/"><img src="http://www.dotnetkicks.com/Services/Images/KickItImageGenerator.ashx?url=http://stefanoricciardi.com/2010/08/05/project-euler-problem-4-in-f/" border="0" alt="kick it on DotNetKicks.com" /></a></p>
<p><a rev="vote-for" href="http://dotnetshoutout.com/Project-Euler-Problem-4-in-F-Stefano-Ricciardi"><img alt="Shout it" src="http://dotnetshoutout.com/image.axd?url=http%3A%2F%2Fstefanoricciardi.com%2F2010%2F08%2F05%2Fproject-euler-problem-4-in-f%2F" style="border:0px"/></a></p>
]]></content:encoded>
			<wfw:commentRss>http://stefanoricciardi.com/2010/08/05/project-euler-problem-4-in-f/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Project Euler Problem 3 in F#</title>
		<link>http://stefanoricciardi.com/2010/07/01/project-euler-problem-3-in-f/</link>
		<comments>http://stefanoricciardi.com/2010/07/01/project-euler-problem-3-in-f/#comments</comments>
		<pubDate>Thu, 01 Jul 2010 08:24:02 +0000</pubDate>
		<dc:creator>stefanoricciardi</dc:creator>
				<category><![CDATA[.NET]]></category>
		<category><![CDATA[F#]]></category>
		<category><![CDATA[algorithm]]></category>
		<category><![CDATA[Euler Problems]]></category>

		<guid isPermaLink="false">http://stefanoricciardi.com/?p=944</guid>
		<description><![CDATA[Continuing with my journey learning F# I have tackled Project Euler problem number 3, which asks: The prime factors of 13195 are 5, 7, 13 and 29. What is the largest prime factor of the number 600851475143 This problem deals with the fascinating problem of prime numbers factorization, which is considered a hard problem. So [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fstefanoricciardi.com%2F2010%2F07%2F01%2Fproject-euler-problem-3-in-f%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fstefanoricciardi.com%2F2010%2F07%2F01%2Fproject-euler-problem-3-in-f%2F&amp;style=normal" height="61" width="50" /><br />
			</a>
		</div>
<p>Continuing with my journey <a href="http://stefanoricciardi.com/2010/05/31/best-resources-to-learn-f/">learning F#</a> I have tackled <a href="http://projecteuler.net">Project Euler</a> problem number 3, which asks:</p>
<blockquote><p>The prime factors of 13195 are 5, 7, 13 and 29.</p>
<p>What is the largest prime factor of the number 600851475143</p></blockquote>
<p>This problem deals with the fascinating problem of <a href="http://en.wikipedia.org/wiki/Integer_factorization">prime numbers factorization</a>, which is considered a <em>hard</em> problem. So hard that our current cryptography schemes rely on this property.</p>
<p>This is my solution:</p>
<pre class="brush: fsharp">
#light
open System

let is_prime x =
    let rec check i =
        double i > sqrt (double x) || (x % i <> 0L &#038;&#038; check (i + 1L))
    check 2L                 

let big_number_factors n =
    let factors = seq {
        let limit = n / 2L
        for i in 2L .. limit do
            if n % i = 0L &#038;&#038; is_prime i then yield i }
    Seq.max factors
</pre>
<p>A few comments:</p>
<ul>
<li>The first function (<code>is_prime</code>) is a simple <a href="http://en.wikipedia.org/wiki/Trial_division">trial division</a> to determine whether a given number is prime. There are cleverer algorithms to find prime numbers: see for example <a href="http://www.haskell.org/haskellwiki/Prime_numbers">here</a> For an interesting discussion you can also have a look at <i><a href="http://www.cs.hmc.edu/~oneill/papers/Sieve-JFP.pdf">The Genuine Sieve of Erathostenes</a></i> by Melissa O&#8217;Neill.</li>
<li>The second function uses <a href="http://en.wikipedia.org/wiki/List_comprehension">comprehension</a> to create the list of primes which are factors for the input value. At the end we simply return the biggest factor.</li>
</ul>
<p><a rev="vote-for" href="http://dotnetshoutout.com/Project-Euler-Problem-3-in-F-Stefano-Ricciardi"><img alt="Shout it" src="http://dotnetshoutout.com/image.axd?url=http%3A%2F%2Fstefanoricciardi.com%2F2010%2F07%2F01%2Fproject-euler-problem-3-in-f%2F" style="border:0px"/></a></p>
]]></content:encoded>
			<wfw:commentRss>http://stefanoricciardi.com/2010/07/01/project-euler-problem-3-in-f/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Project Euler Problem 1 and 2 in F#</title>
		<link>http://stefanoricciardi.com/2010/06/14/project-euler-problem-1-and-2-in-f/</link>
		<comments>http://stefanoricciardi.com/2010/06/14/project-euler-problem-1-and-2-in-f/#comments</comments>
		<pubDate>Mon, 14 Jun 2010 11:30:45 +0000</pubDate>
		<dc:creator>stefanoricciardi</dc:creator>
				<category><![CDATA[.NET]]></category>
		<category><![CDATA[F#]]></category>
		<category><![CDATA[algorithm]]></category>
		<category><![CDATA[Euler Problems]]></category>

		<guid isPermaLink="false">http://stefanoricciardi.com/?p=909</guid>
		<description><![CDATA[In my journey to learn F#, I have recently discovered the Project Euler site, which is a wonderful collection of small algorithmic problems which you can solve in your favorite programming language. This is the kind of excercise I needed to get my feet wet with F# after reading about it. So I started with [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fstefanoricciardi.com%2F2010%2F06%2F14%2Fproject-euler-problem-1-and-2-in-f%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fstefanoricciardi.com%2F2010%2F06%2F14%2Fproject-euler-problem-1-and-2-in-f%2F&amp;style=normal" height="61" width="50" /><br />
			</a>
		</div>
<p>In my journey to learn F#, I have recently discovered the <a href="http://projecteuler.net">Project Euler</a> site, which is a wonderful collection of small algorithmic problems which you can solve in your favorite programming language.</p>
<p>This is the kind of excercise I needed to get my feet wet with F# after reading about it. So I started with the first two problems listed on the site.</p>
<p>They both deal with sequence of numbers. Having a procedural/object-oriented mindset, I have scratched my head a few times in order to find a declarative solution true to the spirit of a functional program. Everything has become clearer after I&#8217;ve dug some more into the <a href="http://msdn.microsoft.com/en-us/library/dd233209.aspx">F# Sequences</a>.</p>
<h2>Problem 1</h2>
<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.</p>
<p>Find the sum of all the multiples of 3 or 5 below 1000.</p></blockquote>
<p>This is my solution to it:</p>
<pre class="brush: fsharp">
# light
let test = 1
    |&gt; Seq.unfold (fun x -&gt; Some(x, x+1))
    |&gt; Seq.takeWhile (fun x -&gt; x &lt; 1000)
    |&gt; Seq.filter ( fun x -&gt; x % 3 = 0 || x % 5 = 0)
    |&gt; Seq.sum;;
</pre>
<h2>Problem 2</h2>
<blockquote><p>Each new term in the Fibonacci sequence is generated by adding the previous two terms. By starting with 1 and 2, the first 10 terms will be:</p>
<p>1, 2, 3, 5, 8, 13, 21, 34, 55, 89, &#8230;</p>
<p>Find the sum of all the even-valued terms in the sequence which do not exceed four million.</p></blockquote>
<p>Follows my solution:</p>
<pre class="brush:fsharp">
# light
let fibonacci_sequence = Seq.unfold (fun (a, b) -> Some(a, (b, a+b))) (0,1)
    |&gt; Seq.takeWhile(fun x -&gt; x &lt;= 400000)
    |&gt; Seq.filter(fun x -&gt; x % 2 = 0)
    |&gt; Seq.sum
</pre>
<p>A few comments:</p>
<ul>
<li>Here I am using the <code>filter</code> method defined on sequences to stop<br />
the sequence itself at 4 million, therefore I can get by with plain integers. Normally you would want to use <a href="http://msdn.microsoft.com/en-us/library/ee620695(v=VS.100).aspx">BigInteger</a>s for sequences where you&#8217;d expect to need handling large numbers.</li>
<li>One of my first attempts to this problem did not have the <code>Seq.filter</code> part. I only had the <code>takeWhile</code> like the following:</li>
<pre class="brush: fsharp">
Seq.takeWhile(fun x -&gt; x % 2 = 0 &amp;&amp; x &lt;= 400000)
</pre>
<p>Unfortunately, this does not work since the <code>takeWhile</code> will interrupt the sequence as soon as it satisfies the first condition (<code>x % 2 = 0</code>); in other words, it yields a sequence consisting only of the value 0, which looked somehow counterintuitive to me at first.
</ul>
<p>If you are also taking your first steps with F#, you might want to have a look to the <a href="http://stefanoricciardi.com/2010/05/31/best-resources-to-learn-f/">best resources to learn it</a>.</p>
<p><a href="http://www.dotnetkicks.com/kick/?url=http%3a%2f%2fstefanoricciardi.com%2f2010%2f06%2f14%2fproject-euler-problem-1-and-2-in-f%2f"><img src="http://www.dotnetkicks.com/Services/Images/KickItImageGenerator.ashx?url=http%3a%2f%2fstefanoricciardi.com%2f2010%2f06%2f14%2fproject-euler-problem-1-and-2-in-f%2f" border="0" alt="kick it on DotNetKicks.com" /></a></p>
<p><a rev="vote-for" href="http://dotnetshoutout.com/Project-Euler-Problem-1-and-2-in-F-Stefano-Ricciardi"><img alt="Shout it" src="http://dotnetshoutout.com/image.axd?url=http%3A%2F%2Fstefanoricciardi.com%2F2010%2F06%2F14%2Fproject-euler-problem-1-and-2-in-f%2F" style="border:0px"/></a></p>
]]></content:encoded>
			<wfw:commentRss>http://stefanoricciardi.com/2010/06/14/project-euler-problem-1-and-2-in-f/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Comparing Floating Point Numbers</title>
		<link>http://stefanoricciardi.com/2010/03/02/comparing-floating-point-numbers/</link>
		<comments>http://stefanoricciardi.com/2010/03/02/comparing-floating-point-numbers/#comments</comments>
		<pubDate>Tue, 02 Mar 2010 13:29:00 +0000</pubDate>
		<dc:creator>stefanoricciardi</dc:creator>
				<category><![CDATA[.NET]]></category>
		<category><![CDATA[C#]]></category>
		<category><![CDATA[algorithm]]></category>
		<category><![CDATA[tips]]></category>

		<guid isPermaLink="false">http://stefanoricciardi.wordpress.com/?p=807</guid>
		<description><![CDATA[Floating Points and Rounding Errors. Working with floating points number can sometimes provide some (un)pleasant surprise, since many real numbers do not have a finite representation and this can lead to rounding errors. If you need to refresh your knowledge (and have some time to spare), you can find a great treatment in the article [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fstefanoricciardi.com%2F2010%2F03%2F02%2Fcomparing-floating-point-numbers%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fstefanoricciardi.com%2F2010%2F03%2F02%2Fcomparing-floating-point-numbers%2F&amp;style=normal" height="61" width="50" /><br />
			</a>
		</div>
<h2>Floating Points and Rounding Errors.</h2>
<p>Working with floating points number can sometimes provide some (un)pleasant surprise, since many real numbers do not have a finite representation and this can lead to rounding errors. </p>
<p>If you need to refresh your knowledge (and have some time to spare), you can find a great treatment in the article <a href="http://docs.sun.com/source/806-3568/ncg_goldberg.html">What Every Computer Scientist Should Know About Floating-Point Arithmetic</a>:</p>
<blockquote><p>
Squeezing infinitely many real numbers into a finite number of bits requires an approximate representation. Although there are infinitely many integers, in most programs the result of integer computations can be stored in 32 bits. In contrast, given any fixed number of bits, most calculations with real numbers will produce quantities that cannot be exactly represented using that many bits. Therefore the result of a floating-point calculation must often be rounded in order to fit back into its finite representation. This rounding error is the characteristic feature of floating-point computation.
</p></blockquote>
<p>A small example should make the problem clearly visible:</p>
<pre class="brush:csharp">
class Program
{
    static void Main(string[] args)
    {
        double a = 22.4;
        double b = a / 131;

        double c = 0;
        for (int i = 0; i < 131; i++)
        {
            c += b;
        }

        Console.WriteLine("Are they equal?: {0}", a == c);
        Console.WriteLine("Difference (a - c) is {0} ", a - c);
    }
}
</pre>
<p>Here we are taking a double (a), diving it by 131 and then creating a new number (c) by adding the result of that division 131 times. By pure math, a and c should be equal. If you try this small program yourself, this is the output that you would get:</p>
<pre>
Are they equal?: False
Difference (a - c) is -4,9737991503207E-14
</pre>
<p>As you can see, the result is not what you might expect, and it's affected by a rounding error that is building up every time b is added to the partial result c.</p>
<p>Note that this is dependent on the number that I have chosen. If you substitute 131 with 5, you will not experience this problem.</p>
<h2>Your Own Comparer</h2>
<p>Sometimes this behavior might annoy you, especially when you don't need such a high precision and a “rough” equality is all you need. A typical situation is unit testing an algorithm against some expected result: your assertions may fail because of a rounding error, even though the logic of your algorithm is formally correct.</p>
<p>In such a case, you might want to implement your own comparer. A desirable property for such a comparer is a threshold value: if the difference between two floating points is <em>below</em> that threshold they are considered equal.</p>
<p>All you need is to implement the .NET interface <code><a href="http://msdn.microsoft.com/en-us/library/ms132151.aspx">IEqualityComparer</a></code><a href="http://msdn.microsoft.com/en-us/library/ms132151.aspx"> </a>interface.</p>
<pre class="brush:csharp">
class DoubleComparer : IEqualityComparer
{
    private readonly double threshold;

    public DoubleComparer(double threshold)
    {
        this.threshold = threshold;
    }

    public bool Equals(double x, double y)
    {
        return Math.Abs(x - y) < this.threshold;
    }

    public int GetHashCode(double obj)
    {
       return obj.GetHashCode();
    }
}
</pre>
<p>I have created my own comparer to use in my unit tests. I only have to implement 2 methods: <code>Equals()</code> and <code>GetHashCode()</code>.</p>
<p>I don't care much for the actual algorithm of the hashcode implementation, so I am reusing <code>double</code> own algorithm.</p>
<p>Instead, I have applied my own logic to the Equals method: to me, two doubles are equal if the absolute value of their difference is within a given threshold (which I can pass to the comparer in the constructor).</p>
<h2>The Comparer In Use</h2>
<p>Suppose I have an algorithm to calculate the histogram of a given collection of doubles, and a unit test to validate the calculation against a collection of expected results.</p>
<p>In the example below, <em>samples</em> are the input values which I want to create the histogram for, and <em>expectedBreaks</em> is a sequence containing the left and right limits of the bins of the histogram (in the example I am requiring 5 bins, so the number of breaks is 5 + 1 = 6).</p>
<pre class="brush:csharp">
var p = new HistogramProvider();
double[] samples = { 20, 12, 4, 22, 19, 24, 9, 5, -12.2, 13, 0 };
double[] expectedBreaks = { -12.2, -4.96, 2.28, 9.52, 16.76, 24 };

var histogram = p.CreateHistogram(samples, 5);

Assert.IsTrue(expectedBreaks.SequenceEqual<double>(
                       histogram.Breaks,
                       new DoubleComparer(0.01)));
</pre>
<p>I have figured out the threshold to pass (0.01) based on the relative size of the doubles under analysis. Of course, you should use your own judgement to come up with a sensible threshold according of the range of your input data.</p>
<p><a href="http://www.dotnetkicks.com/kick/?url=http%3a%2f%2fstefanoricciardi.com%2f2010%2f03%2f02%2fcomparing-floating-point-numbers%2f"><img src="http://www.dotnetkicks.com/Services/Images/KickItImageGenerator.ashx?url=http%3a%2f%2fstefanoricciardi.com%2f2010%2f03%2f02%2fcomparing-floating-point-numbers%2f" border="0" alt="kick it on DotNetKicks.com" /></a></p>
<p><a rev="vote-for" href="http://dotnetshoutout.com/Comparing-Floating-Point-Numbers"><img alt="Shout it" src="http://dotnetshoutout.com/image.axd?url=http%3A%2F%2Fstefanoricciardi.com%2F2010%2F03%2F02%2Fcomparing-floating-point-numbers%2F"></a></p>
]]></content:encoded>
			<wfw:commentRss>http://stefanoricciardi.com/2010/03/02/comparing-floating-point-numbers/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
	</channel>
</rss>
