<?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; laziness</title>
	<atom:link href="http://coder.bsimmons.name/blog/tag/laziness/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>The Gift of Inconsistency</title>
		<link>http://coder.bsimmons.name/blog/2010/07/the-gift-of-inconsistency/</link>
		<comments>http://coder.bsimmons.name/blog/2010/07/the-gift-of-inconsistency/#comments</comments>
		<pubDate>Thu, 22 Jul 2010 23:35:23 +0000</pubDate>
		<dc:creator>jberryman</dc:creator>
				<category><![CDATA[haskell]]></category>
		<category><![CDATA[EsotericLanguages]]></category>
		<category><![CDATA[LambdaCalculus]]></category>
		<category><![CDATA[laziness]]></category>
		<category><![CDATA[recursion]]></category>
		<category><![CDATA[theory]]></category>

		<guid isPermaLink="false">http://coder.bsimmons.name/blog/?p=453</guid>
		<description><![CDATA[<p>Computer science is a fascinating and maddening thing. Even the most seemingly-esoteric topics turn out to be fundamental. Go out to the fringes of CS and you find yourself smack in the middle of <a href="http://en.wikipedia.org/wiki/G%C3%B6del%27s_incompleteness_theorems#Minds_and_machines">Philosophy</a>. You try to understand&#8230; <a href="http://coder.bsimmons.name/blog/2010/07/the-gift-of-inconsistency/" class="read_more">   [ R E A D &#124; M O R E ]</a></p>]]></description>
			<content:encoded><![CDATA[<p>Computer science is a fascinating and maddening thing. Even the most seemingly-esoteric topics turn out to be fundamental. Go out to the fringes of CS and you find yourself smack in the middle of <a href="http://en.wikipedia.org/wiki/G%C3%B6del%27s_incompleteness_theorems#Minds_and_machines">Philosophy</a>. You try to understand a single point and you suddenly find yourself embracing everything. </p>
<p>So this post comes from that infinitely-recursive rabbit hole of wikipedia topics I&#8217;ve been falling down for the last few weeks, and you can probably expect a few more like this one; I&#8217;ll try to keep focused.</p>
<p>We begin (as do All Good Things) with the <a href="http://en.wikipedia.org/wiki/Untyped_lambda_calculus">Untyped Lambda Calculus</a>:<br />
<span id="more-453"></span></p>
<h2>The System</h2>
<p>The lambda calculus, invented by <a href="http://en.wikipedia.org/wiki/Alonzo_Church">Alonzo Church</a>, is a formal system for modeling functional computation and logic. It has an extraordinarily simple set of semantics, has no notion of data as a separate idea, and yet (as was proven later) is Turing complete. It serves as the skeleton and sinew of the Lisp and Scheme programming languages.</p>
<p>At its invention it seems that the system sat right at the crossroads of formal logic, mathematics and computational theory and could embrace all three fields. But it quickly became apparent that there were apparent flaws with the Lambda Calculus as a universal system.</p>
<h2>The Paradox</h2>
<p>In 1935 it was shown that the lambda calculus was <em>logically inconsistent</em> by the <a href="http://en.wikipedia.org/wiki/Kleene%E2%80%93Rosser_paradox">Kleene–Rosser paradox</a>. The &#8220;paradox&#8221; is an apparently self-contradictory lambda expression, and goes like this:</p>
<p>We have a lambda calculus expression we will call <code>'k'</code>, which takes an argument, applies it to to itself, and negates (the ¬ symbol) the result (for some undefined, logical definition of &#8220;negate&#8221;). </p>
<blockquote><p>
k = λx.( ¬ (x x))
</p></blockquote>
<p>Okay, no problem. But look what happens when we apply the function <code>'k'</code> to itself:</p>
<blockquote><p>
k k = λx.( ¬ (x x)) k<br />
k k = ¬ (k k)
</p></blockquote>
<p>After we reduce the expression, we seem to be saying that <code>(k k)</code> is equal to the opposite of itself, a self-contradictory statement.</p>
<p>To address this apparent shortcoming of his system, Church went on to define a <a href="http://en.wikipedia.org/wiki/Simply_typed_lambda_calculus">typed lambda calculus</a>. This new system differentiated between function types and simple terms in order to disallow these kinds of problematic expressions.</p>
<p>But as with many paradoxes, this one was really an issue of perspective&#8230;</p>
<h2>The Foundation</h2>
<p>Church&#8217;s new &#8220;Simply Typed Lambda Calculus&#8221; had an interesting property that the untyped lambda calculus didn&#8217;t have: the <a href="http://en.wikipedia.org/wiki/Strongly_normalizing">normalization property</a>.</p>
<p>This more restricted version of the Lambda Calculus was &#8220;strongly normalizing&#8221;, meaning that any expression could be reduced to some <em>normal form</em> (i.e. a form that cannot be reduced further) through some sequence of rewrite/reduction steps. In programming terms, this means that every expression in the <em>typed</em> lambda calculus is <em>guaranteed to terminate</em>.</p>
<p>That sounds pretty damn useful until you realize that this interesting property also makes Church&#8217;s new typed version of his system <em>not Turing complete</em>! </p>
<p>To prove this is so, consider this: imagine you encoded a program in the typed lambda calculus; it searched for (and halted) when it found an integer that was greater than two, and was <em>not</em> the sum of two primes. </p>
<p>Merely being able to encode such a function would imply the function halted, thus disproving <a href="http://en.wikipedia.org/wiki/Goldbach%27s_conjecture">Goldbach&#8217;s conjecture</a>, one of the great open problems of mathematics. All without even needing to evaluate said expression! The function referred to is of course not expressible in the typed lambda calculus.</p>
<p>It turns out that an apparent logical contradiction was actual the essential secret to computation.</p>
<h3>Embracing Inconsistency</h3>
<p>When you think of the LC as a model of computation, rather than a framework for logical assertions, the Kleene–Rosser paradox becomes what we might call the &#8220;Kleene–Rosser useless function&#8221;. </p>
<p>Let&#8217;s go ahead and express a nearly identical paradox in <a href="http://en.wikipedia.org/wiki/Haskell_%28programming_language%29">haskell</a>:</p>
<blockquote><p>
k :: (Num a) => a<br />
k = negate k
</p></blockquote>
<p>Haskell has no notion of mutability, so what we are saying here is &#8220;k is the negation of itself&#8221;. No logical fallacies or great existential questions here, just an infinite loop (and not a very useful one)! </p>
<p>Let&#8217;s express another similar &#8220;paradox&#8221;, one we can actually <em>use</em>:</p>
<blockquote><p>
babble :: [ String ]<br />
babble = &#8220;blah&#8221; : babble
</p></blockquote>
<p>How can a list be equal to itself with an extra element added? Doesn&#8217;t that imply a paradox? Well I know the runtime isn&#8217;t swayed by that argument, producing an infinite stream of &#8220;blah&#8221;s. We can even <em>use</em> this stream because of haskell&#8217;s lazy evaluation strategy.</p>
<p>But note: it isn&#8217;t laziness that lets us get away with defining paradoxes; it just allows us to make use of some more blatant paradoxical expressions without them blowing up in our faces as soon as we call them.</p>
<h3>Conclusion and Further Thoughts</h3>
<p>Interestingly, there are quite a number of non-turing complete programming languages (or language subsets) that have been created both for theoretical purposes and for practical use. <a href="http://en.wikipedia.org/wiki/Charity_%28programming_language%29">Here</a> <a href="http://en.wikipedia.org/wiki/BlooP_and_FlooP">are</a> <a href="http://www-fp.cs.st-andrews.ac.uk/hume/index.shtml">a few</a>. They seem to owe their existence and usefulness to an environment of turing complete systems.</p>
<p>So does this mean that formal logic is Turing Incomplete? Let me know your thoughts, and please let me know if I harmed any knowledge in the making of this post.</p>
]]></content:encoded>
			<wfw:commentRss>http://coder.bsimmons.name/blog/2010/07/the-gift-of-inconsistency/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Lazy Arithmetic in Haskell</title>
		<link>http://coder.bsimmons.name/blog/2010/03/lazy-arithmetic-in-haskell/</link>
		<comments>http://coder.bsimmons.name/blog/2010/03/lazy-arithmetic-in-haskell/#comments</comments>
		<pubDate>Wed, 24 Mar 2010 17:24:08 +0000</pubDate>
		<dc:creator>jberryman</dc:creator>
				<category><![CDATA[haskell]]></category>
		<category><![CDATA[data]]></category>
		<category><![CDATA[hackage]]></category>
		<category><![CDATA[laziness]]></category>
		<category><![CDATA[NumericTypes]]></category>

		<guid isPermaLink="false">http://coder.bsimmons.name/blog/?p=372</guid>
		<description><![CDATA[<p><em>We don&#8217;t usually give much thought to Numeric data types beyond whether we want to work with integers or decimal numbers. And that is a shame! In this post I&#8217;ll look at how we can actually do arithmetic operations lazily,</em>&#8230; <a href="http://coder.bsimmons.name/blog/2010/03/lazy-arithmetic-in-haskell/" class="read_more">   [ R E A D &#124; M O R E ]</a></p>]]></description>
			<content:encoded><![CDATA[<p><em>We don&#8217;t usually give much thought to Numeric data types beyond whether we want to work with integers or decimal numbers. And that is a shame! In this post I&#8217;ll look at how we can actually do arithmetic operations lazily, and in the process hopefully reveal a bit about haskell&#8217;s numeric classes.</em></p>
<p><div class="vimblock"><br />
<span class="Comment">&gt;</span>&nbsp;<span class="Type">module</span>&nbsp;LazyArithmetic<br />
<span class="Comment">&gt;</span>&nbsp;&nbsp;&nbsp;&nbsp; <span class="Type">where</span><br />
<br /></div></p>
<p>We will be using <a href="http://hackage.haskell.org/package/numbers-2009.8.9">Lennart Augustsson&#8217;s <code>numbers</code> library</a> which can be installed from hackage with <a href="http://hackage.haskell.org/trac/hackage/wiki/CabalInstall">cabal-install</a>:</p>
<blockquote><p>$> cabal install numbers</p></blockquote>
<p><div class="vimblock"><br />
<span class="Comment">&gt;</span>&nbsp;<span class="PreProc">import</span>&nbsp;Data.Number.Natural<br />
<span class="Comment">&gt;</span>&nbsp;<span class="PreProc">import</span>&nbsp;Data.List(genericLength)<br />
<br /></div></p>
<p>Consider two functions: the Prelude function <code>sum</code> and <code>genericLength</code> from the List library:</p>
<p><blockquote class="vimblock"><br />
<span class="Comment"></span>&nbsp;<span class="Identifier">genericLength</span>&nbsp;<span class="Statement">::</span>&nbsp;(<span class="Type">Num</span>&nbsp;i)&nbsp;<span class="Statement">=&gt;</span>&nbsp;[b]&nbsp;<span class="Statement">-&gt;</span>&nbsp;i<br />
<span class="Comment"></span>&nbsp;<span class="Identifier">sum</span>&nbsp;<span class="Statement">::</span>&nbsp;(<span class="Type">Num</span>&nbsp;a)&nbsp;<span class="Statement">=&gt;</span>&nbsp;[a]&nbsp;<span class="Statement">-&gt;</span>&nbsp;a<br />
<br /></blockquote></p>
<p>&#8230;two simple functions that have the potential to be very expensive, depending on the length of the list and the values of the elements.<br />
<span id="more-372"></span><br />
Say for instance that all we want is to use:</p>
<p><div class="vimblock"><br />
<span class="Comment">&gt;</span>&nbsp;sumLengths&nbsp;<span class="Statement">=</span>&nbsp;<span class="Identifier">sum</span>&nbsp;<span class="Statement">.</span>&nbsp;<span class="Identifier">map</span>&nbsp;genericLength<br />
<span class="Comment">&gt;</span><br />
<span class="Comment">&gt;</span>&nbsp;checkLengths&nbsp;as&nbsp;n&nbsp;<span class="Statement">=</span>&nbsp;(sumLengths&nbsp;as&nbsp;<span class="Statement">`div`</span>&nbsp;n)&nbsp;<span class="Statement">&gt;</span>&nbsp;<span class="Constant">2</span><br />
<br /></div></p>
<p>The <code>checkLengths</code> function above has to count every element of every element of every sub-list in order to return a <code>Bool</code> value, and if any of those lists are infinite our program will never terminate:</p>
<p><div class="vimblock"><br />
<span class="Comment">&gt;</span>&nbsp;hopeless&nbsp;<span class="Statement">=</span>&nbsp;checkLengths&nbsp;[[<span class="Constant">'a'</span><span class="Statement">..</span><span class="Constant">'z'</span>],&nbsp;[<span class="Constant">'0'</span>],&nbsp;<span class="Identifier">repeat</span>&nbsp;<span class="Constant">'Z'</span>]&nbsp;&nbsp;<span class="Constant">99</span><br />
<br /></div></p>
<p><em>&#8230;or so we might think!</em></p>
<h3>Lazy Natural Numbers</h3>
<p>It turns out we can solve our seemingly hopeless situation with a type signature:</p>
<p><div class="vimblock"><br />
<span class="Comment">&gt;</span>&nbsp;sumLengths&nbsp;<span class="Statement">::</span>&nbsp;[[b]]&nbsp;<span class="Statement">-&gt;</span>&nbsp;Natural<br />
<br /></div></p>
<p>And suddenly, as if by magic:</p>
<blockquote><p><code>*LazyArithmetic> hopeless<br />
True</code></p></blockquote>
<p>What&#8217;s going on here? Well it turns out the problem is that Haskell&#8217;s built-in numeric types are boring, old-fashioned and (in some cases) just plain wrong. But let&#8217;s step behind the curtain and look at how the Data.Numbers library defines the Natural type internally:</p>
<p><blockquote class="vimblock"><br />
<span class="Comment"></span>&nbsp;<span class="Type">data</span>&nbsp;Natural&nbsp;<span class="Statement">=</span>&nbsp;Z&nbsp;<span class="Statement">|</span>&nbsp;S&nbsp;Natural<br />
<br /></blockquote></p>
<p>We see that we&#8217;re using an abstract data type to represent non-negative integers, and it looks nearly identical to our list type <code>[]</code>. The upshot of that is we gain, in our numeric type and arithmetic operations, the same type of laziness that lists afford us!</p>
<p>So in the above example, <code>hopeless</code>, we need only carry out the operations far enough to see that the result is <code>> 2</code>.</p>
<p>The numeric type in <code>Data.List.Natural</code> are actually known as <a href="http://www.haskell.org/haskellwiki/Peano_numbers">Peano numbers</a>. They are essentially just lists of units and, as you might imagine, are not the most efficient way to represent an integer.</p>
<p>But they are exactly what we want for this application. If we failed to realize that we could solve our problem with an appropriate numeric representation, we might try to rig up something like this:</p>
<p><div class="vimblock"><br />
<span class="Comment">&gt;</span>&nbsp;checkLengthsUnclear&nbsp;as&nbsp;n&nbsp;<span class="Statement">=</span>&nbsp;<span class="Identifier">not</span>&nbsp;<span class="Statement">$</span>&nbsp;<span class="Identifier">null</span>&nbsp;<span class="Statement">$</span>&nbsp;<span class="Identifier">drop</span>&nbsp;(n<span class="Statement">*</span><span class="Constant">2</span>)&nbsp;<span class="Statement">$</span>&nbsp;<span class="Identifier">concat</span>&nbsp;as<br />
<br /></div></p>
<p>&#8230;which works identically to <code>checkLengths</code> with Peano Numbers, but completely obfuscates the intention of the function. As usual laziness gives us <em>expressive power</em> rather than an efficiency boost.</p>
<h3>Limitations, Haskell&#8217;s Numeric Type Classes, and the Numeric Prelude</h3>
<p>The <code>Data.Number.Natural</code> library is convenient because it provides Num and Integral instances so we can use the the Natural type with any function that is polymorphic on those classes.</p>
<p>The problem is <a href="http://hackage.haskell.org/packages/archive/numbers/2009.8.9/doc/html/src/Data-Number-Natural.html#line-44">the Num instance</a> is incomplete and error-prone: and that&#8217;s because a <a href="http://en.wikipedia.org/wiki/Natural_number">natural numbe</a>r type <em>shouldn&#8217;t be an instance of Num</em>! We can&#8217;t negate a Natural, which in turn makes subtraction dangerous, etc.</p>
<blockquote><p><code>*LazyArithmetic> let x = 1 :: Natural; y = 2 in x - y<br />
*** Exception: Natural: (-)</code></p></blockquote>
<p>We might wish that haskell&#8217;s Numeric type classes were more expressive, allowing for more abstract numeric types. For example it might be more &#8220;haskelly&#8221; for the length function to be defined with the type:</p>
<p><blockquote class="vimblock"><br />
<span class="Comment"></span>&nbsp;<span class="Identifier">length</span>&nbsp;<span class="Statement">::</span>&nbsp;Natural&nbsp;n&nbsp;<span class="Statement">=&gt;</span>&nbsp;[a]&nbsp;<span class="Statement">-&gt;</span>&nbsp;n<br />
<br /></blockquote></p>
<p>After all we don&#8217;t use integers for boolean values as in C; we have the abstract type <code>Bool</code>. So why return an Int when a Natural type (or class) might be more expressive? The answer of course is that that gets really complicated really fast. </p>
<p>For one approach at making haskell&#8217;s numeric class hierarchy more expressive and flexible, check out the <a href="http://www.haskell.org/haskellwiki/Numeric_Prelude">Numeric Prelude</a>. It&#8217;s <a href="http://hackage.haskell.org/package/numeric-prelude">haddock documentation</a> is very thorough and an interesting read, and you can see the sheer number of design decisions necessary for such an undertaking. </p>
<p>For some other approaches and links, see <a href="http://www.haskell.org/haskellwiki/Libraries_and_tools/Mathematics#Type_class_hierarchies">here</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://coder.bsimmons.name/blog/2010/03/lazy-arithmetic-in-haskell/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>17&#215;17: Brute Force Algorithm for an Optimal Rectangle-Free Subset</title>
		<link>http://coder.bsimmons.name/blog/2010/02/17x17-brute-force-algorithm-for-an-optimal-rectangle-free-subset/</link>
		<comments>http://coder.bsimmons.name/blog/2010/02/17x17-brute-force-algorithm-for-an-optimal-rectangle-free-subset/#comments</comments>
		<pubDate>Tue, 23 Feb 2010 19:30:51 +0000</pubDate>
		<dc:creator>jberryman</dc:creator>
				<category><![CDATA[haskell]]></category>
		<category><![CDATA[17x17]]></category>
		<category><![CDATA[algorithm]]></category>
		<category><![CDATA[laziness]]></category>

		<guid isPermaLink="false">http://coder.bsimmons.name/blog/?p=333</guid>
		<description><![CDATA[<p>I&#8217;ve been making notes when I have time, on the <a href="http://blog.computationalcomplexity.org/2009/11/17x17-challenge-worth-28900-this-is-not.html">&#8220;17 x 17 challenge&#8221; </a>posted a couple months back by Bill Gasarch. I&#8217;ve been sketching out algorithms for the problem and wanted to quickly produce some optimal rectangle free&#8230; <a href="http://coder.bsimmons.name/blog/2010/02/17x17-brute-force-algorithm-for-an-optimal-rectangle-free-subset/" class="read_more">   [ R E A D &#124; M O R E ]</a></p>]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve been making notes when I have time, on the <a href="http://blog.computationalcomplexity.org/2009/11/17x17-challenge-worth-28900-this-is-not.html">&#8220;17 x 17 challenge&#8221; </a>posted a couple months back by Bill Gasarch. I&#8217;ve been sketching out algorithms for the problem and wanted to quickly produce some optimal rectangle free subsets to check my work and look at. So the code below answers the following question:</p>
<blockquote><p>
<em>Imagine an n x n grid. You can color cells of the grid such that no rectangle overlayed on the grid will have all four corners colored. Find a grid with the maximum possible colored cells.</em></p></blockquote>
<p><span id="more-333"></span><br />
So this is a quick and stupid brute force algorithm, but it let me see an optimal 6-grid, which is what I needed. First out imports:</p>
<p><blockquote class="vimblock"><br />
<span class="PreProc">import</span>&nbsp;Data.List<br />
<span class="PreProc">import</span>&nbsp;Control.Monad<br />
<span class="PreProc">import</span>&nbsp;Data.Ord<br />
<br /></blockquote></p>
<p>We&#8217;ll call a colored cell <code>True</code>, uncolored <code>False</code>:</p>
<p><blockquote class="vimblock"><br />
<span class="Type">type</span>&nbsp;Row&nbsp;<span class="Statement">=</span>&nbsp;[<span class="Type">Bool</span>]<br />
<span class="Type">type</span>&nbsp;Grid&nbsp;<span class="Statement">=</span>&nbsp;[Row]<br />
<br /></blockquote></p>
<p>Given the side length, we&#8217;ll spit out all the possible ways a row can be colored:</p>
<p><blockquote class="vimblock"><br />
allRows&nbsp;<span class="Statement">::</span>&nbsp;<span class="Type">Int</span>&nbsp;<span class="Statement">-&gt;</span>&nbsp;[Row]<br />
allRows&nbsp;<span class="Statement">=</span>&nbsp;<span class="Identifier">mapM</span>&nbsp;(<span class="Statement">\</span>a<span class="Statement">-&gt;</span>&nbsp;[a,<span class="Identifier">not</span>&nbsp;a])&nbsp;<span class="Statement">.</span>&nbsp;<span class="Identifier">flip</span>&nbsp;<span class="Identifier">replicate</span>&nbsp;<span class="Constant">True</span><br />
<br /></blockquote></p>
<p>A quick function to see if two rows form a rectangle:</p>
<p><blockquote class="vimblock"><br />
areRectFree&nbsp;<span class="Statement">::</span>&nbsp;Row&nbsp;<span class="Statement">-&gt;</span>&nbsp;Row&nbsp;<span class="Statement">-&gt;</span>&nbsp;<span class="Type">Bool</span><br />
areRectFree&nbsp;r1&nbsp;<span class="Statement">=</span>&nbsp;<span class="Identifier">not</span>&nbsp;<span class="Statement">.</span>&nbsp;<span class="Identifier">or</span>&nbsp;<span class="Statement">.</span>&nbsp;delete&nbsp;<span class="Constant">True</span>&nbsp;<span class="Statement">.</span>&nbsp;<span class="Identifier">zipWith</span>&nbsp;(<span class="Statement">&amp;&amp;</span>)&nbsp;r1<br />
<br /></blockquote></p>
<p>An ugly function to return all the n-length ordered subsets of the ordered set of rows. (Note: a grid can move about its columns and rows without changing itself fundamentally, which is why we do the extra effort to not return every n-length permutation of the rows):</p>
<p><blockquote class="vimblock"><br />
allGrids&nbsp;<span class="Statement">::</span>&nbsp;<span class="Type">Int</span>&nbsp;<span class="Statement">-&gt;</span>&nbsp;[Grid]<br />
allGrids&nbsp;n&nbsp;<span class="Statement">=</span>&nbsp;allSubsets&nbsp;n&nbsp;(<span class="Constant">2</span><span class="Statement">^</span>n)&nbsp;(allRows&nbsp;n)&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;<span class="Type">where</span>&nbsp;allSubsets&nbsp;<span class="Constant">0</span>&nbsp;_&nbsp;_&nbsp;<span class="Statement">=</span>&nbsp;[[]]<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;allSubsets&nbsp;ln&nbsp;(i<span class="Statement">+</span><span class="Constant">1</span>)&nbsp;(r<span class="Statement">:</span>rs)&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="Statement">|</span>&nbsp;ln&nbsp;<span class="Statement">&gt;</span>&nbsp;i&nbsp;&nbsp; <span class="Statement">=</span>&nbsp;[r<span class="Statement">:</span>rs]<br />
&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><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [&nbsp;r<span class="Statement">:</span>rs' <span class="Statement">|</span>&nbsp;rs' <span class="Statement">&lt;-</span>&nbsp;allSubsets&nbsp;(ln<span class="Statement">-</span><span class="Constant">1</span>)&nbsp;i&nbsp;rs&nbsp;]&nbsp;<span class="Statement">++</span>&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; allSubsets&nbsp;ln&nbsp;i&nbsp;rs<br />
<br /></blockquote></p>
<p>Validate a grid by making sure each pair is rectangle free with every other&#8230;</p>
<p><blockquote class="vimblock"><br />
validGrid&nbsp;<span class="Statement">::</span>&nbsp;[Row]&nbsp;<span class="Statement">-&gt;</span>&nbsp;<span class="Type">Bool</span><br />
validGrid&nbsp;[]&nbsp;<span class="Statement">=</span>&nbsp;<span class="Constant">True</span><br />
validGrid&nbsp;(r<span class="Statement">:</span>rs)&nbsp;<span class="Statement">=</span>&nbsp;all&nbsp;(areRectFree&nbsp;r)&nbsp;rs&nbsp;<span class="Statement">&amp;&amp;</span>&nbsp;validGrid&nbsp;rs<br />
<br /></blockquote></p>
<p>&#8230;and tie it all together:</p>
<p><blockquote class="vimblock"><br />
bestSubset&nbsp;<span class="Statement">=</span>&nbsp;maximumBy&nbsp;mostColored&nbsp;<span class="Statement">.</span>&nbsp;<span class="Identifier">filter</span>&nbsp;validGrid&nbsp;<span class="Statement">.</span>&nbsp;allGrids&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;<span class="Type">where</span>&nbsp;mostColored&nbsp;<span class="Statement">=</span>&nbsp;comparing&nbsp;(<span class="Identifier">length</span>&nbsp;<span class="Statement">.</span>&nbsp;<span class="Identifier">filter</span>&nbsp;<span class="Identifier">id</span>&nbsp;<span class="Statement">.</span>&nbsp;<span class="Identifier">concat</span>)<br />
<br /></blockquote></p>
<p>So a best subset of size four looks like:</p>
<blockquote><p>[[True,True,False,False],[True,False,True,False],[True,False,False,True],[False,True,True,True]]</p></blockquote>
<p>And a pretty picture:</p>
<p><blockquote class="vimblock"><br />
<span class="Statement">+--+--+--+--+</span><br />
<span class="Statement">|</span>XX<span class="Statement">|</span>XX<span class="Statement">|</span>&nbsp;&nbsp;<span class="Statement">|</span>&nbsp;&nbsp;<span class="Statement">|</span><br />
<span class="Statement">+--+--+--+--+</span><br />
<span class="Statement">|</span>XX<span class="Statement">|</span>&nbsp;&nbsp;<span class="Statement">|</span>XX<span class="Statement">|</span>&nbsp;&nbsp;<span class="Statement">|</span><br />
<span class="Statement">+--+--+--+--+</span><br />
<span class="Statement">|</span>XX<span class="Statement">|</span>&nbsp;&nbsp;<span class="Statement">|</span>&nbsp;&nbsp;<span class="Statement">|</span>XX<span class="Statement">|</span><br />
<span class="Statement">+--+--+--+--+</span><br />
<span class="Statement">|</span>&nbsp;&nbsp;<span class="Statement">|</span>XX<span class="Statement">|</span>XX<span class="Statement">|</span>XX<span class="Statement">|</span><br />
<span class="Statement">+--+--+--+--+</span><br />
<br /></blockquote></p>
<p>Does anyone have a more elegant way to represent the <code>allGrids</code> function? In the general sense it finds all n-length ordered subsets of an ordered set when the length of the set is known. </p>
]]></content:encoded>
			<wfw:commentRss>http://coder.bsimmons.name/blog/2010/02/17x17-brute-force-algorithm-for-an-optimal-rectangle-free-subset/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>DeBruijn Sequences pt.3 &#8211; The &#8220;Prefer Opposite&#8221; algorithm</title>
		<link>http://coder.bsimmons.name/blog/2009/12/debruijn-sequences-pt3-the-prefer-opposite-algorithm/</link>
		<comments>http://coder.bsimmons.name/blog/2009/12/debruijn-sequences-pt3-the-prefer-opposite-algorithm/#comments</comments>
		<pubDate>Wed, 02 Dec 2009 02:29:29 +0000</pubDate>
		<dc:creator>jberryman</dc:creator>
				<category><![CDATA[haskell]]></category>
		<category><![CDATA[algorithm]]></category>
		<category><![CDATA[laziness]]></category>
		<category><![CDATA[monads]]></category>
		<category><![CDATA[sequences]]></category>

		<guid isPermaLink="false">http://coder.bsimmons.name/blog/?p=295</guid>
		<description><![CDATA[<p><em>This is the third post of mine on DeBruijn sequences, and is in preparation for another post to come which I hope should be an interesting investigation into a possible parallel algorithm. The first two posts are <a href="http://coder.bsimmons.name/blog/2009/09/cracking-a-lock-in-haskell-with-the-de-bruijn-sequence-pt-1/">here</a> and</em>&#8230; <a href="http://coder.bsimmons.name/blog/2009/12/debruijn-sequences-pt3-the-prefer-opposite-algorithm/" class="read_more">   [ R E A D &#124; M O R E ]</a></p>]]></description>
			<content:encoded><![CDATA[<p><em>This is the third post of mine on DeBruijn sequences, and is in preparation for another post to come which I hope should be an interesting investigation into a possible parallel algorithm. The first two posts are <a href="http://coder.bsimmons.name/blog/2009/09/cracking-a-lock-in-haskell-with-the-de-bruijn-sequence-pt-1/">here</a> and <a href="http://coder.bsimmons.name/blog/2009/09/cracking-a-lock-in-haskell-with-the-de-bruijn-sequence-pt-2/">here</a>.</em><br />
<span id="more-295"></span><br />
&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;</p>
<p><div class="vimblock"><br />
This algorithm works identically to the Prefer One algorithm, however<br />
rather than choose a 1-bit if possible, we instead choose the opposite<br />
bit from the previous bit, if possible.<br />
<br />
This has the effect of evening out the locations of the zeros and ones<br />
throughout the sequence. We will exploit this in a later post where I<br />
will explore a possible parallel algorithm, which should be interesting<br />
I hope!<br />
<br />
Here's the code...<br />
<br />
<span class="Comment">&gt;</span>&nbsp;<span class="Type">module</span>&nbsp;Main<br />
<span class="Comment">&gt;</span>&nbsp;&nbsp;&nbsp;&nbsp; <span class="Type">where</span><br />
<span class="Comment">&gt;</span><br />
<span class="Comment">&gt;</span>&nbsp;<span class="PreProc">import</span>&nbsp;Data.List(tails)<br />
<span class="Comment">&gt;</span>&nbsp;<span class="PreProc">import</span>&nbsp;Control.Monad.State<br />
<span class="Comment">&gt;</span>&nbsp;<span class="PreProc">import</span>&nbsp;Control.Arrow<br />
<br />
<br />
We use Bool for bits, where False ==&gt; 0, True ==&gt; 1:<br />
<br />
<span class="Comment">&gt;</span>&nbsp;<span class="Type">type</span>&nbsp;Bit&nbsp;<span class="Statement">=</span>&nbsp;<span class="Type">Bool</span><br />
<br />
<br />
We use a tree to search for the words already created in our bit stream:<br />
<br />
<span class="Comment">&gt;</span>&nbsp;<span class="Type">data</span>&nbsp;Tree&nbsp;<span class="Statement">=</span>&nbsp;Bs&nbsp;Tree&nbsp;Tree&nbsp;&nbsp;<span class="Comment">-- Bs (zero_bit) (one_bit)</span><br />
<span class="Comment">&gt;</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span class="Statement">|</span>&nbsp;X&nbsp;<span class="Comment">-- incomplete word</span><br />
<span class="Comment">&gt;</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span class="Statement">|</span>&nbsp;B&nbsp;<span class="Comment">-- final bit of word</span><br />
<span class="Comment">&gt;</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span class="Type">deriving</span>&nbsp;<span class="Type">Show</span><br />
<br />
<br />
We'll need to build a new tree from a list of bits, appending<br />
a final bit:<br />
<br />
<span class="Comment">&gt;</span>&nbsp;treeWithFinal&nbsp;<span class="Statement">::</span>&nbsp;Bit&nbsp;<span class="Statement">-&gt;</span>&nbsp;[Bit]&nbsp;<span class="Statement">-&gt;</span>&nbsp;Tree<br />
<span class="Comment">&gt;</span>&nbsp;treeWithFinal&nbsp;p&nbsp;<span class="Statement">=</span>&nbsp;<span class="Identifier">foldr</span>&nbsp;mkBranch&nbsp;(<span class="Statement">if</span>&nbsp;p&nbsp;<span class="Statement">then</span>&nbsp;Bs&nbsp;X&nbsp;B&nbsp;<span class="Statement">else</span>&nbsp;Bs&nbsp;B&nbsp;X)&nbsp;&nbsp; <br />
<span class="Comment">&gt;</span>&nbsp;&nbsp;&nbsp;&nbsp; <span class="Type">where</span>&nbsp;mkBranch&nbsp;b&nbsp;<span class="Statement">|</span>&nbsp;b&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span class="Statement">=</span>&nbsp;Bs&nbsp;X&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="Comment">--1</span><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;<span class="Statement">|</span>&nbsp;<span class="Identifier">otherwise</span>&nbsp;<span class="Statement">=</span>&nbsp;<span class="Identifier">flip</span>&nbsp;Bs&nbsp;X&nbsp;<span class="Comment">--0</span><br />
<br />
<br />
<br />
Finally, here is our new algorithm. The Tree which we use to search for<br />
previously-seen words is passed in the State monad, behind the scenes, <br />
with 'zipWithM', which in our case looks like:<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;zipWithM :: (Bit -&gt; [Bit] -&gt; State Tree Bit) -&gt; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[Bit]&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;-&gt; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[[Bit]]&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;-&gt; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;State Tree [Bit]<br />
<br />
The state monad is a little tricky sometimes:<br />
<br />
<span class="Comment">&gt;</span>&nbsp;preferOpposite&nbsp;<span class="Statement">::</span>&nbsp;<span class="Type">Int</span>&nbsp;<span class="Statement">-&gt;</span>&nbsp;[&nbsp;Bit&nbsp;]<br />
<span class="Comment">&gt;</span>&nbsp;preferOpposite&nbsp;n&nbsp;<span class="Statement">=</span>&nbsp;<br />
<span class="Comment">&gt;</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br />
<span class="Comment">&gt;</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span class="Comment">-- the whole bit sequence, except for the final 1:</span><br />
<span class="Comment">&gt;</span>&nbsp;&nbsp;&nbsp;&nbsp; <span class="Statement">let</span>&nbsp;bs&nbsp;<span class="Statement">=</span>&nbsp;<span class="Identifier">take</span>&nbsp;(<span class="Constant">2</span><span class="Statement">^</span>n<span class="Statement">-</span><span class="Constant">1</span>)&nbsp;(<span class="Identifier">replicate</span>&nbsp;n&nbsp;<span class="Constant">False</span>&nbsp;<span class="Statement">++</span>&nbsp;bs')<br />
<span class="Comment">&gt;</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br />
<span class="Comment">&gt;</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span class="Comment">-- list of (n-1)-bit words:</span><br />
<span class="Comment">&gt;</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (wp0<span class="Statement">:</span>wordPrefixes)&nbsp;<span class="Statement">=</span>&nbsp;<span class="Identifier">map</span>&nbsp;(<span class="Identifier">take</span>&nbsp;(n<span class="Statement">-</span><span class="Constant">1</span>))&nbsp;(tails&nbsp;bs)<br />
<span class="Comment">&gt;</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br />
<span class="Comment">&gt;</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span class="Comment">-- we know the first word is n 0's so we create our initial</span><br />
<span class="Comment">&gt;</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span class="Comment">-- tree from (n-1) 0's with a zero at the end:</span><br />
<span class="Comment">&gt;</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; state0&nbsp;<span class="Statement">=</span>&nbsp;treeWithFinal&nbsp;<span class="Constant">False</span>&nbsp;wp0<br />
<span class="Comment">&gt;</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br />
<span class="Comment">&gt;</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span class="Comment">-- we zipWith a word with it's previous bit (so that we</span><br />
<span class="Comment">&gt;</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span class="Comment">-- can know which bit is the opposite) passing along the</span><br />
<span class="Comment">&gt;</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span class="Comment">-- Tree with help from the State monad:</span><br />
<span class="Comment">&gt;</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; bsM' <span class="Statement">=</span>&nbsp;zipWithM&nbsp;thisBit&nbsp;(<span class="Constant">False</span><span class="Statement">:</span>bs')&nbsp;wordPrefixes<br />
<span class="Comment">&gt;</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; bs' <span class="Statement">=</span>&nbsp;evalState&nbsp;bsM' state0<br />
<span class="Comment">&gt;</span><br />
<span class="Comment">&gt;</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span class="Comment">-- we place a 1 for the final bit:</span><br />
<span class="Comment">&gt;</span>&nbsp;&nbsp;&nbsp;&nbsp;<span class="Statement">in</span>&nbsp;bs&nbsp;<span class="Statement">++</span>&nbsp;[<span class="Constant">True</span>]<br />
<br />
If we wanted to be clever, we would have made the last line:<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp; in cycle (bs ++ [True])<br />
<br />
...as the sequence is actually cyclic.<br />
<br />
This helper function takes the previous bit and an n-1 bit word and returns <br />
a function :: Tree -&gt; (Bit,Tree), which takes the current search tree and<br />
checks the current word to see if the last bit of the word should be one<br />
or zero. The function :: Tree -&gt; (Bit,Tree) is wrapped in the State <br />
constructor, which is all you have to do to turn it into :: State Tree Bit<br />
<br />
<span class="Comment">&gt;</span>&nbsp;thisBit&nbsp;<span class="Statement">::</span>&nbsp;Bit&nbsp;<span class="Statement">-&gt;</span>&nbsp;[&nbsp;Bit&nbsp;]&nbsp;<span class="Statement">-&gt;</span>&nbsp;State&nbsp;Tree&nbsp;Bit<br />
<br />
The wrapper function splits up the input tuple and tuples up the returned<br />
bit to make a proper St so that we can pass the last bit through the state<br />
monad.<br />
<br />
<span class="Comment">&gt;</span>&nbsp;thisBit&nbsp;bP&nbsp;&nbsp; <span class="Statement">=</span>&nbsp;State&nbsp;<span class="Statement">.</span>&nbsp;thisBit'<br />
<span class="Comment">&gt;</span>&nbsp;&nbsp; <span class="Type">where</span>&nbsp;bOpp&nbsp;<span class="Statement">=</span>&nbsp;<span class="Identifier">not</span>&nbsp;bP&nbsp;<br />
<br />
We start checking a word, moving down the tree:<br />
<br />
<span class="Comment">&gt;</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; thisBit' (<span class="Constant">False</span><span class="Statement">:</span>bs)&nbsp;(Bs&nbsp;z&nbsp;o)&nbsp;<span class="Statement">=</span>&nbsp;second&nbsp;(<span class="Identifier">flip</span>&nbsp;Bs&nbsp;o)&nbsp;(thisBit' bs&nbsp;z)<br />
<span class="Comment">&gt;</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; thisBit' (<span class="Constant">True</span><span class="Statement">:</span>bs)&nbsp;&nbsp;(Bs&nbsp;z&nbsp;o)&nbsp;<span class="Statement">=</span>&nbsp;second&nbsp;(Bs&nbsp;z)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(thisBit' bs&nbsp;o)<br />
<br />
...or we walked off end of branch, so return opposite bit, and attach <br />
the rest of word to the tree:<br />
<br />
<span class="Comment">&gt;</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; thisBit' bs&nbsp;X&nbsp;<span class="Statement">=</span>&nbsp;(bOpp,&nbsp;treeWithFinal&nbsp;bOpp&nbsp;bs)<br />
<br />
...or we reached the end of our word, so we prefer the opposite for the last <br />
bit, and check if it was seen:<br />
<br />
<span class="Comment">&gt;</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; thisBit' []&nbsp;(Bs&nbsp;z&nbsp;o)&nbsp;<br />
<span class="Comment">&gt;</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span class="Statement">|</span>&nbsp;bOpp&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="Statement">=</span>&nbsp;<span class="Statement">case</span>&nbsp;o&nbsp;<span class="Statement">of</span>&nbsp;<span class="Comment">-- opposite bit is 1 (True)</span><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;&nbsp;&nbsp;&nbsp;&nbsp;X&nbsp;<span class="Statement">-&gt;</span>&nbsp;(bOpp,Bs&nbsp;z&nbsp;B)<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;&nbsp;&nbsp;&nbsp;&nbsp;_&nbsp;<span class="Statement">-&gt;</span>&nbsp;(bP&nbsp;&nbsp;,Bs&nbsp;B&nbsp;B)<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;<span class="Statement">case</span>&nbsp;z&nbsp;<span class="Statement">of</span><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;&nbsp;&nbsp;&nbsp;&nbsp;X&nbsp;<span class="Statement">-&gt;</span>&nbsp;(bOpp,Bs&nbsp;B&nbsp;o)<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;&nbsp;&nbsp;&nbsp;&nbsp;_&nbsp;<span class="Statement">-&gt;</span>&nbsp;(bP&nbsp;&nbsp;,Bs&nbsp;B&nbsp;B)<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;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br />
Finally, here are some functions to generate the actual sequences <br />
in 0s and 1s:<br />
<br />
<span class="Comment">&gt;</span>&nbsp;test&nbsp;<span class="Statement">=</span>&nbsp;<span class="Identifier">map</span>&nbsp;(<span class="Statement">\</span>x<span class="Statement">-&gt;</span><span class="Statement">if</span>&nbsp;x&nbsp;<span class="Statement">then</span>&nbsp;<span class="Constant">'1'</span>&nbsp;<span class="Statement">else</span>&nbsp;<span class="Constant">'0'</span>)&nbsp;<span class="Statement">.</span>&nbsp;preferOpposite&nbsp;<br />
<span class="Comment">&gt;</span><br />
<span class="Comment">&gt;</span>&nbsp;main&nbsp;<span class="Statement">=</span>&nbsp;<span class="Identifier">print</span>&nbsp;<span class="Statement">$</span>&nbsp;test&nbsp;<span class="Constant">10</span><br />
<br />
<br /></div></p>
]]></content:encoded>
			<wfw:commentRss>http://coder.bsimmons.name/blog/2009/12/debruijn-sequences-pt3-the-prefer-opposite-algorithm/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
