<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://blogs.msdn.com/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>Jomo Fisher -- Sharp Things : Puzzle</title><link>http://blogs.msdn.com/jomo_fisher/archive/tags/Puzzle/default.aspx</link><description>Tags: Puzzle</description><dc:language>en-US</dc:language><generator>CommunityServer 2.1 SP1 (Build: 61025.2)</generator><item><title>Tight Code--A Puzzle in F#</title><link>http://blogs.msdn.com/jomo_fisher/archive/2007/11/17/tight-code-a-puzzle-in-f.aspx</link><pubDate>Sat, 17 Nov 2007 22:37:51 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:6342674</guid><dc:creator>Jomo Fisher</dc:creator><slash:comments>39</slash:comments><comments>http://blogs.msdn.com/jomo_fisher/comments/6342674.aspx</comments><wfw:commentRss>http://blogs.msdn.com/jomo_fisher/commentrss.aspx?PostID=6342674</wfw:commentRss><description>&lt;p&gt;Jomo Fisher--Luke Hoban wrote something in a &lt;a href="http://blogs.msdn.com/lukeh/archive/2007/11/14/f.aspx"&gt;blog entry&lt;/a&gt; that resonated with me:&lt;/p&gt; &lt;blockquote&gt; &lt;p&gt;One of the most striking features of F# code is that it is very terse - ideas can typically be expressed with a small amount of code.&amp;nbsp; &lt;/p&gt;&lt;/blockquote&gt; &lt;p&gt;Don Syme once mentioned (I'm paraphrasing) that an aspirational goal for F# in the beginning was to make a compiler that could compile itself in less than 10,000 lines of code. Though that line count has since been passed I often get the sense that, with enough thought, I could boil whatever code I'm working on down to almost nothing.&lt;/p&gt; &lt;p&gt;Consider this coding problem (which I have since used as an interview question). Take a singly-linked-list of singly-linked-lists and pivot the inner values. For example say I have this list:&lt;/p&gt; &lt;blockquote&gt; &lt;p&gt;&lt;span style="font-size: 10pt; color: blue; font-family: 'Courier New'"&gt;let&lt;/span&gt;&lt;span style="font-size: 10pt; font-family: 'Courier New'"&gt; have = [['a';'b';'1'];['c';'d';'2'];['e';'f';'3']]&lt;/span&gt;&lt;/p&gt;&lt;/blockquote&gt; &lt;p&gt;Then the list I want is this:&lt;/p&gt; &lt;blockquote&gt; &lt;p&gt;&lt;span style="font-size: 10pt; color: blue; font-family: 'Courier New'"&gt;let&lt;/span&gt;&lt;span style="font-size: 10pt; font-family: 'Courier New'"&gt; want = [['a';'c';'e'];['b';'d';'f'];['1';'2';'3']]&lt;/span&gt;&lt;/p&gt;&lt;/blockquote&gt; &lt;p&gt;So the new list's first list has the first item from each of the original inner lists and so on. This problem actually came up in real-world piece of code I was working on. My first cut was procedural and about twenty lines of code. I don't have it here to show you, but after a few iterations and refactorings I got it down to a respectable nine lines:&lt;/p&gt; &lt;blockquote&gt; &lt;p class="MsoNormal"&gt;&lt;span style="font-size: 10pt; color: blue; font-family: 'Courier New'"&gt;let&lt;/span&gt;&lt;span style="font-size: 10pt; font-family: 'Courier New'"&gt; flatteninto source target = &lt;/span&gt;&lt;/p&gt; &lt;p class="MsoNormal"&gt;&lt;span style="font-size: 10pt; font-family: 'Courier New'"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; List.zip target source |&amp;gt; List.map(&lt;span style="color: blue"&gt;fun&lt;/span&gt; (head, tail)&lt;span style="color: blue"&gt;-&amp;gt;&lt;/span&gt;head@[tail])&lt;/span&gt;&lt;/p&gt; &lt;p class="MsoNormal"&gt;&lt;span style="font-size: 10pt; color: blue; font-family: 'Courier New'"&gt;let&lt;/span&gt;&lt;span style="font-size: 10pt; font-family: 'Courier New'"&gt; pivot list = &lt;/span&gt;&lt;/p&gt; &lt;p class="MsoNormal"&gt;&lt;span style="font-size: 10pt; font-family: 'Courier New'"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue"&gt;let&lt;/span&gt; &lt;span style="color: blue"&gt;rec&lt;/span&gt; work target = &lt;span style="color: blue"&gt;function&lt;/span&gt;&lt;/span&gt;&lt;/p&gt; &lt;p class="MsoNormal"&gt;&lt;span style="font-size: 10pt; font-family: 'Courier New'"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; head::tail&lt;span style="color: blue"&gt;-&amp;gt;&lt;/span&gt; work (flatteninto head target) tail&lt;/span&gt;&lt;/p&gt; &lt;p class="MsoNormal"&gt;&lt;span style="font-size: 10pt; font-family: 'Courier New'"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; | [] &lt;span style="color: blue"&gt;-&amp;gt;&lt;/span&gt; target&lt;/span&gt;&lt;/p&gt; &lt;p class="MsoNormal"&gt;&lt;span style="font-size: 10pt; font-family: 'Courier New'"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue"&gt;let&lt;/span&gt; empties = list|&amp;gt;List.map(&lt;span style="color: blue"&gt;fun&lt;/span&gt; l&lt;span style="color: blue"&gt;-&amp;gt;&lt;/span&gt;[])&lt;/span&gt;&lt;/p&gt; &lt;p class="MsoNormal"&gt;&lt;span style="font-size: 10pt; font-family: 'Courier New'"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; work empties list&lt;/span&gt;&lt;/p&gt;&lt;/blockquote&gt; &lt;p&gt;At this point, I was stuck. It worked, but it seemed like there should be a better solution. In particular, the second to last line where I build up a list of empty lists didn't seem quite right. Being stuck, I asked my teammates whether there was a better solution out there. As it turns out, James Margetson had seen a beautiful four line solution to the problem.&lt;/p&gt; &lt;p&gt;I'll post the solution James showed me in a few days. In the meantime, I'd like to invite you to give the problem a try in the programming language of your choice. Can you cleanly beat my nine-line solution above? Can you get it down to four lines? I only ask that you don't change the input structure--singly-linked-list of singly-linked-list. Also, in my problem, the input was guaranteed to be well formed so I didn't need to check for jagged inner lists or other malformed inputs. Finally, notice that while I showed a 3x3 input in the example the dimensions don't have to be the same.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Update 11/20/2007 - Spoiler Alert!&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;As promised, here's the F# that James showed me&lt;/p&gt; &lt;p class="MsoNormal" style="margin: 0in 0in 0pt"&gt;&lt;span style="font-size: 9pt; color: blue; font-family: 'Courier New'"&gt;let&lt;/span&gt;&lt;span style="font-size: 9pt; font-family: 'Courier New'"&gt;&lt;font color="#000000"&gt; &lt;/font&gt;&lt;span style="color: blue"&gt;rec&lt;/span&gt;&lt;font color="#000000"&gt; transpose haves =&lt;?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" /&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/font&gt;&lt;/span&gt;&lt;/p&gt; &lt;p class="MsoNormal" style="margin: 0in 0in 0pt"&gt;&lt;span style="font-size: 9pt; font-family: 'Courier New'"&gt;&lt;font color="#000000"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/font&gt;&lt;span style="color: blue"&gt;match&lt;/span&gt;&lt;font color="#000000"&gt; haves &lt;/font&gt;&lt;span style="color: blue"&gt;with&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt; &lt;p class="MsoNormal" style="margin: 0in 0in 0pt"&gt;&lt;span style="font-size: 9pt; font-family: 'Courier New'"&gt;&lt;font color="#000000"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; | (_::_)::_ &lt;/font&gt;&lt;span style="color: blue"&gt;-&amp;gt;&lt;/span&gt;&lt;font color="#000000"&gt; map hd haves :: transpose (map tl haves)&lt;o:p&gt;&lt;/o:p&gt;&lt;/font&gt;&lt;/span&gt;&lt;/p&gt; &lt;p class="MsoNormal" style="margin: 0in 0in 0pt"&gt;&lt;span style="font-size: 9pt; font-family: 'Courier New'"&gt;&lt;font color="#000000"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; | _&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/font&gt;&lt;span style="color: blue"&gt;-&amp;gt;&lt;/span&gt;&lt;font color="#000000"&gt; []&lt;o:p&gt;&lt;/o:p&gt;&lt;/font&gt;&lt;/span&gt;&lt;/p&gt; &lt;p&gt; &lt;p&gt;This is essentially the same as the Haskell algorithm that has been posted in the comments. &lt;/p&gt; &lt;p&gt;I want to thank the folks who posted solutions in various different languages--Scheme, Haskell, Ruby, C#, Python. Also, there was an OCaml solution which is indeed compatible with F#.&lt;/p&gt; &lt;p&gt;Several folks pointed out the analogy with matrix transpose. The code does get a lot easier when your input is an array of arrays, but you don't always get to pick your input representation.&lt;/p&gt; &lt;p&gt;One commenter opined that functional code may be easier to read than it is to write. This is true for me in one sense: there seems to always be a way to write the code a little better. Figuring out when I'm done is a challenge.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&lt;span lang="EN" style="mso-ansi-language: en; mso-ascii-font-family: calibri; mso-hansi-font-family: calibri"&gt;&lt;font face="Calibri" size="3"&gt;This posting is provided "AS IS" with no warranties, and confers no rights.&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=6342674" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/jomo_fisher/archive/tags/F_2300_/default.aspx">F#</category><category domain="http://blogs.msdn.com/jomo_fisher/archive/tags/Puzzle/default.aspx">Puzzle</category></item></channel></rss>