<?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>LAMBDAPHONE &#187; short</title>
	<atom:link href="http://coder.bsimmons.name/blog/tag/short/feed/" rel="self" type="application/rss+xml" />
	<link>http://coder.bsimmons.name/blog</link>
	<description>fragmentary ideas  ䷿  intellectual what-nots  ䷷  and haskell programming  ䷴</description>
	<lastBuildDate>Tue, 27 Jul 2010 16:58:03 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.1</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>17&#215;17: Symmetric Single-Colorings and some Graph Theory</title>
		<link>http://coder.bsimmons.name/blog/2010/03/17x17-symmetric-single-colorings-and-some-graph-theory/</link>
		<comments>http://coder.bsimmons.name/blog/2010/03/17x17-symmetric-single-colorings-and-some-graph-theory/#comments</comments>
		<pubDate>Sun, 14 Mar 2010 17:44:07 +0000</pubDate>
		<dc:creator>jberryman</dc:creator>
				<category><![CDATA[haskell]]></category>
		<category><![CDATA[17x17]]></category>
		<category><![CDATA[Graph Theory]]></category>
		<category><![CDATA[short]]></category>

		<guid isPermaLink="false">http://coder.bsimmons.name/blog/?p=355</guid>
		<description><![CDATA[<blockquote><p><em>Note: this is part of a <a href="http://coder.bsimmons.name/blog/tag/17x17/">series of posts</a> is related to the &#8220;<a href="http://blog.computationalcomplexity.org/2009/11/17x17-challenge-worth-28900-this-is-not.html">17&#215;17 Challenge</a>&#8221; posted by Bill Gasarch. The goal is to color cells of a 17 by 17 grid, using only four colors, such that no</em></p></blockquote><p>&#8230; <a href="http://coder.bsimmons.name/blog/2010/03/17x17-symmetric-single-colorings-and-some-graph-theory/" class="read_more">   [ R E A D &#124; M O R E ]</a></p>]]></description>
			<content:encoded><![CDATA[<blockquote><p><em>Note: this is part of a <a href="http://coder.bsimmons.name/blog/tag/17x17/">series of posts</a> is related to the &#8220;<a href="http://blog.computationalcomplexity.org/2009/11/17x17-challenge-worth-28900-this-is-not.html">17&#215;17 Challenge</a>&#8221; posted by Bill Gasarch. The goal is to color cells of a 17 by 17 grid, using only four colors, such that no rectangle is formed from four cells of the same color.</em></p></blockquote>
<p>In my <a href="http://coder.bsimmons.name/blog/2010/03/17x17-some-thoughts-on-the-problem/">last post</a> I noticed that all of the smaller optimal single-colorings I generated showed diagonal symmetry, meaning that row 1 is the same as column 1, row 8 is the same as column 8, etc. It&#8217;s my hypothesis that all complete single-colorings are symmetrical in this way. </p>
<p>I decided to play with making the known 74-cell subset symmetrical by applying rotations and came up with this:</p>
<blockquote><p><iframe width='425' height='400' frameborder='0' src='http://spreadsheets.google.com/pub?key=t-3KjM7Nt7-9AmYg9uCi5Xg&#038;single=true&#038;gid=0&#038;output=html&#038;widget=true'></iframe></p></blockquote>
<p><span id="more-355"></span></p>
<p>Figuring out an <a href="http://en.wikipedia.org/wiki/Graph_automorphism">automorphism</a> that would give me that diagonal symmetry was easier than inputting the original points into Google Spreadsheet. The colors show the hints that helped anchor the rotations. (I&#8217;m going to try to come up with an algorithm for permuting a grid into a symmetrical form).</p>
<p>It seems that symmetry is a very interesting quality in a <a href="http://en.wikipedia.org/wiki/Graph_%28mathematics%29">graph</a>, but when the Graph Theorists study <a href="http://en.wikipedia.org/wiki/Symmetric_graph">symmetric graphs</a>, they are looking at graphs with where (as I understand it)</p>
<blockquote><p>
any two linked vertices can be mapped onto any to other linked vertices, resulting in essentially the same graph</p></blockquote>
<p>&#8230;which is much cooler. Another interesting thing to mention is that a valid coloring is essentially a <a href="http://en.wikipedia.org/wiki/Hypergraph">hypergraph</a> where the higher dimensional edges are the row/column relationship. It can be flattened into a graph in any number of ways, for example by connecting every colored cell with it&#8217;s four neighbors (possibly itself).</p>
<p>So up next for me is a brute force algorithm for single-colorings generated symmetrically. </p>
]]></content:encoded>
			<wfw:commentRss>http://coder.bsimmons.name/blog/2010/03/17x17-symmetric-single-colorings-and-some-graph-theory/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>An alternative definition for Data.List.groupBy</title>
		<link>http://coder.bsimmons.name/blog/2010/02/an-alternative-definition-for-datalistgroupby/</link>
		<comments>http://coder.bsimmons.name/blog/2010/02/an-alternative-definition-for-datalistgroupby/#comments</comments>
		<pubDate>Wed, 10 Feb 2010 18:15:50 +0000</pubDate>
		<dc:creator>jberryman</dc:creator>
				<category><![CDATA[haskell]]></category>
		<category><![CDATA[data]]></category>
		<category><![CDATA[library]]></category>
		<category><![CDATA[short]]></category>
		<category><![CDATA[sorting]]></category>

		<guid isPermaLink="false">http://coder.bsimmons.name/blog/?p=318</guid>
		<description><![CDATA[<p>The function <a href="http://haskell.org/ghc/docs/latest/html/libraries/base-4.2.0.0/Data-List.html#v:groupBy"><code>groupBy</code></a> from haskell&#8217;s standard library is defined in terms of <code>span</code>, the effect being that the supplied predicate function is used to compare the first element of a group with successive elements.</p>
<p>This isn&#8217;t clear from the&#8230; <a href="http://coder.bsimmons.name/blog/2010/02/an-alternative-definition-for-datalistgroupby/" class="read_more">   [ R E A D &#124; M O R E ]</a></p>]]></description>
			<content:encoded><![CDATA[<p>The function <a href="http://haskell.org/ghc/docs/latest/html/libraries/base-4.2.0.0/Data-List.html#v:groupBy"><code>groupBy</code></a> from haskell&#8217;s standard library is defined in terms of <code>span</code>, the effect being that the supplied predicate function is used to compare the first element of a group with successive elements.</p>
<p>This isn&#8217;t clear from the docs, and you might try to do this and wonder at the output you got:</p>
<blockquote><pre>*Main> groupBy (< =) [3,4,5,3,2,1,4,4,1,1,2,3,4,5,4,5,6,7]
[[3,4,5,3],[2],[1,4,4,1,1,2,3,4,5,4,5,6,7]]</pre>
</pre>
</blockquote>
<p><span id="more-318"></span></p>
<p>We can redefine <code>groupBy</code> as follows, so that the supplied predicate function compares adjacent elements one-by-one and returns <code>True</code> if they should be grouped together:</p>
<p><blockquote class="vimblock"><br />
<span class="Comment">&gt;</span>&nbsp;groupBy' <span class="Statement">::</span>&nbsp;(a&nbsp;<span class="Statement">-&gt;</span>&nbsp;a&nbsp;<span class="Statement">-&gt;</span>&nbsp;<span class="Type">Bool</span>)&nbsp;<span class="Statement">-&gt;</span>&nbsp;[a]&nbsp;<span class="Statement">-&gt;</span>&nbsp;[[a]]<br />
<span class="Comment">&gt;</span>&nbsp;groupBy' c&nbsp;[]&nbsp;&nbsp;&nbsp;&nbsp; <span class="Statement">=</span>&nbsp;[]<br />
<span class="Comment">&gt;</span>&nbsp;groupBy' c&nbsp;(a<span class="Statement">:</span>as)&nbsp;<span class="Statement">=</span>&nbsp;(a<span class="Statement">:</span>ys)&nbsp;<span class="Statement">:</span>&nbsp;groupBy' c&nbsp;zs<br />
<span class="Comment">&gt;</span>&nbsp;&nbsp;&nbsp;&nbsp; <span class="Type">where</span>&nbsp;(ys,zs)&nbsp;<span class="Statement">=</span>&nbsp;spanC&nbsp;a&nbsp;as<br />
<span class="Comment">&gt;</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; spanC&nbsp;_&nbsp;&nbsp;[]&nbsp;&nbsp;&nbsp;&nbsp;<span class="Statement">=</span>&nbsp;([],&nbsp;[])<br />
<span class="Comment">&gt;</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; spanC&nbsp;a' (x<span class="Statement">:</span>xs)<br />
<span class="Comment">&gt;</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span class="Statement">|</span>&nbsp;a' <span class="Statement">`c`</span>&nbsp;x&nbsp;&nbsp; <span class="Statement">=</span>&nbsp;<span class="Statement">let</span>&nbsp;(ps,qs)&nbsp;<span class="Statement">=</span>&nbsp;spanC&nbsp;x&nbsp;xs&nbsp;<br />
<span class="Comment">&gt;</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="Statement">in</span>&nbsp;(x<span class="Statement">:</span>ps,qs)<br />
<span class="Comment">&gt;</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span class="Statement">|</span>&nbsp;<span class="Identifier">otherwise</span>&nbsp;<span class="Statement">=</span>&nbsp;([],&nbsp;x<span class="Statement">:</span>xs)<br />
<br /></blockquote></p>
<p>Now we can use the <code>groupBy</code> function to return a list of ascending lists, like we (probably) wanted:</p>
<blockquote><pre>*Main> groupBy' (< =) [3,4,5,3,2,1,4,4,1,1,2,3,4,5,4,5,6,7]
[[3,4,5],[3],[2],[1,4,4],[1,1,2,3,4,5],[4,5,6,7]]</pre>
</pre>
</blockquote>
<p>The functionality is of course the same for <code>groupBy (==)</code>.</p>
]]></content:encoded>
			<wfw:commentRss>http://coder.bsimmons.name/blog/2010/02/an-alternative-definition-for-datalistgroupby/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>The Definition of Data.List.group</title>
		<link>http://coder.bsimmons.name/blog/2010/02/the-definition-of-datalistgroup/</link>
		<comments>http://coder.bsimmons.name/blog/2010/02/the-definition-of-datalistgroup/#comments</comments>
		<pubDate>Sat, 06 Feb 2010 16:00:40 +0000</pubDate>
		<dc:creator>jberryman</dc:creator>
				<category><![CDATA[haskell]]></category>
		<category><![CDATA[data]]></category>
		<category><![CDATA[library]]></category>
		<category><![CDATA[short]]></category>

		<guid isPermaLink="false">http://coder.bsimmons.name/blog/?p=312</guid>
		<description><![CDATA[<p>I&#8217;ve been thinking quite a bit lately about a category of functions that are always a bit awkward to define: they involve cases where we would like to traverse a recursive data structure and do something with the data that&#8230; <a href="http://coder.bsimmons.name/blog/2010/02/the-definition-of-datalistgroup/" class="read_more">   [ R E A D &#124; M O R E ]</a></p>]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve been thinking quite a bit lately about a category of functions that are always a bit awkward to define: they involve cases where we would like to traverse a recursive data structure and do something with the data that we have passed over but which is &#8220;gone now&#8221;.<br />
<span id="more-312"></span><br />
There are many examples of functions like these in the haskell standard libraries: <code><a href="http://haskell.org/ghc/docs/latest/html/libraries/base-4.2.0.0/src/GHC-List.html#span">span</a></code>, <code><a href="http://haskell.org/ghc/docs/latest/html/libraries/base-4.2.0.0/src/GHC-List.html#splitAt">splitAt</a></code>, etc.</p>
<p>A function like <code>group</code> is in this category. It&#8217;s conceptually very simple, but defining it actually requires a bit of indirection. Here I&#8217;ve translated the definition from <code>Data.List</code> to use explicit recursion:</p>
<p><blockquote class="vimblock"><br />
<span class="lnr">66 </span><span class="Comment">&gt;</span>&nbsp;group&nbsp;<span class="Statement">::</span>&nbsp;(<span class="Type">Eq</span>&nbsp;a)&nbsp;<span class="Statement">=&gt;</span>&nbsp;[a]&nbsp;<span class="Statement">-&gt;</span>&nbsp;[[a]]<br />
<span class="lnr">67 </span><span class="Comment">&gt;</span>&nbsp;group&nbsp;[]&nbsp;&nbsp;&nbsp;&nbsp; <span class="Statement">=</span>&nbsp;[]<br />
<span class="lnr">68 </span><span class="Comment">&gt;</span>&nbsp;group&nbsp;(a<span class="Statement">:</span>as)&nbsp;<span class="Statement">=</span>&nbsp;(a<span class="Statement">:</span>ys)&nbsp;<span class="Statement">:</span>&nbsp;group&nbsp;zs<br />
<span class="lnr">69 </span><span class="Comment">&gt;</span>&nbsp;&nbsp;&nbsp;&nbsp; <span class="Type">where</span>&nbsp;(ys,zs)&nbsp;<span class="Statement">=</span>&nbsp;spanEq&nbsp;as<br />
<span class="lnr">70 </span><span class="Comment">&gt;</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; spanEq&nbsp;[]&nbsp;&nbsp;&nbsp;&nbsp; <span class="Statement">=</span>&nbsp;([],&nbsp;[])<br />
<span class="lnr">71 </span><span class="Comment">&gt;</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; spanEq&nbsp;(x<span class="Statement">:</span>xs)<br />
<span class="lnr">72 </span><span class="Comment">&gt;</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span class="Statement">|</span>&nbsp;a&nbsp;<span class="Statement">==</span>&nbsp;x&nbsp;&nbsp;&nbsp;&nbsp;<span class="Statement">=</span>&nbsp;<span class="Statement">let</span>&nbsp;(ps,qs)&nbsp;<span class="Statement">=</span>&nbsp;spanEq&nbsp;xs&nbsp;<br />
<span class="lnr">73 </span><span class="Comment">&gt;</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="Statement">in</span>&nbsp;(x<span class="Statement">:</span>ps,qs)<br />
<span class="lnr">74 </span><span class="Comment">&gt;</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span class="Statement">|</span>&nbsp;<span class="Identifier">otherwise</span>&nbsp;<span class="Statement">=</span>&nbsp;([],&nbsp;x<span class="Statement">:</span>xs)<br />
<span class="lnr">75 </span><br />
<br /></blockquote></p>
<p>I think if I were asked to define this having never seen it, the first thing I would think of would be something using <code>foldl1</code>, which wouldn&#8217;t work.</p>
<p><em><strong>EDIT</strong>:</em> see also <a href="http://coder.bsimmons.name/blog/2010/02/an-alternative-definition-for-datalistgroupby/">an alternative definition for Data.List.groupBy</a></p>
]]></content:encoded>
			<wfw:commentRss>http://coder.bsimmons.name/blog/2010/02/the-definition-of-datalistgroup/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Find a permutation given its Inversion Table</title>
		<link>http://coder.bsimmons.name/blog/2009/11/find-a-permutation-given-its-inversion-table/</link>
		<comments>http://coder.bsimmons.name/blog/2009/11/find-a-permutation-given-its-inversion-table/#comments</comments>
		<pubDate>Sun, 15 Nov 2009 19:04:22 +0000</pubDate>
		<dc:creator>jberryman</dc:creator>
				<category><![CDATA[haskell]]></category>
		<category><![CDATA[algorithm]]></category>
		<category><![CDATA[short]]></category>
		<category><![CDATA[sorting]]></category>

		<guid isPermaLink="false">http://coder.bsimmons.name/blog/?p=284</guid>
		<description><![CDATA[<p>Here is some code I whipped up in response to an <a href="http://www.reddit.com/r/coding/comments/a3ckw/programming_problem_find_a_permutation_given_its/">interesting problem posted on reddit.com/r/coding/</a>. It was a really interesting algorithm to work out:</p>
<p><blockquote class="vimblock"><br />
<br />
<span class="PreProc">import</span>&#160;Data.List (sortBy)<br />
<br />
<span class="Comment">-- takes an inversion list and converts</span></blockquote>&#8230; <a href="http://coder.bsimmons.name/blog/2009/11/find-a-permutation-given-its-inversion-table/" class="read_more">   [ R E A D &#124; M O R E ]</a></p>]]></description>
			<content:encoded><![CDATA[<p>Here is some code I whipped up in response to an <a href="http://www.reddit.com/r/coding/comments/a3ckw/programming_problem_find_a_permutation_given_its/">interesting problem posted on reddit.com/r/coding/</a>. It was a really interesting algorithm to work out:</p>
<p><blockquote class="vimblock"><br>
<br>
<span class="PreProc">import</span>&nbsp;Data.List (sortBy)<br>
<br>
<span class="Comment">-- takes an inversion list and converts it to the list of permuted</span><br>
<span class="Comment">-- elements:</span><br>
decode&nbsp;<span class="Statement">=</span>&nbsp;dec&nbsp;[]&nbsp;<span class="Statement">.</span>&nbsp;sortBy&nbsp;lowHi&nbsp;<span class="Statement">.</span>&nbsp;<span class="Identifier">zip</span>&nbsp;[<span class="Constant">1</span><span class="Statement">..</span>]&nbsp;&nbsp;<span class="Type">where</span><br>
&nbsp;&nbsp;&nbsp;&nbsp;dec&nbsp;as&nbsp;[]&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span class="Statement">=</span>&nbsp;as<br>
&nbsp;&nbsp;&nbsp;&nbsp;dec&nbsp;as&nbsp;((a,_)<span class="Statement">:</span>is)&nbsp;<span class="Statement">=</span>&nbsp;<span class="Statement">let</span>&nbsp;is' <span class="Statement">=</span>&nbsp;sortBy&nbsp;lowHi&nbsp;(decrementGT&nbsp;a&nbsp;is)<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span class="Statement">in</span>&nbsp;dec&nbsp;(a<span class="Statement">:</span>as)&nbsp;is'<br>
<br>
<span class="Comment">-- decrement every inversion number by 1, for every tuple in which</span><br>
<span class="Comment">-- the element is greater than `a`:</span><br>
decrementGT&nbsp;a&nbsp;<span class="Statement">=</span>&nbsp;<span class="Identifier">map</span>&nbsp;(<span class="Statement">\</span>(a',i)&nbsp;<span class="Statement">-&gt;</span>&nbsp;(a',&nbsp;<span class="Statement">if</span>&nbsp;a'<span class="Statement">&gt;</span>a&nbsp;<span class="Statement">then</span>&nbsp;i<span class="Statement">-</span><span class="Constant">1</span>&nbsp;<span class="Statement">else</span>&nbsp;i)&nbsp;)<br>
<br>
<span class="Comment">-- we sort by the inversion number, low to high. For elements with</span><br>
<span class="Comment">-- the same inversion number, we say that the greater element tuple</span><br>
<span class="Comment">-- should go before a lesser element:</span><br>
lowHi&nbsp;(a,i)&nbsp;(a',i')&nbsp;<br>
&nbsp;&nbsp;&nbsp;&nbsp;<span class="Statement">|</span>&nbsp;i&nbsp;<span class="Statement">==</span>&nbsp;i'&nbsp;&nbsp; <span class="Statement">=</span>&nbsp;<span class="Statement">if</span>&nbsp;a<span class="Statement">&gt;</span>a' <span class="Statement">then</span>&nbsp;<span class="Constant">LT</span>&nbsp;<span class="Statement">else</span>&nbsp;<span class="Constant">GT</span><br>
&nbsp;&nbsp;&nbsp;&nbsp;<span class="Statement">|</span>&nbsp;<span class="Identifier">otherwise</span>&nbsp;<span class="Statement">=</span>&nbsp;<span class="Identifier">compare</span>&nbsp;i&nbsp;i'<br>
<br></blockquote></p>
<p>It&#8217;s not the prettiest code I&#8217;ve written, but it&#8217;s pretty straight-forward and concise. Thanks for looking!</p>
]]></content:encoded>
			<wfw:commentRss>http://coder.bsimmons.name/blog/2009/11/find-a-permutation-given-its-inversion-table/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>The move-to-front (MTF) Transform</title>
		<link>http://coder.bsimmons.name/blog/2009/11/the-move-to-front-mtf-transform/</link>
		<comments>http://coder.bsimmons.name/blog/2009/11/the-move-to-front-mtf-transform/#comments</comments>
		<pubDate>Tue, 10 Nov 2009 13:06:35 +0000</pubDate>
		<dc:creator>jberryman</dc:creator>
				<category><![CDATA[haskell]]></category>
		<category><![CDATA[algorithm]]></category>
		<category><![CDATA[compression]]></category>
		<category><![CDATA[data]]></category>
		<category><![CDATA[short]]></category>

		<guid isPermaLink="false">http://coder.bsimmons.name/blog/?p=265</guid>
		<description><![CDATA[<p>To follow up my last <a href="http://coder.bsimmons.name/blog/2009/11/polishing-a-functional-pearl-the-burrows-wheeler-transform/">post about the Burrows-Wheeler Transform</a>, I decided to implement another simple algorithm which is often used after the BWT to help consolidate localized redundancy in the data before entropy encoding.</p>
<p>The idea behind the&#8230; <a href="http://coder.bsimmons.name/blog/2009/11/the-move-to-front-mtf-transform/" class="read_more">   [ R E A D &#124; M O R E ]</a></p>]]></description>
			<content:encoded><![CDATA[<p>To follow up my last <a href="http://coder.bsimmons.name/blog/2009/11/polishing-a-functional-pearl-the-burrows-wheeler-transform/">post about the Burrows-Wheeler Transform</a>, I decided to implement another simple algorithm which is often used after the BWT to help consolidate localized redundancy in the data before entropy encoding.</p>
<p>The idea behind the <a href="http://www.data-compression.info/Algorithms/MTF/index.htm">Move-to-Front algorithm</a> is that we start with some known alphabet (like the list of ASCII characters), and encode our data elements as the <em>index into that alphabet list</em> of each element. The trick is that after each character is encoded, the alphabet list is modified by <strong>moving</strong> the element whose index we just looked up <strong>to the front</strong> of the alphabet.</p>
<p>Here are my implementations of encode and decode:</p>
<p><blockquote class="vimblock"><br>
<span class="PreProc">import</span>&nbsp;Data.List<br>
<br>
<br>
mtf&nbsp;<span class="Statement">::</span>&nbsp;(<span class="Type">Eq</span>&nbsp;a,&nbsp;<span class="Type">Bounded</span>&nbsp;a,&nbsp;<span class="Type">Enum</span>&nbsp;a)<span class="Statement">=&gt;</span>&nbsp;[a]&nbsp;<span class="Statement">-&gt;</span>&nbsp;<span class="Type">Maybe</span>&nbsp;[<span class="Type">Int</span>]<br>
mtf&nbsp;<span class="Statement">=</span>&nbsp;<span class="Identifier">sequence</span>&nbsp;<span class="Statement">.</span>&nbsp;<span class="Identifier">snd</span>&nbsp;<span class="Statement">.</span>&nbsp;mapAccumL&nbsp;enc&nbsp;[&nbsp;<span class="Identifier">minBound</span><span class="Statement">..</span>&nbsp;]<br>
&nbsp;&nbsp;&nbsp;&nbsp;<span class="Type">where</span>&nbsp;enc&nbsp;l&nbsp;x&nbsp;<span class="Statement">=</span>&nbsp;(x<span class="Statement">:</span>delete&nbsp;x&nbsp;l,&nbsp;elemIndex&nbsp;x&nbsp;l)<br>
<br>
<br>
mtfD&nbsp;<span class="Statement">::</span>&nbsp;(<span class="Type">Eq</span>&nbsp;a,&nbsp;<span class="Type">Bounded</span>&nbsp;a,&nbsp;<span class="Type">Enum</span>&nbsp;a)<span class="Statement">=&gt;</span>&nbsp;[<span class="Type">Int</span>]&nbsp;<span class="Statement">-&gt;</span>&nbsp;[a]<br>
mtfD&nbsp;<span class="Statement">=</span>&nbsp;<span class="Identifier">snd</span>&nbsp;<span class="Statement">.</span>&nbsp;mapAccumL&nbsp;dec&nbsp;[&nbsp;<span class="Identifier">minBound</span><span class="Statement">..</span>&nbsp;]<br>
&nbsp;&nbsp;&nbsp;&nbsp;<span class="Type">where</span>&nbsp;dec&nbsp;l&nbsp;i&nbsp;<span class="Statement">=</span>&nbsp;<span class="Statement">let</span>&nbsp;x&nbsp;<span class="Statement">=</span>&nbsp;l&nbsp;<span class="Statement">!!</span>&nbsp;i&nbsp;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span class="Statement">in</span>&nbsp;(x<span class="Statement">:</span>delete&nbsp;x&nbsp;l,&nbsp;x)<br>
<br></blockquote></p>
<p>The <code>mapAccumL</code> function is perfect for passing the state of the dictionary list. Another point of interest to mention is the use of <code>minBound</code> to let the function be polymorphic over any type for which there is a defined order and lowest element.</p>
<p>For example, we can do this:</p>
<blockquote><p><strong>*Main></strong> mtf &#8220;SIX.MIXED.PIXIES.SIFT.SIXTY.PIXIE.DUST.BOXES&#8221;  >>= return . mtfDec :: Maybe String<br />
<em>Just &#8220;SIX.MIXED.PIXIES.SIFT.SIXTY.PIXIE.DUST.BOXES&#8221;</em></p></blockquote>
<p>or we can decode to Word8 bytes, if we want to get back the ASCII character in that form, just by specifying a different return type:</p>
<blockquote><p><strong>*Main></strong> :m + Data.Word<br />
<strong>*Main Data.Word></strong> mtf &#8220;SIX.MIXED.PIXIES.SIFT.SIXTY.PIXIE.DUST.BOXES&#8221;  >>= return . mtfDec :: Maybe [Word8]<br />
<em>Just [83,73,88,46,77,73,88,69,68,46,80,73,88,73,69,83, 46,83,73,70,84,46,83,73,88,84,89,46,80,73,88,73,69,46, 68,85,83,84,46,66,79,88,69,83]</em>
</p></blockquote>
<p>Let me know your thoughts!</p>
]]></content:encoded>
			<wfw:commentRss>http://coder.bsimmons.name/blog/2009/11/the-move-to-front-mtf-transform/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
	</channel>
</rss>
