<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://weblogs.asp.net/utility/FeedStylesheets/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/"><channel><title>.NET at 9.400 ft above sea level : C#</title><link>http://weblogs.asp.net/esanchez/archive/tags/C_2300_/default.aspx</link><description>Tags: C#</description><dc:language>en</dc:language><generator>CommunityServer 2007 SP1 (Build: 20510.895)</generator><item><title>Visual Studio 2010 and .NET Framework Beta 2 available on Wednesday</title><link>http://weblogs.asp.net/esanchez/archive/2009/10/19/visual-studio-2010-and-net-framework-beta-2-available-on-wednesday.aspx</link><pubDate>Mon, 19 Oct 2009 16:31:27 GMT</pubDate><guid isPermaLink="false">c06e2b9d-981a-45b4-a55f-ab0d8bbfdc1c:7233083</guid><dc:creator>Edgar Sánchez</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://weblogs.asp.net/esanchez/rsscomments.aspx?PostID=7233083</wfw:commentRss><comments>http://weblogs.asp.net/esanchez/archive/2009/10/19/visual-studio-2010-and-net-framework-beta-2-available-on-wednesday.aspx#comments</comments><description>&lt;p&gt;This blog has been abandoned for the longest time :-$ but I’ve got great news to try and re-inaugurate it (again): it’s just been announced that &lt;strong&gt;beta 2&lt;/strong&gt; for &lt;strong&gt;Visual Studio 2010&lt;/strong&gt; and &lt;strong&gt;.NET Framework 4&lt;/strong&gt; will be available the day after tomorrow, i.e. on &lt;strong&gt;October 21st&lt;/strong&gt;; moreover, we now have a firm date for the launch of the &lt;strong&gt;final versions&lt;/strong&gt; of these products: &lt;strong&gt;March 22nd 2010&lt;/strong&gt;. There is a lot of cool stuff in the new versions of Visual Studio and .NET Framework but my personal favorites (at least for the time being :-) are:&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;The inclusion of dynamic programming elements in C# and other framework languages. Good things from languages like Python, Groovy, or Ruby are now an integral part of C#. &lt;/li&gt;    &lt;li&gt;The inclusion of &lt;a href="http://blogs.msdn.com/somasegar/archive/2009/10/09/f-in-vs2010.aspx"&gt;F# as a first level language of the .NET Framework&lt;/a&gt;, welcome functional programming to the most popular commercial development platform on the planet! &lt;/li&gt;    &lt;li&gt;A new version of Entity Framework, making the oficial .NET ORM tool more flexible and adequate. Less and less, we’ll need to code SQL by hand and laboriously move data from tables to objects and viceversa. &lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;As I said, there’s a lot of cool stuff in Visual Studio 2010 and .NET Framework 4, but I plan to start using those three things as soon as possible in customer projects, after all, to have success stories by March 2010, we have to start working before this year ends.&lt;/p&gt;&lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=7233083" width="1" height="1"&gt;</description><category domain="http://weblogs.asp.net/esanchez/archive/tags/Visual+Studio+2010/default.aspx">Visual Studio 2010</category><category domain="http://weblogs.asp.net/esanchez/archive/tags/.NET/default.aspx">.NET</category><category domain="http://weblogs.asp.net/esanchez/archive/tags/C_2300_/default.aspx">C#</category><category domain="http://weblogs.asp.net/esanchez/archive/tags/F_2300_/default.aspx">F#</category><category domain="http://weblogs.asp.net/esanchez/archive/tags/Functional+Programming/default.aspx">Functional Programming</category><category domain="http://weblogs.asp.net/esanchez/archive/tags/Entity+Framework/default.aspx">Entity Framework</category><category domain="http://weblogs.asp.net/esanchez/archive/tags/Visual+Studio/default.aspx">Visual Studio</category><category domain="http://weblogs.asp.net/esanchez/archive/tags/.NET+Framework+4/default.aspx">.NET Framework 4</category></item><item><title>Cloning objects in .NET</title><link>http://weblogs.asp.net/esanchez/archive/2008/05/18/cloning-objects-in-net.aspx</link><pubDate>Sun, 18 May 2008 06:27:38 GMT</pubDate><guid isPermaLink="false">c06e2b9d-981a-45b4-a55f-ab0d8bbfdc1c:6200321</guid><dc:creator>Edgar Sánchez</dc:creator><slash:comments>2</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://weblogs.asp.net/esanchez/rsscomments.aspx?PostID=6200321</wfw:commentRss><comments>http://weblogs.asp.net/esanchez/archive/2008/05/18/cloning-objects-in-net.aspx#comments</comments><description>&lt;p&gt;In an interesting project where I'm giving a hand, we need to clone objects of a number of different types, perhaps surprisingly the CLR doesn't offer a general cloning method, of course you could use &lt;a href="http://msdn.microsoft.com/en-us/system.object.memberwiseclone.aspx" target="_blank"&gt;MemberwiseClone()&lt;/a&gt; but this is a protected method, so it can be invoked only from inside the class of the object being cloned, which makes it difficult to use it in a general method, besides, MemberWiseClone() does just a &lt;a href="http://en.wikipedia.org/wiki/Object_copy#Shallow_copy" target="_blank"&gt;shallow copy&lt;/a&gt; and what we really need is a &lt;a href="http://en.wikipedia.org/wiki/Object_copy#Deep_copy" target="_blank"&gt;deep copy&lt;/a&gt;.&lt;/p&gt;  &lt;p&gt;There is a good reason for not having such a general method: object cloning is one of those problems which have a simple solution for simple scenarios but that resist a satisfactory solution for all the scenarios, for example the objects may have references to other objects and even to themselves be it directly or after a long chain, for example a customer has invoices that have payments that refer to the customer, a general cloning algorithm for a web several times more complex than that is anything but trivial. But the need of moving objects (and their web) is inescapable in distributed environments, because you have to move the invoices and the customers from the business layer to the presentation layer, so there are indeed mechanisms, albeit with some limitations, for serializing and deserializing object graphs, with the help of these mechanisms we can try and build a general object cloner:&lt;/p&gt;  &lt;div style="font-size: 10pt; background: #101010; color: white; font-family: consolas"&gt;   &lt;p style="margin: 0px"&gt;&lt;span style="background: #181818; color: #ffaa55"&gt;&amp;#160;&amp;#160;&amp;#160; 1&lt;/span&gt;&amp;#160;&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&lt;span style="background: #181818; color: #ffaa55"&gt;&amp;#160;&amp;#160;&amp;#160; 2&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: #8ac5ff"&gt;public&lt;/span&gt; &lt;span style="color: #8ac5ff"&gt;static&lt;/span&gt; T BinaryClone&lt;span style="color: silver"&gt;&amp;lt;&lt;/span&gt;T&lt;span style="color: silver"&gt;&amp;gt;&lt;/span&gt;(&lt;span style="color: #8ac5ff"&gt;this&lt;/span&gt; T originalObject)&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&lt;span style="background: #181818; color: #ffaa55"&gt;&amp;#160;&amp;#160;&amp;#160; 3&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&lt;span style="background: #181818; color: #ffaa55"&gt;&amp;#160;&amp;#160;&amp;#160; 4&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: #8ac5ff"&gt;using&lt;/span&gt; (&lt;span style="color: #8ac5ff"&gt;var&lt;/span&gt; stream &lt;span style="color: silver"&gt;=&lt;/span&gt; &lt;span style="color: #8ac5ff"&gt;new&lt;/span&gt; System&lt;span style="color: silver"&gt;.&lt;/span&gt;IO&lt;span style="color: silver"&gt;.&lt;/span&gt;&lt;span style="color: #64b1ff"&gt;MemoryStream&lt;/span&gt;())&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&lt;span style="background: #181818; color: #ffaa55"&gt;&amp;#160;&amp;#160;&amp;#160; 5&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&lt;span style="background: #181818; color: #ffaa55"&gt;&amp;#160;&amp;#160;&amp;#160; 6&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: #8ac5ff"&gt;var&lt;/span&gt; binaryFormatter &lt;span style="color: silver"&gt;=&lt;/span&gt; &lt;span style="color: #8ac5ff"&gt;new&lt;/span&gt; System&lt;span style="color: silver"&gt;.&lt;/span&gt;Runtime&lt;span style="color: silver"&gt;.&lt;/span&gt;Serialization&lt;span style="color: silver"&gt;.&lt;/span&gt;Formatters&lt;span style="color: silver"&gt;.&lt;/span&gt;Binary&lt;span style="color: silver"&gt;.&lt;/span&gt;&lt;span style="color: #64b1ff"&gt;BinaryFormatter&lt;/span&gt;();&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&lt;span style="background: #181818; color: #ffaa55"&gt;&amp;#160;&amp;#160;&amp;#160; 7&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; binaryFormatter&lt;span style="color: silver"&gt;.&lt;/span&gt;Serialize(stream, originalObject);&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&lt;span style="background: #181818; color: #ffaa55"&gt;&amp;#160;&amp;#160;&amp;#160; 8&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; stream&lt;span style="color: silver"&gt;.&lt;/span&gt;Position &lt;span style="color: silver"&gt;=&lt;/span&gt; &lt;span style="color: #ffff80"&gt;0&lt;/span&gt;;&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&lt;span style="background: #181818; color: #ffaa55"&gt;&amp;#160;&amp;#160;&amp;#160; 9&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: #8ac5ff"&gt;return&lt;/span&gt; (T)binaryFormatter&lt;span style="color: silver"&gt;.&lt;/span&gt;Deserialize(stream);&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&lt;span style="background: #181818; color: #ffaa55"&gt;&amp;#160;&amp;#160; 10&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&lt;span style="background: #181818; color: #ffaa55"&gt;&amp;#160;&amp;#160; 11&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&lt;span style="background: #181818; color: #ffaa55"&gt;&amp;#160;&amp;#160; 12&lt;/span&gt;&amp;#160;&lt;/p&gt; &lt;/div&gt;  &lt;p&gt;We just convert, using as intermediary a memory stream, our object to a bit string and then we synthesize a *new object* from that bit string. The use of BinaryClone() flows nicely:&lt;/p&gt;  &lt;div style="font-size: 10pt; background: #101010; color: white; font-family: consolas"&gt;   &lt;p style="margin: 0px"&gt;&lt;span style="background: #181818; color: #ffaa55"&gt;&amp;#160;&amp;#160;&amp;#160; 1&lt;/span&gt;&amp;#160;&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&lt;span style="background: #181818; color: #ffaa55"&gt;&amp;#160;&amp;#160;&amp;#160; 2&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: #8ac5ff"&gt;var&lt;/span&gt; clone &lt;span style="color: silver"&gt;=&lt;/span&gt; person&lt;span style="color: silver"&gt;.&lt;/span&gt;BinaryClone();&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&lt;span style="background: #181818; color: #ffaa55"&gt;&amp;#160;&amp;#160;&amp;#160; 3&lt;/span&gt;&amp;#160;&lt;/p&gt; &lt;/div&gt;  &lt;p&gt;Easy to write, but we have to be careful of the performance and the corner cases. I run a few *very informal* performance tests with this object:&lt;/p&gt;  &lt;div style="font-size: 10pt; background: #101010; color: white; font-family: consolas"&gt;   &lt;p style="margin: 0px"&gt;&lt;span style="background: #181818; color: #ffaa55"&gt;&amp;#160;&amp;#160;&amp;#160; 1&lt;/span&gt;&amp;#160;&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&lt;span style="background: #181818; color: #ffaa55"&gt;&amp;#160;&amp;#160;&amp;#160; 2&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: #8ac5ff"&gt;var&lt;/span&gt; person &lt;span style="color: silver"&gt;=&lt;/span&gt; &lt;span style="color: #8ac5ff"&gt;new&lt;/span&gt; &lt;span style="color: #64b1ff"&gt;Person&lt;/span&gt;&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&lt;span style="background: #181818; color: #ffaa55"&gt;&amp;#160;&amp;#160;&amp;#160; 3&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&lt;span style="background: #181818; color: #ffaa55"&gt;&amp;#160;&amp;#160;&amp;#160; 4&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Id &lt;span style="color: silver"&gt;=&lt;/span&gt; &lt;span style="color: #ffff80"&gt;101&lt;/span&gt;,&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&lt;span style="background: #181818; color: #ffaa55"&gt;&amp;#160;&amp;#160;&amp;#160; 5&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Name &lt;span style="color: silver"&gt;=&lt;/span&gt; &lt;span style="color: #ff8040"&gt;&amp;quot;S&amp;#225;nchez, Sebasti&amp;#225;n&amp;quot;&lt;/span&gt;,&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&lt;span style="background: #181818; color: #ffaa55"&gt;&amp;#160;&amp;#160;&amp;#160; 6&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Salary &lt;span style="color: silver"&gt;=&lt;/span&gt; &lt;span style="color: #ffff80"&gt;590.20m&lt;/span&gt;,&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&lt;span style="background: #181818; color: #ffaa55"&gt;&amp;#160;&amp;#160;&amp;#160; 7&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; BirthDate &lt;span style="color: silver"&gt;=&lt;/span&gt; &lt;span style="color: #8ac5ff"&gt;new&lt;/span&gt; &lt;span style="color: #ffffaa"&gt;DateTime&lt;/span&gt;(&lt;span style="color: #ffff80"&gt;2000&lt;/span&gt;, &lt;span style="color: #ffff80"&gt;6&lt;/span&gt;, &lt;span style="color: #ffff80"&gt;15&lt;/span&gt;),&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&lt;span style="background: #181818; color: #ffaa55"&gt;&amp;#160;&amp;#160;&amp;#160; 8&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Address &lt;span style="color: silver"&gt;=&lt;/span&gt; &lt;span style="color: #8ac5ff"&gt;new&lt;/span&gt; &lt;span style="color: #64b1ff"&gt;Address&lt;/span&gt; { Number &lt;span style="color: silver"&gt;=&lt;/span&gt; &lt;span style="color: #ff8040"&gt;&amp;quot;N24-78&amp;quot;&lt;/span&gt;, Street &lt;span style="color: silver"&gt;=&lt;/span&gt; &lt;span style="color: #ff8040"&gt;&amp;quot;Pasaje C&amp;#243;rdova&amp;quot;&lt;/span&gt; }&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&lt;span style="background: #181818; color: #ffaa55"&gt;&amp;#160;&amp;#160;&amp;#160; 9&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; };&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&lt;span style="background: #181818; color: #ffaa55"&gt;&amp;#160;&amp;#160; 10&lt;/span&gt;&amp;#160;&lt;/p&gt; &lt;/div&gt;  &lt;p&gt;And I found that doing a hundred thousand clones takes some nine thousand milliseconds, that is each cloning takes less than one ten-thousandth of a second, which is adequate to our needs. BinaryFormatter has been with us since .NET Framework 1.0 so I'm not like saying anything even remotely new or unknown, but tomorrow (or the day after, or the day after...) I'll talk about a small refinement to BinaryClone().&lt;/p&gt;&lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=6200321" width="1" height="1"&gt;</description><category domain="http://weblogs.asp.net/esanchez/archive/tags/.NET/default.aspx">.NET</category><category domain="http://weblogs.asp.net/esanchez/archive/tags/C_2300_/default.aspx">C#</category></item><item><title>A cool way to find out whether a number is palindromic</title><link>http://weblogs.asp.net/esanchez/archive/2008/05/06/a-cool-way-to-find-out-whether-a-number-is-palindromic.aspx</link><pubDate>Tue, 06 May 2008 06:40:08 GMT</pubDate><guid isPermaLink="false">c06e2b9d-981a-45b4-a55f-ab0d8bbfdc1c:6161587</guid><dc:creator>Edgar Sánchez</dc:creator><slash:comments>4</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://weblogs.asp.net/esanchez/rsscomments.aspx?PostID=6161587</wfw:commentRss><comments>http://weblogs.asp.net/esanchez/archive/2008/05/06/a-cool-way-to-find-out-whether-a-number-is-palindromic.aspx#comments</comments><description>&lt;p&gt;In &lt;a href="http://weblogs.asp.net/esanchez/archive/2008/04/22/nested-sequences-and-palindrome-numbers.aspx" target="_blank"&gt;this blog entry I proposed a solution&lt;/a&gt; to &lt;a href="http://projecteuler.net/index.php?section=problems&amp;amp;id=4" target="_blank"&gt;Problem 4 at Project Euler&lt;/a&gt;, a crucial element of the problem is to find out whether a number is a palindrome (909 is, 809 isn't), a bit out of laziness and a bit in order to reuse existing methods, I decided to verify the palindrome by converting the number into a char array and then comparing this array with its mirror version, it works but it's not really that mathematical... &lt;a href="http://diditwith.net/2008/05/02/YAPESProblemFour.aspx" target="_blank"&gt;Dustin Campbell proposed a solution&lt;/a&gt; kind of similar to mine (alas, more elegant and, above that, in F#) and using the same trick of converting the number to chars, as he didn't like this part of the solution, in &lt;a href="http://diditwith.net/2008/05/06/YAPESProblemFourAlternateSolution.aspx" target="_blank"&gt;this new blog entry he proposes the detection of a palindrome by mirroring the number one digit at a time&lt;/a&gt;. A translation of his F# code to C# 3.0 could be:&lt;/p&gt; &lt;div style="font-size: 10pt; background: white; color: black; font-family: consolas"&gt; &lt;p style="margin: 0px"&gt;&lt;span style="color: #2b91af"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 1&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: #2b91af"&gt;Func&lt;/span&gt;&amp;lt;&lt;span style="color: blue"&gt;int&lt;/span&gt;, &lt;span style="color: blue"&gt;int&lt;/span&gt;, &lt;span style="color: blue"&gt;int&lt;/span&gt;&amp;gt; TailReverseNumber = &lt;span style="color: blue"&gt;null&lt;/span&gt;;&lt;/p&gt; &lt;p style="margin: 0px"&gt;&lt;span style="color: #2b91af"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 2&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; TailReverseNumber = (n, res) =&amp;gt; n == 0 ? res : TailReverseNumber(n / 10, 10 * res + n % 10);&lt;/p&gt; &lt;p style="margin: 0px"&gt;&lt;span style="color: #2b91af"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 3&lt;/span&gt;&amp;nbsp;&lt;/p&gt; &lt;p style="margin: 0px"&gt;&lt;span style="color: #2b91af"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 4&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: #2b91af"&gt;Func&lt;/span&gt;&amp;lt;&lt;span style="color: blue"&gt;int&lt;/span&gt;, &lt;span style="color: blue"&gt;bool&lt;/span&gt;&amp;gt; IsPalindrome = n =&amp;gt; n == TailReverseNumber(n, 0);&lt;/p&gt;&lt;/div&gt; &lt;p&gt;TailReverseNumber takes a number n and "mirrors" it, one digit at a time, for example: TailReverseNumber(237, 0) -&amp;gt; TailReverseNumber(23, 7) -&amp;gt; TailReverseNumber(2, 73) -&amp;gt; TailReverseNumber(0, 732), the big trick is that res works as an accumulator that is multiplied by 10, therefore moving its value to the left, and putting in the "hole" that appears at the right the least significant digit of n. As it names implies, TailReverseNumber() uses &lt;a href="http://en.wikipedia.org/wiki/Tail_recursion" target="_blank"&gt;tail recursion&lt;/a&gt;, so that no extra call stack space is used to save any intermediate results, which makes the process pretty efficient. Actually, in my PC it's four times faster than the initial solution. More efficient and more elegant, a smart guy Dustin.&lt;/p&gt;&lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=6161587" width="1" height="1"&gt;</description><category domain="http://weblogs.asp.net/esanchez/archive/tags/C_2300_/default.aspx">C#</category><category domain="http://weblogs.asp.net/esanchez/archive/tags/C_2300_+3.0/default.aspx">C# 3.0</category><category domain="http://weblogs.asp.net/esanchez/archive/tags/F_2300_/default.aspx">F#</category><category domain="http://weblogs.asp.net/esanchez/archive/tags/Functional+Programming/default.aspx">Functional Programming</category><category domain="http://weblogs.asp.net/esanchez/archive/tags/Project+Euler/default.aspx">Project Euler</category></item><item><title>Which is the ten thousand first prime?</title><link>http://weblogs.asp.net/esanchez/archive/2008/05/02/which-is-the-ten-thousand-first-prime.aspx</link><pubDate>Fri, 02 May 2008 05:09:56 GMT</pubDate><guid isPermaLink="false">c06e2b9d-981a-45b4-a55f-ab0d8bbfdc1c:6149321</guid><dc:creator>Edgar Sánchez</dc:creator><slash:comments>4</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://weblogs.asp.net/esanchez/rsscomments.aspx?PostID=6149321</wfw:commentRss><comments>http://weblogs.asp.net/esanchez/archive/2008/05/02/which-is-the-ten-thousand-first-prime.aspx#comments</comments><description>&lt;p&gt;Prime numbers have a good deal of practical applications (for example in cryptography) but let's face it, even if they would have none, they would still be the &lt;a title="Prime Obsession" href="http://olimu.com/Riemann/Riemann.htm" target="_blank"&gt;favorite toy of mathematicians&lt;/a&gt;. In &lt;a href="http://projecteuler.net/index.php?section=problems&amp;amp;id=7" target="_blank"&gt;Problem 7 of Project Euler&lt;/a&gt;, we are asked to find the 10001st element of the famous list, my approach was this:&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;Define the *infinite* sequence of the prime numbers &lt;/li&gt;    &lt;li&gt;From this sequence, throw away the first 10000 items and then take the first of the remaining &lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;Creating an infinite sequence in C# is easy (since version 2) thanks to IEnumerables and, above all, the yield statement:&lt;/p&gt;  &lt;div style="font-size: 10pt; background: white; color: black; font-family: consolas"&gt;   &lt;p style="margin: 0px"&gt;&lt;span style="color: #2b91af"&gt;&amp;#160;&amp;#160;&amp;#160; 1&lt;/span&gt;&amp;#160;&lt;span style="color: #2b91af"&gt;IEnumerable&lt;/span&gt;&amp;lt;&lt;span style="color: blue"&gt;int&lt;/span&gt;&amp;gt; Primes()&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&lt;span style="color: #2b91af"&gt;&amp;#160;&amp;#160;&amp;#160; 2&lt;/span&gt; {&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&lt;span style="color: #2b91af"&gt;&amp;#160;&amp;#160;&amp;#160; 3&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: blue"&gt;yield&lt;/span&gt; &lt;span style="color: blue"&gt;return&lt;/span&gt; 2;&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&lt;span style="color: #2b91af"&gt;&amp;#160;&amp;#160;&amp;#160; 4&lt;/span&gt;&amp;#160;&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&lt;span style="color: #2b91af"&gt;&amp;#160;&amp;#160;&amp;#160; 5&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: blue"&gt;var&lt;/span&gt; primesSoFar = &lt;span style="color: blue"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af"&gt;List&lt;/span&gt;&amp;lt;&lt;span style="color: blue"&gt;int&lt;/span&gt;&amp;gt;();&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&lt;span style="color: #2b91af"&gt;&amp;#160;&amp;#160;&amp;#160; 6&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; primesSoFar.Add(2);&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&lt;span style="color: #2b91af"&gt;&amp;#160;&amp;#160;&amp;#160; 7&lt;/span&gt;&amp;#160;&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&lt;span style="color: #2b91af"&gt;&amp;#160;&amp;#160;&amp;#160; 8&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: #2b91af"&gt;Func&lt;/span&gt;&amp;lt;&lt;span style="color: blue"&gt;int&lt;/span&gt;, &lt;span style="color: blue"&gt;bool&lt;/span&gt;&amp;gt; IsPrime = n =&amp;gt; primesSoFar.TakeWhile(p =&amp;gt; p &amp;lt;= (&lt;span style="color: blue"&gt;int&lt;/span&gt;)&lt;span style="color: #2b91af"&gt;Math&lt;/span&gt;.Sqrt(n)).FirstOrDefault(p =&amp;gt; n % p == 0) == 0;&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&lt;span style="color: #2b91af"&gt;&amp;#160;&amp;#160;&amp;#160; 9&lt;/span&gt;&amp;#160;&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&lt;span style="color: #2b91af"&gt;&amp;#160;&amp;#160; 10&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: blue"&gt;for&lt;/span&gt; (&lt;span style="color: blue"&gt;int&lt;/span&gt; i = 3; &lt;span style="color: blue"&gt;true&lt;/span&gt;; i += 2)&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&lt;span style="color: #2b91af"&gt;&amp;#160;&amp;#160; 11&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&lt;span style="color: #2b91af"&gt;&amp;#160;&amp;#160; 12&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: blue"&gt;if&lt;/span&gt; (IsPrime(i))&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&lt;span style="color: #2b91af"&gt;&amp;#160;&amp;#160; 13&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&lt;span style="color: #2b91af"&gt;&amp;#160;&amp;#160; 14&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: blue"&gt;yield&lt;/span&gt; &lt;span style="color: blue"&gt;return&lt;/span&gt; i;&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&lt;span style="color: #2b91af"&gt;&amp;#160;&amp;#160; 15&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; primesSoFar.Add(i);&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&lt;span style="color: #2b91af"&gt;&amp;#160;&amp;#160; 16&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&lt;span style="color: #2b91af"&gt;&amp;#160;&amp;#160; 17&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&lt;span style="color: #2b91af"&gt;&amp;#160;&amp;#160; 18&lt;/span&gt; }&lt;/p&gt; &lt;/div&gt;  &lt;p&gt;The yield at line 3 returns the first item of the sequence: the always excepcional 2 (the only even prime). Then at line 5 we create a list where we will be saving the generated primes as we progress in the sequence (this way we will gain speed at the cost of memory). The IsPrime(n) function defined at line 9, proposes a method -pretty crude actually- of verifying whether a number is prime: we take all primes generated so far which are lower or equal than the square root of n, and we look for the first among them that divides n evenly, if such a divisor exists then n is not a prime, that is: if none of the primes already generated is an exact divisor of n then FirstOrDefault() returns a 0, signaling the fact that n is indeed a prime. Finally at line 10 starts the loop that, every time the Prime() invoker asks for an item, it progresses thru 3, 5, 7, 9, 11, 13, ... stopping and returning, thru yield, when it finds a new prime.&lt;/p&gt;  &lt;p&gt;With this sequence in our hands, step 2 of my plan is utterly simple:&lt;/p&gt;  &lt;blockquote&gt;   &lt;div style="font-size: 10pt; background: white; color: black; font-family: consolas"&gt;     &lt;p style="margin: 0px"&gt;&lt;span style="color: blue"&gt;return&lt;/span&gt; Primes().Skip(nth - 1).First();&lt;/p&gt;   &lt;/div&gt; &lt;/blockquote&gt;  &lt;p&gt;We take the Primes() sequence, ignore the first nth - 1 (in our case nth = 100001) and then take the first of the remaining. This little code returns the answer in far less than a second.&lt;/p&gt;&lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=6149321" width="1" height="1"&gt;</description><category domain="http://weblogs.asp.net/esanchez/archive/tags/C_2300_/default.aspx">C#</category><category domain="http://weblogs.asp.net/esanchez/archive/tags/C_2300_+3.0/default.aspx">C# 3.0</category><category domain="http://weblogs.asp.net/esanchez/archive/tags/Functional+Programming/default.aspx">Functional Programming</category><category domain="http://weblogs.asp.net/esanchez/archive/tags/LINQ/default.aspx">LINQ</category><category domain="http://weblogs.asp.net/esanchez/archive/tags/Math/default.aspx">Math</category><category domain="http://weblogs.asp.net/esanchez/archive/tags/Project+Euler/default.aspx">Project Euler</category></item><item><title>The square of the sum vs. the sum of the squares</title><link>http://weblogs.asp.net/esanchez/archive/2008/04/27/the-square-of-the-sum-vs-the-sum-of-the-squares.aspx</link><pubDate>Mon, 28 Apr 2008 02:56:32 GMT</pubDate><guid isPermaLink="false">c06e2b9d-981a-45b4-a55f-ab0d8bbfdc1c:6137746</guid><dc:creator>Edgar Sánchez</dc:creator><slash:comments>4</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://weblogs.asp.net/esanchez/rsscomments.aspx?PostID=6137746</wfw:commentRss><comments>http://weblogs.asp.net/esanchez/archive/2008/04/27/the-square-of-the-sum-vs-the-sum-of-the-squares.aspx#comments</comments><description>&lt;p&gt;The &lt;a href="http://projecteuler.net/index.php?section=problems&amp;amp;id=6" target="_blank"&gt;sixth Project Euler problem&lt;/a&gt; poses an exercise that, to me, offers no major hurdles:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;What is the difference between the sum of the squares and the square of the sums [of a sequence of natural numbers]?&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;The functional C# solution is fairly easy to write and read:&lt;/p&gt;  &lt;div style="font-size: 10pt; background: white; color: black; font-family: consolas"&gt;   &lt;p style="margin: 0px"&gt;&lt;span style="color: #2b91af"&gt;&amp;#160;&amp;#160;&amp;#160; 1&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: blue"&gt;public&lt;/span&gt; &lt;span style="color: blue"&gt;int&lt;/span&gt; SquareSumsLessSumSquares(&lt;span style="color: #2b91af"&gt;IEnumerable&lt;/span&gt;&amp;lt;&lt;span style="color: blue"&gt;int&lt;/span&gt;&amp;gt; sequence)&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&lt;span style="color: #2b91af"&gt;&amp;#160;&amp;#160;&amp;#160; 2&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&lt;span style="color: #2b91af"&gt;&amp;#160;&amp;#160;&amp;#160; 3&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: blue"&gt;var&lt;/span&gt; sum = sequence.Sum();&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&lt;span style="color: #2b91af"&gt;&amp;#160;&amp;#160;&amp;#160; 4&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: blue"&gt;var&lt;/span&gt; sumSquares = sequence.Select(i =&amp;gt; i * i).Sum();&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&lt;span style="color: #2b91af"&gt;&amp;#160;&amp;#160;&amp;#160; 5&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: blue"&gt;return&lt;/span&gt; sum * sum - sumSquares;&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&lt;span style="color: #2b91af"&gt;&amp;#160;&amp;#160;&amp;#160; 6&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }&lt;/p&gt; &lt;/div&gt;  &lt;p&gt;We get any sequence of integers (list, array, etc.) and we find the sum of its elements at line 3. The Select() in line 4 generates a new sequence with the square of each item from the original sequence and then we add them up. From there, getting the answer to Problem 6 is easy. Actually, the specific value that the problem asks for is to find out this difference for the first 100 natural numbers, so the corresponding call is:&lt;/p&gt;  &lt;div style="font-size: 10pt; background: white; color: black; font-family: consolas"&gt;   &lt;p style="margin: 0px"&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: blue"&gt;var&lt;/span&gt; result006 = SquareSumsLessSumSquares(&lt;span style="color: #2b91af"&gt;Enumerable&lt;/span&gt;.Range(1, 100));&lt;/p&gt; &lt;/div&gt;  &lt;p&gt;Now, given that the sequence we are focused on is 1, 2, 3, ..., 100, we can leverage a couple of math formulas:&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;&lt;a title="The sum of the first n natural numbers" href="http://en.wikipedia.org/wiki/1_%2B_2_%2B_3_%2B_4_%2B_%C2%B7_%C2%B7_%C2%B7" target="_blank"&gt;&lt;img src="http://upload.wikimedia.org/math/f/1/a/f1a147372db0aa2d5cafc82164ea518c.png" border="0" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;y&lt;/p&gt;  &lt;p&gt;&lt;a title="The sum of the *squares* of the first n natural numbers" href="http://en.wikipedia.org/wiki/Square_pyramidal_number" target="_blank"&gt;&lt;img src="http://upload.wikimedia.org/math/7/7/9/779324dc10f4e762a3eb95f1c4977a6b.png" border="0" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;Isn't the &lt;a href="http://en.wikipedia.org" target="_blank"&gt;Wikipedia&lt;/a&gt; something? With this information in our hands we can re-write our solution this way:&lt;/p&gt;  &lt;div style="font-size: 10pt; background: white; color: black; font-family: consolas"&gt;   &lt;p style="margin: 0px"&gt;&lt;span style="color: #2b91af"&gt;&amp;#160;&amp;#160;&amp;#160; 1&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: blue"&gt;public&lt;/span&gt; &lt;span style="color: blue"&gt;int&lt;/span&gt; SquareSumsLessSumSquaresFirstNumbers(&lt;span style="color: blue"&gt;int&lt;/span&gt; n)&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&lt;span style="color: #2b91af"&gt;&amp;#160;&amp;#160;&amp;#160; 2&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&lt;span style="color: #2b91af"&gt;&amp;#160;&amp;#160;&amp;#160; 3&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: blue"&gt;var&lt;/span&gt; sum = n * (n + 1) / 2;&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&lt;span style="color: #2b91af"&gt;&amp;#160;&amp;#160;&amp;#160; 4&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: blue"&gt;var&lt;/span&gt; sumSquares = n * (n + 1) * (2 * n + 1) / 6;&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&lt;span style="color: #2b91af"&gt;&amp;#160;&amp;#160;&amp;#160; 5&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: blue"&gt;return&lt;/span&gt; sum * sum - sumSquares;&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&lt;span style="color: #2b91af"&gt;&amp;#160;&amp;#160;&amp;#160; 6&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }&lt;/p&gt; &lt;/div&gt;  &lt;p&gt;Clearly this latter way of solving the problem uses far less memory and CPU time. My first solution follows what is called a &amp;quot;brute force&amp;quot; approach, contemption intended. It works, for sure, but there are more elegant and efficient ways of solving the problem. The moral of this story is that a little research can take us a long way towards fresh solutions, probably better than our first approach. How frequently have you seen brute force solutions in production environments?&lt;/p&gt;&lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=6137746" width="1" height="1"&gt;</description><category domain="http://weblogs.asp.net/esanchez/archive/tags/C_2300_/default.aspx">C#</category><category domain="http://weblogs.asp.net/esanchez/archive/tags/C_2300_+3.0/default.aspx">C# 3.0</category><category domain="http://weblogs.asp.net/esanchez/archive/tags/Functional+Programming/default.aspx">Functional Programming</category><category domain="http://weblogs.asp.net/esanchez/archive/tags/Project+Euler/default.aspx">Project Euler</category></item><item><title>Recursive lambdas and sequence aggregations</title><link>http://weblogs.asp.net/esanchez/archive/2008/04/24/recursive-lambdas-and-sequence-aggregations.aspx</link><pubDate>Thu, 24 Apr 2008 05:22:45 GMT</pubDate><guid isPermaLink="false">c06e2b9d-981a-45b4-a55f-ab0d8bbfdc1c:6125982</guid><dc:creator>Edgar Sánchez</dc:creator><slash:comments>4</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://weblogs.asp.net/esanchez/rsscomments.aspx?PostID=6125982</wfw:commentRss><comments>http://weblogs.asp.net/esanchez/archive/2008/04/24/recursive-lambdas-and-sequence-aggregations.aspx#comments</comments><description>&lt;p&gt;The &lt;a href="http://projecteuler.net/index.php?section=problems&amp;amp;id=5" target="_blank"&gt;fifth problem at Project Euler&lt;/a&gt; proposes this nostalgic primary school exercise: find the smallest quantity that is evenly divisible by some numbers, the &lt;a href="http://en.wikipedia.org/wiki/Least_common_multiple" target="_blank"&gt;least common multiple&lt;/a&gt; of 1, 2, 3, ..., 20 to be precise. To begin with, let's remember the old arithmetic formula:&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;img src="http://upload.wikimedia.org/math/4/d/2/4d244548521249d1b5a71941506d5f41.png" /&gt; &lt;/p&gt;  &lt;p&gt;Where gcd is the &lt;a href="http://en.wikipedia.org/wiki/Greatest_common_divisor" target="_blank"&gt;greatest common divisor&lt;/a&gt; of a and b. It's also useful to remember that the lcm is associative, that is lcm(1,2,3) is the same as lcm(lcm(1,2), 3), in other words, we can calculate the lcm of 1 and 2, then the lcm of this result and 3, then the lcm of this result and 4, and so on. In functional C#, these ideas can be expressed like so:&lt;/p&gt;  &lt;div style="font-size: 10pt; background: white; color: black; font-family: consolas"&gt;   &lt;p style="margin: 0px"&gt;&lt;span style="color: #2b91af"&gt;&amp;#160;&amp;#160;&amp;#160; 1&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: #2b91af"&gt;Func&lt;/span&gt;&amp;lt;&lt;span style="color: blue"&gt;int&lt;/span&gt;, &lt;span style="color: blue"&gt;int&lt;/span&gt;, &lt;span style="color: blue"&gt;int&lt;/span&gt;&amp;gt; gcd = &lt;span style="color: blue"&gt;null&lt;/span&gt;;&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&lt;span style="color: #2b91af"&gt;&amp;#160;&amp;#160;&amp;#160; 2&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; gcd = (x, y) =&amp;gt; x % y == 0 ? y : gcd(y, x % y);&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&lt;span style="color: #2b91af"&gt;&amp;#160;&amp;#160;&amp;#160; 3&lt;/span&gt;&amp;#160;&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&lt;span style="color: #2b91af"&gt;&amp;#160;&amp;#160;&amp;#160; 4&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: blue"&gt;return&lt;/span&gt; &lt;span style="color: #2b91af"&gt;Enumerable&lt;/span&gt;.Range(1, 20).Aggregate(1, (x,y) =&amp;gt; x * (y / gcd(x, y)));&lt;/p&gt; &lt;/div&gt;  &lt;p&gt;Line 2 finds the gcd of x and y like this: if the remainder of dividing x by y is zero, then y is the gcd, if not, we must find the gcd of y and such remainder. Note that gcd is defined recursively. The only interesting point here is that in order to define a recursive lambda expression, it is mandatory to first declare the expression variable (which we do in line 1), and only after this the compiler allows us to define a lambda expression in terms of itself. Odd, granted, but easy to get used to.&lt;/p&gt;  &lt;p&gt;Line 4 takes the sequence 1, 2, ..., 20 and accumulates the lcm as the sequence is traversed, that is: it starts calculating lcm(1, 1) (let's call this accum1), then it calculates lcm(accum1, 2) (let's call this accum2), then it calculates lcm(accum2, 3), ..., and finishes with lcm(accum19, 20) which is precisely lcm(1, 2, ..., 20). The Aggregate() function is frequently used for chores like adding each term of a sequence, or multiplying them all, in our case we are using Aggregate() to get the succesive lcm's, which answers the question of Project Euler in two and a half lines of code, cool, eh?&lt;/p&gt;&lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=6125982" width="1" height="1"&gt;</description><category domain="http://weblogs.asp.net/esanchez/archive/tags/C_2300_/default.aspx">C#</category><category domain="http://weblogs.asp.net/esanchez/archive/tags/C_2300_+3.0/default.aspx">C# 3.0</category><category domain="http://weblogs.asp.net/esanchez/archive/tags/Functional+Programming/default.aspx">Functional Programming</category><category domain="http://weblogs.asp.net/esanchez/archive/tags/Math/default.aspx">Math</category><category domain="http://weblogs.asp.net/esanchez/archive/tags/Project+Euler/default.aspx">Project Euler</category></item><item><title>Nested sequences and palindrome numbers</title><link>http://weblogs.asp.net/esanchez/archive/2008/04/22/nested-sequences-and-palindrome-numbers.aspx</link><pubDate>Tue, 22 Apr 2008 06:41:44 GMT</pubDate><guid isPermaLink="false">c06e2b9d-981a-45b4-a55f-ab0d8bbfdc1c:6120740</guid><dc:creator>Edgar Sánchez</dc:creator><slash:comments>4</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://weblogs.asp.net/esanchez/rsscomments.aspx?PostID=6120740</wfw:commentRss><comments>http://weblogs.asp.net/esanchez/archive/2008/04/22/nested-sequences-and-palindrome-numbers.aspx#comments</comments><description>&lt;p&gt;&lt;a href="http://projecteuler.net/index.php?section=problems&amp;amp;id=4" target="_blank"&gt;Problem 4 of Project Euler&lt;/a&gt; poses and impractical albeit intriguing problem: given all three digit numbers (100, 101, 102, ..., 998, 999), find the largest product of 2 of those numbers, where the &lt;strong&gt;product is a palindrome&lt;/strong&gt;. For example, 580.085 is the product of two three-digit numbers (995 x 583) but it isn't the largest of such products. One possible functional C# solution is:&lt;/p&gt;  &lt;div style="font-size: 10pt; background: white; color: black; font-family: consolas"&gt;   &lt;p style="margin: 0px"&gt;&lt;span style="color: #2b91af"&gt;&amp;#160;&amp;#160;&amp;#160; 1&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: #2b91af"&gt;Func&lt;/span&gt;&amp;lt;&lt;span style="color: blue"&gt;int&lt;/span&gt;,&lt;span style="color: blue"&gt;bool&lt;/span&gt;&amp;gt; IsPalindrome = n =&amp;gt; { &lt;span style="color: blue"&gt;var&lt;/span&gt; nchar = n.ToString().ToCharArray(); &lt;span style="color: blue"&gt;return&lt;/span&gt; nchar.SequenceEqual(nchar.Reverse()); };&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&lt;span style="color: #2b91af"&gt;&amp;#160;&amp;#160;&amp;#160; 2&lt;/span&gt;&amp;#160;&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&lt;span style="color: #2b91af"&gt;&amp;#160;&amp;#160;&amp;#160; 3&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: blue"&gt;return&lt;/span&gt; &lt;span style="color: #2b91af"&gt;Enumerable&lt;/span&gt;.Range(100, 900)&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&lt;span style="color: #2b91af"&gt;&amp;#160;&amp;#160;&amp;#160; 4&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; .SelectMany(i =&amp;gt; &lt;span style="color: #2b91af"&gt;Enumerable&lt;/span&gt;.Range(i, 900 - (i - 100)).Select(j =&amp;gt; i * j))&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&lt;span style="color: #2b91af"&gt;&amp;#160;&amp;#160;&amp;#160; 5&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; .Where (p =&amp;gt; IsPalindrome(p))&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&lt;span style="color: #2b91af"&gt;&amp;#160;&amp;#160;&amp;#160; 6&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; .Max();&lt;/p&gt; &lt;/div&gt;  &lt;p&gt;To begin with, let's focus on the interesting part: at line 3, Enumerable.Range() generates the sequence 100, 101, ..., 998, 999; SelectMany() at line 4 does several things, first &lt;strong&gt;for every number i from the previous line&lt;/strong&gt; it generates the sequence i, i + 1, i + 2, ..., 998, 999, and then the inner Select() generates the products {100 x 100, 100 x 101, ..., 100 x 999}, {101 x 101, 101 x 102, ..., 101 x 999 }, ... As you can see, there are 999 sequences generated (are all the same size?) finally SelectMany() kindly &amp;quot;flattens&amp;quot; those 999 sequences in one large sequence containing each and every product; line 5 then is easy, the Where() just keeps those products that are palindromes; the Max() in line 6 isn't worth any explanation.&lt;/p&gt;  &lt;p&gt;Back to line 1, I took the lazy path to check whether a number is a palindrome: I just converted it to a string and then to a char array, finally I checked whether that array is equal, item by item, to its reversed version (and all that work just to leverage IEnumerable.Reverse() ;-)&lt;/p&gt;&lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=6120740" width="1" height="1"&gt;</description><category domain="http://weblogs.asp.net/esanchez/archive/tags/C_2300_/default.aspx">C#</category><category domain="http://weblogs.asp.net/esanchez/archive/tags/C_2300_+3.0/default.aspx">C# 3.0</category><category domain="http://weblogs.asp.net/esanchez/archive/tags/Functional+Programming/default.aspx">Functional Programming</category><category domain="http://weblogs.asp.net/esanchez/archive/tags/Project+Euler/default.aspx">Project Euler</category></item><item><title>Oracle 10g for Windows Vista released</title><link>http://weblogs.asp.net/esanchez/archive/2007/05/08/oracle-10g-for-windows-vista-released.aspx</link><pubDate>Wed, 09 May 2007 03:25:00 GMT</pubDate><guid isPermaLink="false">c06e2b9d-981a-45b4-a55f-ab0d8bbfdc1c:2527826</guid><dc:creator>Edgar Sánchez</dc:creator><slash:comments>12</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://weblogs.asp.net/esanchez/rsscomments.aspx?PostID=2527826</wfw:commentRss><comments>http://weblogs.asp.net/esanchez/archive/2007/05/08/oracle-10g-for-windows-vista-released.aspx#comments</comments><description>&lt;p&gt;&lt;img alt="Herramientas Oracle para trabajar con Visual Studio" height="61" src="http://www.oracle.com/technology/software/tech/dotnet/vs2005logo205x61.jpg" style="width: 205px; height: 61px" title="Herramientas Oracle para trabajar con Visual Studio" width="205" /&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;Oracle has just released a version of its database server specific&amp;nbsp;for&amp;nbsp;Windows Vista,&amp;nbsp;you can download&amp;nbsp;&lt;a href="http://www.oracle.com/technology/software/products/database/oracle10g/htdocs/10203vista.html" target="_blank"&gt;Oracle Database 10g Release 2 (10.2.0.3) Enterprise/Standard Edition for Microsoft Windows Vista&lt;/a&gt; (slightly long name). Now, if what you want is to *develop* applications with Visual Studio 2005&amp;nbsp;in Vista that&amp;nbsp;work with Oracle, the story is somewhat more complex:&lt;/p&gt;&lt;ol start="1"&gt;&lt;li&gt;In the Visual Studio 2005 Vista machine, you must install&amp;nbsp;&lt;a href="http://www.oracle.com/technology/software/products/database/oracle10g/htdocs/10203vista.html" target="_blank"&gt;Oracle Database 10&lt;em&gt;g&lt;/em&gt; Client Release 2 (10.2.0.3)&lt;/a&gt; (same URL as the server).&lt;/li&gt;&lt;li&gt;If you plan to use System.Data.OracleClient, the Oracle ADO.NET provider written by Microsoft then you&amp;#39;re all set.&lt;/li&gt;&lt;li&gt;If you plan to use ODP, the ADO.NET provider written by Oracle itself, then you must download and install &lt;span class="topstoryhead"&gt;&lt;a href="http://www.oracle.com/technology/software/tech/dotnet/utilsoft.html" target="_blank"&gt;Oracle10&lt;em&gt;g&lt;/em&gt; Release 2 ODAC and Oracle Developer Tools for Visual Studio .NET (10.2.0.2.21)&lt;/a&gt; *after*&amp;nbsp;having installed the client of Step&amp;nbsp;1,&amp;nbsp;this additional installer provides the following components:&lt;/span&gt;&lt;/li&gt;&lt;ol start="1"&gt;&lt;li&gt;&lt;span class="topstoryhead"&gt;ODP, the ADO.NET Oracle provider itself&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span class="topstoryhead"&gt;ODE, Oracle Database Extensions for .NET 2.0, a server add-in that allows you to write stored procedures in C# (yeah, that&amp;#39;s right, you can use C# instead of PL/SQL)&lt;/span&gt;&lt;/li&gt;&lt;li&gt;ODT, Oracle Developer Tools for Visual Studio 2005, a Visual Studio add-in that allows you to browse an Oracle server, create tables, view data, etc. from within the IDE&lt;/li&gt;&lt;/ol&gt;&lt;/ol&gt;&lt;p&gt;Why you have to install first the 10.2.0.3 client and after that ODP, ODE&amp;nbsp;and ODT from the 10.2.0.2.21 client is beyond my comprehension but I&amp;#39;ll better stick to the procedure.&lt;br /&gt;&lt;/p&gt;&lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=2527826" width="1" height="1"&gt;</description><category domain="http://weblogs.asp.net/esanchez/archive/tags/ADO.NET/default.aspx">ADO.NET</category><category domain="http://weblogs.asp.net/esanchez/archive/tags/C_2300_/default.aspx">C#</category><category domain="http://weblogs.asp.net/esanchez/archive/tags/Oracle/default.aspx">Oracle</category><category domain="http://weblogs.asp.net/esanchez/archive/tags/vista/default.aspx">vista</category><category domain="http://weblogs.asp.net/esanchez/archive/tags/Visual+Studio/default.aspx">Visual Studio</category><category domain="http://weblogs.asp.net/esanchez/archive/tags/Visual+Studio+2005/default.aspx">Visual Studio 2005</category></item><item><title>Mono 1.1.16: Python, Windows Forms, ASP.NET 2.0</title><link>http://weblogs.asp.net/esanchez/archive/2006/07/07/Mono-1.1.16_3A00_-Python_2C00_-Windows-Forms_2C00_-ASP.NET-2.0.aspx</link><pubDate>Fri, 07 Jul 2006 15:02:00 GMT</pubDate><guid isPermaLink="false">c06e2b9d-981a-45b4-a55f-ab0d8bbfdc1c:455827</guid><dc:creator>Edgar Sánchez</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://weblogs.asp.net/esanchez/rsscomments.aspx?PostID=455827</wfw:commentRss><comments>http://weblogs.asp.net/esanchez/archive/2006/07/07/Mono-1.1.16_3A00_-Python_2C00_-Windows-Forms_2C00_-ASP.NET-2.0.aspx#comments</comments><description>&lt;P&gt;&lt;FONT face=Georgia size=2&gt;This is actually Beta 3 of Mono 1.2, some highlights (according to the &lt;A href="http://www.go-mono.com/archive/1.1.16/"&gt;official&amp;nbsp;announcement&lt;/A&gt;):&lt;/FONT&gt;&lt;/P&gt;
&lt;BLOCKQUOTE dir=ltr style="MARGIN-RIGHT: 0px"&gt;
&lt;P&gt;&lt;A href="http://www.codeplex.com/Wiki/View.aspx?ProjectName=IronPython"&gt;&lt;FONT face=Tahoma size=2&gt;IronPython 1.0 Beta 8&lt;/FONT&gt;&lt;/A&gt;&lt;FONT face=Tahoma size=2&gt; works with this release out of the box. &lt;/FONT&gt;
&lt;P&gt;&lt;FONT face=Tahoma size=2&gt;Majorly improved Windows.Forms and System.Drawing as our beta program for Windows.Forms continues. &lt;/FONT&gt;
&lt;P&gt;&lt;FONT face=Tahoma size=2&gt;New default optimizations boost performance for compute intensive applications. &lt;/FONT&gt;
&lt;P&gt;&lt;FONT face=Tahoma size=2&gt;Long standing debugging line numbers bug fixed. &lt;/FONT&gt;
&lt;P&gt;&lt;FONT face=Tahoma size=2&gt;Preview code for the new Compacting GC. &lt;/FONT&gt;
&lt;P&gt;&lt;FONT face=Tahoma size=2&gt;Hardened runtime for verification, AppDomain unloading and type loading failures &lt;/FONT&gt;
&lt;P&gt;&lt;FONT face=Tahoma size=2&gt;Significant progress on ASP.NET 2.0, some &lt;/FONT&gt;&lt;A href="http://www.asp.net/downloads/starterkits/default.aspx?tabid=62#personal"&gt;&lt;FONT face=Tahoma size=2&gt;Starter Kits&lt;/FONT&gt;&lt;/A&gt;&lt;FONT face=Tahoma size=2&gt; are now functional, as well as large improvements to its test suite.&lt;/FONT&gt;&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;P dir=ltr&gt;&lt;FONT face=Georgia size=2&gt;Seems like we are one step closer to SmartClients (TM)&amp;nbsp;in Linux... Go &lt;A href="http://www.go-mono.com/archive/1.1.16/"&gt;get&amp;nbsp;your copy here&lt;/A&gt;.&lt;/FONT&gt;&lt;/P&gt;&lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=455827" width="1" height="1"&gt;</description><category domain="http://weblogs.asp.net/esanchez/archive/tags/Windows+Forms/default.aspx">Windows Forms</category><category domain="http://weblogs.asp.net/esanchez/archive/tags/.NET/default.aspx">.NET</category><category domain="http://weblogs.asp.net/esanchez/archive/tags/C_2300_/default.aspx">C#</category><category domain="http://weblogs.asp.net/esanchez/archive/tags/Linux/default.aspx">Linux</category><category domain="http://weblogs.asp.net/esanchez/archive/tags/Mono/default.aspx">Mono</category><category domain="http://weblogs.asp.net/esanchez/archive/tags/Python/default.aspx">Python</category><category domain="http://weblogs.asp.net/esanchez/archive/tags/WindowsForms/default.aspx">WindowsForms</category></item><item><title>From the Peculiar Ideas Departament: Compilr</title><link>http://weblogs.asp.net/esanchez/archive/2006/06/30/From-the-Peculiar-Ideas-Departament_3A00_-Compilr.aspx</link><pubDate>Fri, 30 Jun 2006 14:12:00 GMT</pubDate><guid isPermaLink="false">c06e2b9d-981a-45b4-a55f-ab0d8bbfdc1c:455299</guid><dc:creator>Edgar Sánchez</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://weblogs.asp.net/esanchez/rsscomments.aspx?PostID=455299</wfw:commentRss><comments>http://weblogs.asp.net/esanchez/archive/2006/06/30/From-the-Peculiar-Ideas-Departament_3A00_-Compilr.aspx#comments</comments><description>&lt;TABLE&gt;
&lt;TBODY&gt;
&lt;TR&gt;
&lt;TD&gt;
&lt;P&gt;&lt;FONT face=Georgia size=2&gt;Say you're away from home and just have to compile some lines of code to prove a theory, how do you do? Easy: browse to &lt;/FONT&gt;&lt;A href="http://www.caller.me.uk/Compilr/"&gt;&lt;FONT face=Georgia size=2&gt;http://www.caller.me.uk/Compilr/&lt;/FONT&gt;&lt;/A&gt;&lt;FONT face=Georgia size=2&gt;, type or paste your lines and the code is compiled in a far and away server. It sounds like a strange&amp;nbsp;proposition&amp;nbsp;to me, but who knows, may be there are reams of programmers with Internet access that don't have a compiler at hand... Where's the money in the site? Advertising of course (Google is now generating some really weird spawn.) For the time being, they offer you C#, VB.NET, C, and Fortran compilers. Come to think of it, if they offer a few exotic languages like Lisp, Prolog, or APL, I may very well give it a try...&lt;/FONT&gt;&lt;/P&gt;&lt;/TD&gt;
&lt;TD vAlign=top&gt;&lt;IMG src="http://www.caller.me.uk/Compilr/compilr_large.jpg"&gt;&lt;/TD&gt;&lt;/TR&gt;&lt;/TBODY&gt;&lt;/TABLE&gt;&lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=455299" width="1" height="1"&gt;</description><category domain="http://weblogs.asp.net/esanchez/archive/tags/C_2300_/default.aspx">C#</category><category domain="http://weblogs.asp.net/esanchez/archive/tags/Fortran/default.aspx">Fortran</category><category domain="http://weblogs.asp.net/esanchez/archive/tags/General+Software+Development/default.aspx">General Software Development</category><category domain="http://weblogs.asp.net/esanchez/archive/tags/VB.NET/default.aspx">VB.NET</category></item><item><title>ADO.NET provider for Postgresql</title><link>http://weblogs.asp.net/esanchez/archive/2006/06/24/ADO.NET-provider-for-Postgresql.aspx</link><pubDate>Sat, 24 Jun 2006 05:08:00 GMT</pubDate><guid isPermaLink="false">c06e2b9d-981a-45b4-a55f-ab0d8bbfdc1c:454590</guid><dc:creator>Edgar Sánchez</dc:creator><slash:comments>2</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://weblogs.asp.net/esanchez/rsscomments.aspx?PostID=454590</wfw:commentRss><comments>http://weblogs.asp.net/esanchez/archive/2006/06/24/ADO.NET-provider-for-Postgresql.aspx#comments</comments><description>&lt;P&gt;&lt;FONT face=Georgia size=2&gt;This&amp;nbsp;is not really news as the driver has been available since April: &lt;/FONT&gt;&lt;A href="http://pgfoundry.org/projects/npgsql"&gt;&lt;FONT face=Georgia size=2&gt;Npgsql&lt;/FONT&gt;&lt;/A&gt;&lt;FONT face=Georgia size=2&gt; is an ADO.NET data provider written in C# that enables any .NET application to work with&lt;/FONT&gt;&lt;FONT face=Georgia size=2&gt; Postgresql 7.x&amp;nbsp;and 8.x.&amp;nbsp;You can download the provider from&amp;nbsp;&lt;/FONT&gt;&lt;A href="http://pgfoundry.org/projects/npgsql"&gt;&lt;FONT face=Georgia size=2&gt;here&lt;/FONT&gt;&lt;/A&gt;&lt;FONT face=Georgia size=2&gt;.&lt;/FONT&gt;&lt;/P&gt;&lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=454590" width="1" height="1"&gt;</description><category domain="http://weblogs.asp.net/esanchez/archive/tags/.NET/default.aspx">.NET</category><category domain="http://weblogs.asp.net/esanchez/archive/tags/ADO.NET/default.aspx">ADO.NET</category><category domain="http://weblogs.asp.net/esanchez/archive/tags/C_2300_/default.aspx">C#</category><category domain="http://weblogs.asp.net/esanchez/archive/tags/Postgresql/default.aspx">Postgresql</category></item><item><title>.NET in Linux (and something about numerical analysis)</title><link>http://weblogs.asp.net/esanchez/archive/2006/06/22/DotNET-in-Linux-and-something-about-numerical-analysis.aspx</link><pubDate>Thu, 22 Jun 2006 05:58:00 GMT</pubDate><guid isPermaLink="false">c06e2b9d-981a-45b4-a55f-ab0d8bbfdc1c:454305</guid><dc:creator>Edgar Sánchez</dc:creator><slash:comments>1</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://weblogs.asp.net/esanchez/rsscomments.aspx?PostID=454305</wfw:commentRss><comments>http://weblogs.asp.net/esanchez/archive/2006/06/22/DotNET-in-Linux-and-something-about-numerical-analysis.aspx#comments</comments><description>&lt;P&gt;&lt;FONT face=Georgia size=2&gt;Every few months &lt;A href="http://www.devx.com/opensource/Article/31741"&gt;news emerge&lt;/A&gt; about the&amp;nbsp;&lt;A href="http://www.mono-project.com/Main_Page"&gt;Mono project&lt;/A&gt;: spearheaded by &lt;A href="http://en.wikipedia.org/wiki/Miguel_de_Icaza"&gt;Miguel de Icaza&lt;/A&gt; in order to have a Linux .NET implementation that would allow to more easily create Windows like applications in Linux, Mono has managed to implement a good C# compiler, most of the BCL (ADO.NET included) and a pretty reasonable&amp;nbsp;ASP.NET 1.1, but it has failed to have a production-level Windows Forms implementation (they are moving ahead, but Microsoft goes much faster.) A couple of years ago I got enthusiastic about Mono, but now I see (sadly) that it's stalling (even though it was acquired by Novell, or may be exactly because of that&lt;/FONT&gt;&lt;FONT face=Georgia size=2&gt; [;)]).&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face=Georgia size=2&gt;While visiting&amp;nbsp;the Mono site I found (again)&amp;nbsp;&lt;A href="http://www.dnanalytics.net/"&gt;dnAnalytics&lt;/A&gt;, an open source project&amp;nbsp;trying&amp;nbsp;to&amp;nbsp;implement&amp;nbsp;a standard set of numerical methods libraries (stuff like matrix manipulation, differential equations, etc.) in C#. It runs OK in Mono and also in the official .NET (although it doesn't use the new abilities in .NET 2.0), it could be of use for those of you working on numerical analysis.&lt;/FONT&gt;&lt;/P&gt;&lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=454305" width="1" height="1"&gt;</description><category domain="http://weblogs.asp.net/esanchez/archive/tags/.NET/default.aspx">.NET</category><category domain="http://weblogs.asp.net/esanchez/archive/tags/ASP.NET/default.aspx">ASP.NET</category><category domain="http://weblogs.asp.net/esanchez/archive/tags/C_2300_/default.aspx">C#</category><category domain="http://weblogs.asp.net/esanchez/archive/tags/Linux/default.aspx">Linux</category><category domain="http://weblogs.asp.net/esanchez/archive/tags/Mono/default.aspx">Mono</category><category domain="http://weblogs.asp.net/esanchez/archive/tags/Numerical+Analysis/default.aspx">Numerical Analysis</category></item><item><title>Friendly Web sites, design patterns, and metacognition</title><link>http://weblogs.asp.net/esanchez/archive/2006/06/08/Friendly-Web-sites_2C00_-design-patterns_2C00_-and-metacognition.aspx</link><pubDate>Thu, 08 Jun 2006 05:06:00 GMT</pubDate><guid isPermaLink="false">c06e2b9d-981a-45b4-a55f-ab0d8bbfdc1c:451527</guid><dc:creator>Edgar Sánchez</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://weblogs.asp.net/esanchez/rsscomments.aspx?PostID=451527</wfw:commentRss><comments>http://weblogs.asp.net/esanchez/archive/2006/06/08/Friendly-Web-sites_2C00_-design-patterns_2C00_-and-metacognition.aspx#comments</comments><description>&lt;DIV class=BlogPostContent&gt;
&lt;P&gt;&lt;FONT face=Georgia size=2&gt;First of all, you just have to love the guys that created these register policies:&lt;/FONT&gt;&lt;/P&gt;&lt;A href="http://ecuador.latindevelopers.net/photos/programadores_aprendiendo/picture288.aspx" target=_blank&gt;&lt;IMG src="http://ecuador.latindevelopers.net/photos/programadores_aprendiendo/images/288/572x480.aspx" border=0&gt;&lt;/A&gt; 
&lt;P&gt;&lt;FONT face=Georgia size=2&gt;Isn't that all what you expect from a Web community member? Who needs lawyers anyway? Before you start laughing, note that &lt;EM&gt;JavaRanch&lt;/EM&gt; gets &lt;STRONG&gt;millions of entries in its forums every month&lt;/STRONG&gt; and they have won a Jolt Productivity Award on the Web Site and Developer Networks category twice in a row. When you know that, you are not surprised that these same guys created the&lt;/FONT&gt;&lt;FONT face=Georgia size=2&gt; &lt;A href="http://www.oreilly.com/store/series/headfirst.csp"&gt;&lt;FONT color=#7395c1&gt;Head First book series&lt;/FONT&gt;&lt;/A&gt;, of which I started to read &lt;A href="http://www.amazon.com/gp/product/0596007124/ref=pd_kar_gw_3/002-8382853-0692801?%5Fencoding=UTF8&amp;amp;v=glance&amp;amp;n=283155"&gt;&lt;FONT color=#7395c1&gt;Head First Design Patterns&lt;/FONT&gt;&lt;/A&gt;&amp;nbsp;today, a book where, for example, the possibilities of the decorator pattern are&amp;nbsp;illustrated in&amp;nbsp;this way:&lt;/FONT&gt;&lt;/P&gt;&lt;A href="http://ecuador.latindevelopers.net/photos/programadores_aprendiendo/picture289.aspx" target=_blank&gt;&lt;IMG src="http://ecuador.latindevelopers.net/photos/programadores_aprendiendo/images/289/original.aspx" border=0&gt;&lt;/A&gt; 
&lt;P&gt;&lt;FONT face=Georgia size=2&gt;Does that chap looks like an object decorator or what? &lt;IMG alt="Wink [;)]" src="http://ecuador.latindevelopers.net/emoticons/emotion-5.gif"&gt;&amp;nbsp;The authors &lt;A href="http://headrush.typepad.com/creating_passionate_users/"&gt;&lt;FONT color=#7395c1&gt;use in funny ways the results of metacognitive research&lt;/FONT&gt;&lt;/A&gt; (that is, the research on how people learn), so you will laugh while you learn. Now, the authors write all of their examples in Java (nothing is perfect &lt;IMG alt="Stick out tongue [:P]" src="http://ecuador.latindevelopers.net/emoticons/emotion-4.gif"&gt;), but luckily a good soul already &lt;A href="http://www.msquaredweb.com/DesignPatterns/HeadFirstDesignPatternsInCSharp.zip"&gt;&lt;FONT color=#7395c1&gt;translated the samples to .NET&lt;/FONT&gt;&lt;/A&gt; &lt;IMG alt="Cool [H]" src="http://ecuador.latindevelopers.net/emoticons/emotion-11.gif"&gt;. Recommended reading.&lt;/FONT&gt;&lt;/P&gt;&lt;/DIV&gt;&lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=451527" width="1" height="1"&gt;</description><category domain="http://weblogs.asp.net/esanchez/archive/tags/.NET/default.aspx">.NET</category><category domain="http://weblogs.asp.net/esanchez/archive/tags/C_2300_/default.aspx">C#</category><category domain="http://weblogs.asp.net/esanchez/archive/tags/General+Software+Development/default.aspx">General Software Development</category><category domain="http://weblogs.asp.net/esanchez/archive/tags/Java/default.aspx">Java</category></item><item><title>Datasets are not for everything (and neither XML)</title><link>http://weblogs.asp.net/esanchez/archive/2006/06/07/Datasets-are-not-for-everything-_2800_and-neither-XML_2900_.aspx</link><pubDate>Wed, 07 Jun 2006 04:02:00 GMT</pubDate><guid isPermaLink="false">c06e2b9d-981a-45b4-a55f-ab0d8bbfdc1c:451346</guid><dc:creator>Edgar Sánchez</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://weblogs.asp.net/esanchez/rsscomments.aspx?PostID=451346</wfw:commentRss><comments>http://weblogs.asp.net/esanchez/archive/2006/06/07/Datasets-are-not-for-everything-_2800_and-neither-XML_2900_.aspx#comments</comments><description>&lt;DIV class=BlogPostContent&gt;
&lt;P&gt;&lt;FONT face=Georgia size=2&gt;First of all,&amp;nbsp;let me tell you that datasets are wonderful, especially if you have to do CRUD operations on relational records. But that doesn't mean they are always the best choice. Ditto for XML. With the obvious statement out of the way, let me tell you this little tale:&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face=Georgia size=2&gt;My pal Sandra needed to execute a process &lt;STRONG&gt;except&lt;/STRONG&gt; for a group of operations, moreover, this group of "forbidden" operations could be changed at runtime. So, to begin with, Sandra defined an XML file with the forbidden operations:&lt;/FONT&gt;&lt;/P&gt;&lt;FONT color=#0000ff&gt;
&lt;P&gt;&lt;FONT face=Tahoma size=2&gt;&amp;lt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face=Tahoma color=#800000 size=2&gt;ForbiddenOperations&lt;/FONT&gt;&lt;FONT color=#0000ff&gt;&lt;FONT face=Tahoma size=2&gt;&amp;gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face=Tahoma size=2&gt;&amp;nbsp; &amp;lt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt;&lt;FONT face=Tahoma&gt;&lt;FONT color=#800000&gt;Operation&lt;/FONT&gt;&lt;FONT color=#0000ff&gt;&amp;gt;&lt;/FONT&gt;Destroy&lt;FONT color=#0000ff&gt;&amp;lt;/&lt;/FONT&gt;&lt;FONT color=#800000&gt;Operation&lt;/FONT&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff&gt;&lt;FONT face=Tahoma size=2&gt;&amp;gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face=Tahoma size=2&gt;&amp;nbsp; &amp;lt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt;&lt;FONT face=Tahoma&gt;&lt;FONT color=#800000&gt;Operation&lt;/FONT&gt;&lt;FONT color=#0000ff&gt;&amp;gt;&lt;/FONT&gt;Kill&lt;FONT color=#0000ff&gt;&amp;lt;/&lt;/FONT&gt;&lt;FONT color=#800000&gt;Operation&lt;/FONT&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff&gt;&lt;FONT face=Tahoma size=2&gt;&amp;gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face=Tahoma size=2&gt;&amp;nbsp; &amp;lt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt;&lt;FONT face=Tahoma&gt;&lt;FONT color=#800000&gt;Operation&lt;/FONT&gt;&lt;FONT color=#0000ff&gt;&amp;gt;&lt;/FONT&gt;Maime&lt;FONT color=#0000ff&gt;&amp;lt;/&lt;/FONT&gt;&lt;FONT color=#800000&gt;Operation&lt;/FONT&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff&gt;&lt;FONT face=Tahoma size=2&gt;&amp;gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face=Tahoma size=2&gt;&amp;lt;/&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt;&lt;FONT face=Tahoma&gt;&lt;FONT color=#800000&gt;ForbiddenOperations&lt;/FONT&gt;&lt;FONT color=#0000ff&gt;&amp;gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT color=#0000ff&gt;&lt;FONT face=Georgia color=#000000 size=2&gt;Then, she populated a dataset with the contents of the XML file:&lt;/FONT&gt;&lt;/FONT&gt;&lt;/P&gt;&lt;FONT color=#0000ff size=3&gt;
&lt;P&gt;&lt;FONT size=2&gt;&lt;FONT face=Tahoma&gt;&lt;FONT color=#008080&gt;DataSet&lt;/FONT&gt; dataSet = &lt;FONT color=#0000ff&gt;new&lt;/FONT&gt; &lt;FONT color=#008080&gt;DataSet&lt;/FONT&gt;();&lt;/FONT&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT size=2&gt;&lt;FONT face=Tahoma&gt;&lt;FONT color=#000000&gt;dataSet.ReadXml(&lt;/FONT&gt;&lt;FONT color=#800000&gt;@"..\..\ForbiddenOperations.xml"&lt;/FONT&gt;&lt;FONT color=#000000&gt;);&lt;/FONT&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;/P&gt;&lt;FONT size=3&gt;
&lt;P&gt;&lt;FONT color=#0000ff&gt;&lt;FONT face=Georgia color=#000000 size=2&gt;And now, she could execute the process, except for forbidden operations, like so:&lt;/FONT&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT size=2&gt;&lt;FONT face=Tahoma&gt;&lt;FONT color=#008080&gt;DataTable&lt;/FONT&gt; operationsTable = dataSet.Tables[0];&lt;/FONT&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT size=2&gt;&lt;FONT face=Tahoma&gt;&lt;FONT color=#008080&gt;DataRow&lt;/FONT&gt;[] foundRows = operationsTable.Select(&lt;FONT color=#800000&gt;"Operation_Text='"&lt;/FONT&gt; + operation + &lt;FONT color=#800000&gt;"'"&lt;/FONT&gt;);&lt;/FONT&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT size=2&gt;&lt;FONT face=Tahoma&gt;&lt;FONT color=#000000&gt;if&lt;/FONT&gt;&lt;FONT color=#000000&gt; (foundRows&lt;/FONT&gt;.Length&lt;FONT color=#000000&gt; == 0)&lt;/FONT&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face=Tahoma color=#000000 size=2&gt;{&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT color=#008000&gt;&lt;FONT face=Tahoma size=2&gt;&amp;nbsp; // It isn't a forbidden operation, so do the process&lt;/FONT&gt;&lt;/P&gt;&lt;/FONT&gt;&lt;FONT size=3&gt;
&lt;P&gt;&lt;FONT face=Tahoma color=#000000 size=2&gt;}&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT color=#0000ff&gt;&lt;FONT face=Georgia color=#000000 size=2&gt;It works, and it uses just a few lines of code. OTOH, it's terribly inefficient. To begin with, reading an XML file to populate a dataset demands a lot of resources and the file becomes a semaphore. Furthermore, the &lt;FONT face=Tahoma&gt;Select()&lt;/FONT&gt; method scans the table linearly, interpreting the expression for every row. If the table has many rows or the process is invoked many times, the response time will suffer noticeably.&lt;/FONT&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face=Georgia color=#000000 size=2&gt;Which is the alternative? First, let's put the forbidden operations in the App.config file:&lt;/FONT&gt;&lt;/P&gt;&lt;FONT color=#0000ff&gt;
&lt;P&gt;&lt;FONT face=Tahoma size=2&gt;&amp;lt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face=Tahoma color=#800000 size=2&gt;appSettings&lt;/FONT&gt;&lt;FONT color=#0000ff&gt;&lt;FONT face=Tahoma size=2&gt;&amp;gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face=Tahoma size=2&gt;&amp;nbsp; &amp;lt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt;&lt;FONT face=Tahoma&gt;&lt;FONT color=#800000&gt;add&lt;/FONT&gt;&lt;FONT color=#0000ff&gt; &lt;/FONT&gt;&lt;FONT color=#ff0000&gt;key&lt;/FONT&gt;&lt;FONT color=#0000ff&gt;=&lt;/FONT&gt;&lt;FONT color=#000000&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff&gt;forbiddenOperations&lt;/FONT&gt;&lt;FONT color=#000000&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff&gt; &lt;/FONT&gt;&lt;FONT color=#ff0000&gt;value&lt;/FONT&gt;&lt;FONT color=#0000ff&gt;=&lt;/FONT&gt;&lt;FONT color=#000000&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff&gt;Destroy,Kill,Maime&lt;/FONT&gt;&lt;FONT color=#000000&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff&gt;&amp;gt;&amp;lt;/&lt;/FONT&gt;&lt;FONT color=#800000&gt;add&lt;/FONT&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff&gt;&lt;FONT face=Tahoma size=2&gt;&amp;gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face=Tahoma size=2&gt;&amp;lt;/&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt;&lt;FONT face=Tahoma&gt;&lt;FONT color=#800000&gt;appSettings&lt;/FONT&gt;&lt;FONT color=#0000ff&gt;&amp;gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;/P&gt;&lt;FONT color=#0000ff size=3&gt;
&lt;P&gt;&lt;FONT face=Georgia color=#000000 size=2&gt;Then, populate a string dictionary with those operations:&lt;/FONT&gt;&lt;/P&gt;&lt;FONT size=2&gt;&lt;FONT face=Tahoma&gt;&lt;FONT color=#008080&gt;
&lt;P&gt;&lt;FONT size=2&gt;&lt;FONT face=Tahoma&gt;&lt;FONT color=#0000ff&gt;string&lt;/FONT&gt;[] &lt;FONT color=#000000&gt;forbiddenOperations&lt;/FONT&gt; = &lt;FONT color=#008080&gt;ConfigurationSettings&lt;/FONT&gt;.AppSettings[&lt;FONT color=#800000&gt;"forbiddenOperations"&lt;/FONT&gt;].Split(&lt;FONT color=#800000&gt;','&lt;/FONT&gt;);&lt;/FONT&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;StringDictionary&lt;/FONT&gt; &lt;FONT color=#000000&gt;forbiddenOperationsDictionary&lt;/FONT&gt; = &lt;FONT color=#0000ff&gt;new&lt;/FONT&gt; &lt;FONT color=#008080&gt;StringDictionary&lt;/FONT&gt;();&lt;/FONT&gt;&lt;/FONT&gt;&lt;/P&gt;&lt;FONT color=#0000ff size=3&gt;
&lt;P&gt;&lt;FONT size=2&gt;&lt;FONT face=Tahoma&gt;&lt;FONT color=#0000ff&gt;foreach&lt;/FONT&gt; &lt;FONT color=#000000&gt;(&lt;/FONT&gt;&lt;FONT color=#0000ff&gt;string&lt;/FONT&gt; &lt;FONT color=#000000&gt;operation&lt;/FONT&gt; &lt;FONT color=#0000ff&gt;in&lt;/FONT&gt; &lt;FONT color=#000000&gt;forbiddenOperations&lt;/FONT&gt;&lt;FONT color=#000000&gt;)&lt;/FONT&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face=Tahoma color=#000000 size=2&gt;{&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face=Tahoma color=#000000 size=2&gt;&amp;nbsp; forbiddenOperationsDictionary.Add(operation, operation);&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face=Tahoma color=#000000 size=2&gt;}&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face=Georgia color=#000000 size=2&gt;And finally, you can execute the process, except for forbidden operations, like so:&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT size=2&gt;&lt;FONT face=Tahoma&gt;&lt;FONT color=#0000ff&gt;if&lt;/FONT&gt;&lt;FONT color=#000000&gt; (!forbiddenOperationsDictionary&lt;/FONT&gt;&lt;FONT color=#000000&gt;.ContainsKey(operation))&lt;/FONT&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face=Tahoma color=#000000 size=2&gt;{&lt;/FONT&gt;&lt;/P&gt;&lt;FONT color=#008000&gt;&lt;FONT color=#008000&gt;&lt;FONT face=Tahoma size=2&gt;
&lt;P&gt;&lt;FONT color=#008000&gt;&lt;FONT face=Tahoma size=2&gt;&amp;nbsp; // It isn't a forbidden operation, so do the process&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face=Tahoma color=#000000 size=2&gt;}&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face=Georgia color=#000000 size=2&gt;The first and last parts are more compact than in the first solution, even though the second part takes more lines. But the whole process is far more efficient and fast.&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT color=#000000 size=3&gt;&lt;FONT face=Georgia size=2&gt;So, even though datasets are great, don't use them for everything, in particular don't use them as a dictionary or a cache, if you want to find objects or records by a certain key it's far better to use a dictionary. Ditto, for XML.&lt;/FONT&gt;&lt;/FONT&gt;&lt;/P&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;/DIV&gt;&lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=451346" width="1" height="1"&gt;</description><category domain="http://weblogs.asp.net/esanchez/archive/tags/.NET/default.aspx">.NET</category><category domain="http://weblogs.asp.net/esanchez/archive/tags/C_2300_/default.aspx">C#</category></item><item><title>C# Expression Evaluators</title><link>http://weblogs.asp.net/esanchez/archive/2006/06/06/C_2300_-Expression-Evaluators.aspx</link><pubDate>Tue, 06 Jun 2006 05:30:00 GMT</pubDate><guid isPermaLink="false">c06e2b9d-981a-45b4-a55f-ab0d8bbfdc1c:450840</guid><dc:creator>Edgar Sánchez</dc:creator><slash:comments>3</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://weblogs.asp.net/esanchez/rsscomments.aspx?PostID=450840</wfw:commentRss><comments>http://weblogs.asp.net/esanchez/archive/2006/06/06/C_2300_-Expression-Evaluators.aspx#comments</comments><description>&lt;P&gt;&lt;FONT face=Georgia&gt;&lt;FONT size=2&gt;&lt;FONT color=#ff0000&gt;Warning:&lt;/FONT&gt; this is &lt;STRONG&gt;not&lt;/STRONG&gt; the usual code sample ready to be cut and pasted in your homework due for tomorrow.&lt;/FONT&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face=Georgia size=2&gt;OTOH, if you are one of those guys that just have to understand why and how you can implement an expression evaluator in C#, then&lt;/FONT&gt;&lt;FONT face=Georgia size=2&gt; boy has &lt;A href="http://www.removingalldoubt.com/"&gt;Chuck Jazdzewski&lt;/A&gt; some interesting information for you. Chuck likes to propose interesting problems/challenges (often useless yet fascinating) and then discuss at detail various approaches to the problem, in the case of expression evaluators, Chuck offers us &lt;STRONG&gt;four&lt;/STRONG&gt; alternatives:&lt;/FONT&gt;&lt;/P&gt;
&lt;OL&gt;
&lt;LI&gt;&lt;FONT face=Georgia size=2&gt;The classic &lt;A href="http://www.removingalldoubt.com/permalink.aspx/e6fb6ded-a66f-4707-97e7-0edaa04b30d9"&gt;procedural solution&lt;/A&gt; (á la plain old Visual Basic)&lt;/FONT&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;FONT face=Georgia size=2&gt;The&amp;nbsp;&lt;A href="http://www.removingalldoubt.com/permalink.aspx/eb49ee14-56da-410b-93d4-bd39e88d54d7"&gt;object oriented solution&lt;/A&gt; (at the best 199x Smalltalk/Java style)&lt;/FONT&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;FONT face=Georgia size=2&gt;The&amp;nbsp;&lt;A href="http://www.removingalldoubt.com/permalink.aspx/861feae8-2404-4044-b661-aa13d432b08d"&gt;visitor pattern solution&lt;/A&gt; (for&amp;nbsp;the guys&amp;nbsp;one stair above average Java or C# programmers)&lt;/FONT&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;FONT face=Georgia size=2&gt;The &lt;A href="http://www.removingalldoubt.com/permalink.aspx/bece3be7-04a1-4130-b1ac-0b88c94e7708"&gt;layered solution using partial classes&lt;/A&gt; (for the neoteric programmers using C# 2.0 or VB.NET 2005)&lt;/FONT&gt;&lt;/LI&gt;&lt;/OL&gt;
&lt;P&gt;&lt;FONT face=Georgia size=2&gt;As I said, don't expect a complete solution ready to be run but some pseudo-code and an interesting discussion of pros and cons. It may not help you with tomorrow's homework but it sure will help you impress the geek gal on the next cubicle.&lt;/FONT&gt;&lt;/P&gt;&lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=450840" width="1" height="1"&gt;</description><category domain="http://weblogs.asp.net/esanchez/archive/tags/C_2300_/default.aspx">C#</category><category domain="http://weblogs.asp.net/esanchez/archive/tags/General+Software+Development/default.aspx">General Software Development</category></item></channel></rss>