<?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>Algorithm Blogs &#187; computer science</title>
	<atom:link href="http://www.algorithm.co.il/blogs/index.php/category/computer-science/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.algorithm.co.il/blogs</link>
	<description>Algorithms, for the heck of it</description>
	<lastBuildDate>Thu, 22 Apr 2010 21:04:32 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>The mathematics behind the solution for Challenge No. 5</title>
		<link>http://www.algorithm.co.il/blogs/index.php/programming/python/the-mathematics-behind-the-solution-for-challenge-no-5/</link>
		<comments>http://www.algorithm.co.il/blogs/index.php/programming/python/the-mathematics-behind-the-solution-for-challenge-no-5/#comments</comments>
		<pubDate>Fri, 26 Feb 2010 23:49:15 +0000</pubDate>
		<dc:creator>lorg</dc:creator>
				<category><![CDATA[Challenges]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[computer science]]></category>
		<category><![CDATA[base systems]]></category>
		<category><![CDATA[factorial]]></category>
		<category><![CDATA[Knuth]]></category>
		<category><![CDATA[Math]]></category>
		<category><![CDATA[permutations]]></category>

		<guid isPermaLink="false">http://www.algorithm.co.il/blogs/?p=500</guid>
		<description><![CDATA[If you take a look at the various solutions people proposed for the last challenge of generating a specific permutation, you&#8217;ll see that they are very similar. Most of them are based on some form of div-mod usage. The reason this is so, is because all of these solutions are using the Factorial Base.
What does [...]]]></description>
			<content:encoded><![CDATA[<p>If you take a look at the various solutions people proposed for the <a href="http://www.algorithm.co.il/blogs/index.php/programming/small-programming-challenge-no-5-generating-a-permutation/">last challenge of generating a specific permutation</a>, you&#8217;ll see that they are very similar. Most of them are based on some form of div-mod usage. The reason this is so, is because all of these solutions are using the <a href="http://en.wikipedia.org/wiki/Factorial_base">Factorial Base</a>.</p>
<p>What does that mean?<br />
Note that we usually encounter div-mods when we want to find the representation of a number in a certain base. That should already pique your interest. Now consider that a base&#8217;s digits need not have the same weight. For example, consider how we count the number of seconds since the start of the week:</p>
<p>seconds of the last minute, A (at most 60-1)<br />
minutes of the last hour, B (at most 60-1)<br />
hours of the last day, C (at most (24-1)<br />
days of the last week, D (at most 7-1)</p>
<p>So given A, B, C, D, we would say that the number of seconds is:<br />
A + 60*B + 24*C + 7*D. This certainly looks like a base transformation. To go back, we would use divmod.</p>
<p>The factorial base is just the same, with the numbers n, n-1, &#8230; 1. Note that in the factorial base, you can only represent a finite number of numbers &#8211; n!. This should not be surprising &#8211; this is what we set out to do in the first place!<br />
The thing that I found really amazing about this is that all the people to whom I posed this challenge came up with almost the same &#8220;way&#8221; of solving it. </p>
<p>Other interesting curiosities regarding bases can be found in Knuth&#8217;s book, &#8220;The Art of Computer Programming&#8221;, volume 2, Section 4.1. </p>
]]></content:encoded>
			<wfw:commentRss>http://www.algorithm.co.il/blogs/index.php/programming/python/the-mathematics-behind-the-solution-for-challenge-no-5/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Small Programming Challenge no. 5 &#8211; Generating a Permutation</title>
		<link>http://www.algorithm.co.il/blogs/index.php/programming/small-programming-challenge-no-5-generating-a-permutation/</link>
		<comments>http://www.algorithm.co.il/blogs/index.php/programming/small-programming-challenge-no-5-generating-a-permutation/#comments</comments>
		<pubDate>Wed, 11 Nov 2009 19:43:45 +0000</pubDate>
		<dc:creator>lorg</dc:creator>
				<category><![CDATA[Challenges]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[computer science]]></category>
		<category><![CDATA[challenge]]></category>

		<guid isPermaLink="false">http://www.algorithm.co.il/blogs/?p=493</guid>
		<description><![CDATA[I thought of this one quite a long time ago, and I believe that the idea behind it is pretty nice mathematically. I got the idea for it from Knuth&#8217;s &#8220;The Art of Computer Programming&#8221;.
The challenge is simple:
write a function that receives as arguments two numbers, n, and num such that 0 ]]></description>
			<content:encoded><![CDATA[<p>I thought of this one quite a long time ago, and I believe that the idea behind it is pretty nice mathematically. I got the idea for it from Knuth&#8217;s &#8220;The Art of Computer Programming&#8221;.</p>
<p>The challenge is simple:<br />
write a function that receives as arguments two numbers, n, and num such that 0 <= num < n!. This function needs to return an array (list) representing a permutation of the numbers 0..n-1. For each possible num, the function needs to return a different permutation, such that over all values of num, all possible permutations are generated. The order of permutations is up to you.</p>
<p>The function you write should do this in at most O(n) time &#038; space (Various O(nlogn) are also acceptable).<br />
Write your solutions in the comments, in [ LANG ] [/ LANG ] blocks (without the spaces) where LANG is preferably Python :). I will post my solution in a few days. As usual, the most efficient &#038; elegant solution wins.</p>
<p>Go!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.algorithm.co.il/blogs/index.php/programming/small-programming-challenge-no-5-generating-a-permutation/feed/</wfw:commentRss>
		<slash:comments>15</slash:comments>
		</item>
		<item>
		<title>10 Python Optimization Tips and Issues</title>
		<link>http://www.algorithm.co.il/blogs/index.php/programming/python/10-python-optimization-tips-and-issues/</link>
		<comments>http://www.algorithm.co.il/blogs/index.php/programming/python/10-python-optimization-tips-and-issues/#comments</comments>
		<pubDate>Mon, 21 Sep 2009 21:37:38 +0000</pubDate>
		<dc:creator>lorg</dc:creator>
				<category><![CDATA[Design]]></category>
		<category><![CDATA[Optimization]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[computer science]]></category>
		<category><![CDATA[memory]]></category>
		<category><![CDATA[memory usage]]></category>
		<category><![CDATA[optimization]]></category>

		<guid isPermaLink="false">http://www.algorithm.co.il/blogs/?p=373</guid>
		<description><![CDATA[Following my previous post on Optimizing Javascript, I thought I'd write a similar post regarding Python optimization.

Before going on to the more interesting stuff, there are a few issues that need to be addressed:
0. Basics
Know the basics - especially profiling!
Just by looking at the profiling output, you can tell where does the computing time go. [...]]]></description>
			<content:encoded><![CDATA[<p>Following my previous post on <a href="http://www.algorithm.co.il/blogs/index.php/programming/javascript/javascript-optimization-tricks/">Optimizing Javascript</a>, I thought I'd write a similar post regarding Python optimization.<br />
<span id="more-373"></span><br />
Before going on to the more interesting stuff, there are a few issues that need to be addressed:</p>
<h4>0. Basics</h4>
<p>Know the <a href="http://wiki.python.org/moin/PythonSpeed/PerformanceTips">basics</a> - especially profiling!<br />
Just by looking at the profiling output, you can tell where does the computing time go. To get that information, I like to sort on cumulative time (i.e, time taken by a given function and all functions called from it, over all of its calls).</p>
<h4>0.5. Knowing your goal, and your enemy</h4>
<p>The kind of optimizations you do, and how far you're willing to go is dependent on your code's users. If you're writing batch processing software, your required time for running might be a minute, an hour, or a day. So far, I had to optimize various cases of weeks to minutes for batch processing and also seconds to milliseconds for web-application UI.<br />
Your timing should apply to typical input, and probably to your biggest probable input as well. </p>
<p>Create some simple benchmark you can test your code against. It's important that your benchmark be typical 'complexity-wise', but smaller in size, so that running it and getting profiling results takes no more than a few seconds. You may even want multiple benchmarks, each one for a different size. That way, once you are more sure of yourself, you can run your code against the larger benchmark. If your benchmarks are real inputs - all the better.</p>
<h4>1. Python vs. C and similar considerations</h4>
<p>In my line of work, I usually do research oriented development. That means that it's harder to know upfront where the bottlenecks will be. As a result, the prevailing attitude is usually "let's write it in Python, and later, when the need arises, convert the critical code to C".<br />
So far, I haven't had the chance to do that. Usually what happens is we write the code, it works well enough, and we figure that the flexibility of writing it in Python is more important than the Python to C conversion gains. Also, Python is not always the bottleneck - sometimes it's a database, or some 3rd party API.<br />
Usually "import pysco", and changing the code to allow parallel processing is cheaper and simpler than the conversion to C.</p>
<h4>2. The small time-eater</h4>
<p>A common problem is when a relatively trivial function is taking a lot of cumulative time. That's usually a sign you're doing something wrong. I had this issue when I used my <a href="http://www.algorithm.co.il/blogs/index.php/programming/python/various-small-python-helpers/">symbolic constants</a> for a new project. Consider the following:</p>
<div class="syntax_hilite">
<div id="python-9">
<div class="python"><span style="color: #00007f;font-weight:bold;">def</span> SymbolInt<span style="color: black;">&#40;</span>value, name<span style="color: black;">&#41;</span>:<br />
&nbsp; &nbsp; <span style="color: #00007f;font-weight:bold;">class</span> _SymbolInt<span style="color: black;">&#40;</span><span style="color: #008000;">int</span><span style="color: black;">&#41;</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #00007f;font-weight:bold;">def</span> <span style="color: #0000cd;">__str__</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span><span style="color: black;">&#41;</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #00007f;font-weight:bold;">return</span> name<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #00007f;font-weight:bold;">def</span> <span style="color: #0000cd;">__repr__</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span><span style="color: black;">&#41;</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #00007f;font-weight:bold;">return</span> <span style="color: #483d8b;">'SymbolInt(%d, &quot;%s&quot;)'</span> % <span style="color: black;">&#40;</span>value, name<span style="color: black;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #00007f;font-weight:bold;">def</span> <span style="color: #0000cd;">__eq__</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, other<span style="color: black;">&#41;</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #00007f;font-weight:bold;">if</span> <span style="color: #008000;">isinstance</span><span style="color: black;">&#40;</span>other, <span style="color: #008000;">str</span><span style="color: black;">&#41;</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; other = other.<span style="color: #000000;">lower</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #00007f;font-weight:bold;">return</span> <span style="color: #008000;">int</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span><span style="color: black;">&#41;</span>==other <span style="color: #00007f;font-weight:bold;">or</span> name.<span style="color: #000000;">lower</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span> == other<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #00007f;font-weight:bold;">def</span> <span style="color: #0000cd;">__ne__</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, other<span style="color: black;">&#41;</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #00007f;font-weight:bold;">return</span> <span style="color: #00007f;font-weight:bold;">not</span> <span style="color: #008000;">self</span> == other<br />
&nbsp; &nbsp; <span style="color: #00007f;font-weight:bold;">return</span> _SymbolInt<span style="color: black;">&#40;</span>value<span style="color: black;">&#41;</span></div>
</div>
</div>
<p>
This one is very nice for interactive interfaces. However, in the new project, I found out that __eq__ was taking *a lot* of time. Way more than it should, even when I wasn't comparing SymbolInt-s to strings!<br />
It turned out that 'or name.lower() == other' was very bad speed wise. So for that project, I removed this subcondition, and voila! My code was fast!</p>
<h4>3. The algorithm is critical</h4>
<p>In many cases I've worked on, the greatest reductions in running time were due to algorithm changes. That means that playing with issues such as variable lookups and so on should come after you're mostly settled on your algorithm. The latest example that I can think of is the <a href="http://www.algorithm.co.il/blogs/index.php/computer-science/small-python-challenge-no-4-counting-sets/">set counting problem</a>, where using <a href="http://www.algorithm.co.il/blogs/index.php/programming/python/my-solution-to-the-counting-sets-challenge/">my solution</a> got me down from two weeks to 20 something minutes on my real input.<br />
Later I did some simpler optimizations that chopped off a few more minutes.</p>
<h4>4. Avoiding loops</h4>
<p>That one is easy. Everyone knows you should avoid loops, especially nested ones. Still, there are some cases where your code just has to have these loops - because that's the essence of what your code is doing.</p>
<p>To make loop avoidance possible, and specifically cartesian product kind of loops, consider refactoring your code to use set intersections and unions. As simple illustration, consider:<br />
Instead of this,</p>
<div class="syntax_hilite">
<div id="python-10">
<div class="python"><span style="color: #00007f;font-weight:bold;">for</span> x <span style="color: #00007f;font-weight:bold;">in</span> a:<br />
&nbsp; &nbsp; <span style="color: #00007f;font-weight:bold;">for</span> y <span style="color: #00007f;font-weight:bold;">in</span> b:<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #00007f;font-weight:bold;">if</span> x == y:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #00007f;font-weight:bold;">yield</span> <span style="color: black;">&#40;</span>x,y<span style="color: black;">&#41;</span></div>
</div>
</div>
<p>
do this:</p>
<div class="syntax_hilite">
<div id="python-11">
<div class="python"><span style="color: #00007f;font-weight:bold;">return</span> <span style="color: #008000;">set</span><span style="color: black;">&#40;</span>a<span style="color: black;">&#41;</span> &amp; <span style="color: #008000;">set</span><span style="color: black;">&#40;</span>b<span style="color: black;">&#41;</span></div>
</div>
</div>
<p>
Sometimes, applying this change doesn't quite fit your algorithm. In that cases, try to change your algorithm to accommodate. For example, it might yield less accurate results. In that case, aim for returning more than you need, and then do a second pass to filter the bad ones. The time gains from avoiding the extra loops should still be worth it.</p>
<p>(Note: this is similar to doing your computations in your database queries instead of in your code. Similar ideas apply.)</p>
<h4>5. Lookups</h4>
<p>If you spend time looking for something, use a dict. If that is not feasable, use any other data-structure that fits your problem. For example, let's say you're looking for given strings in a lot of files. You can build a small index beforehand, and instead of looking at the files each time, just look at this index.</p>
<p>(Note: this is similar to creating an index on the database column you are searching on.)</p>
<h4>6. Memory</h4>
<p>When dealing with large inputs, you'll usually want to reduce your memory requirements. Consider an algorithm that requires O(n) memory, for n-sized inputs. All you need is a factor of 4, and 500 megs of input, and your code will choke on many current machines.<br />
Also, I've found out that writing your code in such a way as to use drastically less memory, will sometimes force me to write it more time-efficiently as well.</p>
<p>There are a few techniques to dealing with the memory issue. The central idea is to have as little of your data as you need available at any time.</p>
<h4>7. Generators</h4>
<p>Generator expressions are usually preferable to list comprehensions. Similarly, consider replacing this kind of functions:</p>
<div class="syntax_hilite">
<div id="python-12">
<div class="python"><span style="color: #00007f;font-weight:bold;">def</span> myfunc<span style="color: black;">&#40;</span>some_input<span style="color: black;">&#41;</span>:<br />
&nbsp; &nbsp; ...<br />
&nbsp; &nbsp; <span style="color: #000000;">result</span> = <span style="color: black;">&#91;</span><span style="color: black;">&#93;</span><br />
&nbsp; &nbsp; <span style="color: #00007f;font-weight:bold;">for</span> bla <span style="color: #00007f;font-weight:bold;">in</span> foo:<br />
&nbsp; &nbsp; &nbsp; &nbsp; ...<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000000;">result</span>.<span style="color: #000000;">append</span><span style="color: black;">&#40;</span>bar<span style="color: black;">&#41;</span><br />
&nbsp; &nbsp; <span style="color: #00007f;font-weight:bold;">return</span> result</div>
</div>
</div>
<p>
with the following idiom:</p>
<div class="syntax_hilite">
<div id="python-13">
<div class="python"><span style="color: #00007f;font-weight:bold;">def</span> myfunc<span style="color: black;">&#40;</span>some_input<span style="color: black;">&#41;</span>:<br />
&nbsp; &nbsp; ...<br />
&nbsp; &nbsp; <span style="color: #00007f;font-weight:bold;">for</span> bla <span style="color: #00007f;font-weight:bold;">in</span> foo:<br />
&nbsp; &nbsp; &nbsp; &nbsp; ...<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #00007f;font-weight:bold;">yield</span> bar</div>
</div>
</div>
<p>
This has the added advantage of simplifying myfunc, as its state is kept for you. On really big inputs and outputs, this one could save you from keeping all of your output in memory.<br />
If you are not familiar with generators, I suggest reading <a href="http://www.dabeaz.com/generators/index.html">David Beazley's presentation</a> on the subject, it's an excellent read, regardless of optimizations.</p>
<h4>8. Outputs</h4>
<p>If your goal is to generate output, dump it to a file as soon as possible. This is made simple by the previous idiom:</p>
<div class="syntax_hilite">
<div id="python-14">
<div class="python"><span style="color: #00007f;font-weight:bold;">for</span> bar <span style="color: #00007f;font-weight:bold;">in</span> myfunc<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>:<br />
&nbsp; &nbsp; <span style="color: #808080; font-style: italic;">#process bar</span><br />
&nbsp; &nbsp; ...<br />
&nbsp; &nbsp; <span style="color: #000000;">dump</span><span style="color: black;">&#40;</span>foobar<span style="color: black;">&#41;</span></div>
</div>
</div>
<p>
Just make sure that dump doesn't keep your data around for too long.<br />
For example, I once had to insert a lot of data into a database. After I finished processing each record, I would insert it. The bottleneck was the database. I tried flushing only after several inserts (which meant inserts in chunks of N for various N), until I was introduced to the solution: <a href="http://www.algorithm.co.il/blogs/index.php/programming/bulk-inserts-ftw/">bulk inserts</a>.<br />
The, my extraction script just dumped to a text file, which was lightning fast, and later I did the bulk insert.</p>
<h4>9. Summing up</h4>
<p>Do</p>
<div class="syntax_hilite">
<div id="python-15">
<div class="python"><span style="color: #008000;">sum</span><span style="color: black;">&#40;</span>x <span style="color: #00007f;font-weight:bold;">for</span> x <span style="color: #00007f;font-weight:bold;">in</span> some_generator<span style="color: black;">&#41;</span></div>
</div>
</div>
<p>
Instead of</p>
<div class="syntax_hilite">
<div id="python-16">
<div class="python"><span style="color: #00007f;font-weight:bold;">for</span> x <span style="color: #00007f;font-weight:bold;">in</span> some_list:<br />
&nbsp; &nbsp; my_sum += x</div>
</div>
</div>
<p></p>
<p>Kidding!<br />
Use your profiler, your head, psyco, and more experienced advice in the best order that suits you. As I've come to learn, getting advice from friends is an excellent way to avoid bashing your head against some mad bugger's O(n<sup>2</sup>) wall.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.algorithm.co.il/blogs/index.php/programming/python/10-python-optimization-tips-and-issues/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>My solution to the counting sets challenge</title>
		<link>http://www.algorithm.co.il/blogs/index.php/programming/python/my-solution-to-the-counting-sets-challenge/</link>
		<comments>http://www.algorithm.co.il/blogs/index.php/programming/python/my-solution-to-the-counting-sets-challenge/#comments</comments>
		<pubDate>Mon, 07 Sep 2009 15:00:51 +0000</pubDate>
		<dc:creator>lorg</dc:creator>
				<category><![CDATA[Challenges]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[computer science]]></category>
		<category><![CDATA[challenge]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Sets]]></category>
		<category><![CDATA[Solution]]></category>

		<guid isPermaLink="false">http://www.algorithm.co.il/blogs/?p=325</guid>
		<description><![CDATA[A few days ago, I wrote up a challenge - to count the number of sets a given set is contained in.
In the comments, I touched briefly on the original problem from which the challenge was created, and I'll describe it in more depth here.
In the problem, I am given an initial group of sets, [...]]]></description>
			<content:encoded><![CDATA[<p>A few days ago, I wrote up a <a href="http://www.algorithm.co.il/blogs/index.php/computer-science/small-python-challenge-no-4-counting-sets/">challenge</a> - to count the number of sets a given set is contained in.</p>
<p>In the comments, I touched briefly on the original problem from which the challenge was created, and I'll describe it in more depth here.<br />
In the problem, I am given an initial group of sets, and then an endless 'stream of sets'. For each of the sets in the stream, I have to measure its uniqueness. relative to the initial group of sets. A set that is contained in only one set from the initial group is very unique, one that is contained in ten - not so much.</p>
<p>So how to solve this problem? My original solution is somewhat akin to the classic "lion-in-the-desert" problem, but more like the "blood test" story. I didn't find a link to the story, so I'll give it as I remember it. </p>
<p>In an army somewhere, it was discovered that at least one of the soldiers was sick and so had to be put in isolation until he heals. It is only possible to check for the disease via a blood test, but tests are expensive, and they didn't want to test all of the soldiers. What did they do?</p>
<p>They took enough blood from each soldier. Now, from each sample they took a little bit, and divided the samples into two groups. They mixed together the samples of each group, and tested the mixed sample. If the sample was positive - they repeated the process for the blood samples of all the soldiers in the matching group.</p>
<p>Now my solution is clear: let's build a tree of set unions. At bottom level will be the union of couples of sets. At the next level, unions of couples of couples of sets. So on, until we end up with just two sets, or even just one - if we are not sure the set is contained in any of the initial sets.</p>
<p>Testing is just like in the story. We'll start at the two biggest unions, and work our way down. There is an optimization though - if a set appears more than say, 10 times, it's not very unique, and its score is zeroed. In that case, we don't have to go down all the way, but stop as soon as we pass the 10 "positive result" mark.</p>
<p>Here's the code:</p>
<div class="syntax_hilite">
<div id="python-18">
<div class="python"><span style="color: #00007f;font-weight:bold;">class</span> SetGroup<span style="color: black;">&#40;</span><span style="color: #008000;">object</span><span style="color: black;">&#41;</span>:<br />
&nbsp; &nbsp; <span style="color: #00007f;font-weight:bold;">def</span> <span style="color: #0000cd;">__init__</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, set_list<span style="color: black;">&#41;</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; cur_level = <span style="color: #008000;">list</span><span style="color: black;">&#40;</span>set_list<span style="color: black;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #008000;">self</span>.<span style="color: #000000;">levels</span> = <span style="color: black;">&#91;</span><span style="color: black;">&#93;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #00007f;font-weight:bold;">while</span> <span style="color: #008000;">len</span><span style="color: black;">&#40;</span>cur_level<span style="color: black;">&#41;</span>&gt; <span style="color: #ff4500;">1</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #008000;">self</span>.<span style="color: #000000;">levels</span>.<span style="color: #000000;">append</span><span style="color: black;">&#40;</span>cur_level<span style="color: black;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; cur_level = <span style="color: black;">&#91;</span>union<span style="color: black;">&#40;</span>couple<span style="color: black;">&#41;</span> <span style="color: #00007f;font-weight:bold;">for</span> couple <span style="color: #00007f;font-weight:bold;">in</span> blocks<span style="color: black;">&#40;</span>cur_level, <span style="color: #ff4500;">2</span><span style="color: black;">&#41;</span><span style="color: black;">&#93;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #008000;">self</span>.<span style="color: #000000;">levels</span>.<span style="color: #000000;">reverse</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span></p>
<p>&nbsp; &nbsp; <span style="color: #00007f;font-weight:bold;">def</span> count<span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, some_set, max_appear = <span style="color: #008000;">None</span><span style="color: black;">&#41;</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; indexes = <span style="color: black;">&#91;</span><span style="color: #ff4500;">0</span><span style="color: black;">&#93;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #00007f;font-weight:bold;">for</span> level <span style="color: #00007f;font-weight:bold;">in</span> <span style="color: #008000;">self</span>.<span style="color: #000000;">levels</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; indexes = <span style="color: #dc143c;">itertools</span>.<span style="color: #000000;">chain</span><span style="color: black;">&#40;</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">2</span>*x <span style="color: #00007f;font-weight:bold;">for</span> x <span style="color: #00007f;font-weight:bold;">in</span> indexes<span style="color: black;">&#41;</span>, <span style="color: black;">&#40;</span><span style="color: #ff4500;">2</span>*x+<span style="color: #ff4500;">1</span> <span style="color: #00007f;font-weight:bold;">for</span> x <span style="color: #00007f;font-weight:bold;">in</span> indexes<span style="color: black;">&#41;</span><span style="color: black;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; indexes = <span style="color: black;">&#40;</span>x <span style="color: #00007f;font-weight:bold;">for</span> x <span style="color: #00007f;font-weight:bold;">in</span> indexes <span style="color: #00007f;font-weight:bold;">if</span> x &lt;len<span style="color: black;">&#40;</span>level<span style="color: black;">&#41;</span><span style="color: black;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; indexes = <span style="color: black;">&#91;</span>x <span style="color: #00007f;font-weight:bold;">for</span> x <span style="color: #00007f;font-weight:bold;">in</span> indexes <span style="color: #00007f;font-weight:bold;">if</span> some_set &lt;= level<span style="color: black;">&#91;</span>x<span style="color: black;">&#93;</span><span style="color: black;">&#93;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #00007f;font-weight:bold;">if</span> max_appear <span style="color: #00007f;font-weight:bold;">is</span> <span style="color: #00007f;font-weight:bold;">not</span> <span style="color: #008000;">None</span> <span style="color: #00007f;font-weight:bold;">and</span> <span style="color: #008000;">len</span><span style="color: black;">&#40;</span>indexes<span style="color: black;">&#41;</span>&gt;= max_appear:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #00007f;font-weight:bold;">return</span> max_appear<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #00007f;font-weight:bold;">return</span> <span style="color: #008000;">len</span><span style="color: black;">&#40;</span>indexes<span style="color: black;">&#41;</span></div>
</div>
</div>
<p></p>
<p>Here's a link to the <a href="http://www.algorithm.co.il/sitecode/counting.py">full code</a>.</p>
<p>I didn't implement this solution right away. At first, I used the naive approach, of checking against each set. Then, when it proved to be too slow, I tried implementing the solution outlined by <a href="http://www.algorithm.co.il/blogs/index.php/computer-science/small-python-challenge-no-4-counting-sets/#comment-33424">Shenberg</a> and <a href="http://www.algorithm.co.il/blogs/index.php/computer-science/small-python-challenge-no-4-counting-sets/#comment-33366">Eric</a> in the comments to the challenge. Unfortunately, their solution proved to be very slow as well. I believe it's because some elements appear in almost all of the sets, and so computing the intersection for these elements takes a long time.<br />
Although originally I thought that my solution would suffer from some serious drawbacks (can you see what they are?), the max_appear limit removed most of the issues.</p>
<p>Implementing this solution was a major part of taking down the running time of the complete algorithm for the full problem I was solving from about 2 days, to about 15-20 minutes. That was one fun optimizing session :)</p>
]]></content:encoded>
			<wfw:commentRss>http://www.algorithm.co.il/blogs/index.php/programming/python/my-solution-to-the-counting-sets-challenge/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Fractals in 10 minutes No. 6: Turtle Snowflake</title>
		<link>http://www.algorithm.co.il/blogs/index.php/programming/python/fractals-in-10-minutes-no-6-turtle-snowflake/</link>
		<comments>http://www.algorithm.co.il/blogs/index.php/programming/python/fractals-in-10-minutes-no-6-turtle-snowflake/#comments</comments>
		<pubDate>Mon, 31 Aug 2009 09:32:35 +0000</pubDate>
		<dc:creator>lorg</dc:creator>
				<category><![CDATA[Fractals]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[computer science]]></category>
		<category><![CDATA[turtle]]></category>

		<guid isPermaLink="false">http://www.algorithm.co.il/blogs/?p=320</guid>
		<description><![CDATA[I didn't write this one, but I found it's simplicity and availability so compelling, I couldn't just not write about it.
In a reddit post from a while ago, some commenter named jfedor left the following comment:
A little known fact is that you can do the following on any standard Python installation:


from turtle import *
def f&#40;length, [...]]]></description>
			<content:encoded><![CDATA[<p>I didn't write this one, but I found it's simplicity and availability so compelling, I couldn't just not write about it.<br />
In a reddit post from a while ago, some commenter named jfedor left the <a href="http://www.reddit.com/r/programming/comments/9733s/pythonturtle_the_lowestthreshold_way_to_learn/c0bnoei">following comment</a>:</p>
<blockquote><p>A little known fact is that you can do the following on any standard Python installation:</p>
<div class="syntax_hilite">
<div id="python-20">
<div class="python"><span style="color: #00007f;font-weight:bold;">from</span> <span style="color: #dc143c;">turtle</span> <span style="color: #00007f;font-weight:bold;">import</span> *</p>
<p><span style="color: #00007f;font-weight:bold;">def</span> f<span style="color: black;">&#40;</span>length, depth<span style="color: black;">&#41;</span>:<br />
&nbsp; &nbsp;<span style="color: #00007f;font-weight:bold;">if</span> depth == <span style="color: #ff4500;">0</span>:<br />
&nbsp; &nbsp; &nbsp;forward<span style="color: black;">&#40;</span>length<span style="color: black;">&#41;</span><br />
&nbsp; &nbsp;<span style="color: #00007f;font-weight:bold;">else</span>:<br />
&nbsp; &nbsp; &nbsp;f<span style="color: black;">&#40;</span>length/<span style="color: #ff4500;">3</span>, depth-<span style="color: #ff4500;">1</span><span style="color: black;">&#41;</span><br />
&nbsp; &nbsp; &nbsp;right<span style="color: black;">&#40;</span><span style="color: #ff4500;">60</span><span style="color: black;">&#41;</span><br />
&nbsp; &nbsp; &nbsp;f<span style="color: black;">&#40;</span>length/<span style="color: #ff4500;">3</span>, depth-<span style="color: #ff4500;">1</span><span style="color: black;">&#41;</span><br />
&nbsp; &nbsp; &nbsp;left<span style="color: black;">&#40;</span><span style="color: #ff4500;">120</span><span style="color: black;">&#41;</span><br />
&nbsp; &nbsp; &nbsp;f<span style="color: black;">&#40;</span>length/<span style="color: #ff4500;">3</span>, depth-<span style="color: #ff4500;">1</span><span style="color: black;">&#41;</span><br />
&nbsp; &nbsp; &nbsp;right<span style="color: black;">&#40;</span><span style="color: #ff4500;">60</span><span style="color: black;">&#41;</span><br />
&nbsp; &nbsp; &nbsp;f<span style="color: black;">&#40;</span>length/<span style="color: #ff4500;">3</span>, depth-<span style="color: #ff4500;">1</span><span style="color: black;">&#41;</span></p>
<p>f<span style="color: black;">&#40;</span><span style="color: #ff4500;">500</span>, <span style="color: #ff4500;">4</span><span style="color: black;">&#41;</span></div>
</div>
</div>
<p></p>
</blockquote>
<p>If you copy paste, it's a fractal in less than a minute. If you type it yourself, it's still less than 10. And it's something you can show a kid. I really liked this one.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.algorithm.co.il/blogs/index.php/programming/python/fractals-in-10-minutes-no-6-turtle-snowflake/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Small Python Challenge No. 4 &#8211; Counting Sets</title>
		<link>http://www.algorithm.co.il/blogs/index.php/computer-science/small-python-challenge-no-4-counting-sets/</link>
		<comments>http://www.algorithm.co.il/blogs/index.php/computer-science/small-python-challenge-no-4-counting-sets/#comments</comments>
		<pubDate>Fri, 28 Aug 2009 12:00:58 +0000</pubDate>
		<dc:creator>lorg</dc:creator>
				<category><![CDATA[Challenges]]></category>
		<category><![CDATA[computer science]]></category>
		<category><![CDATA[challenge]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Sets]]></category>

		<guid isPermaLink="false">http://www.algorithm.co.il/blogs/?p=315</guid>
		<description><![CDATA[This is a problem that I encountered a short while ago. It seems like it could be easily solved very efficiently, but it's not as easy as it looks.
Let's say that we are given N (finite) sets of integers - S. For now we won't assume anything about them. We are also given another set, [...]]]></description>
			<content:encoded><![CDATA[<p>This is a problem that I encountered a short while ago. It seems like it could be easily solved very efficiently, but it's not as easy as it looks.<br />
Let's say that we are given N (finite) sets of integers - S. For now we won't assume anything about them. We are also given another set, a. The challenge is to write an efficient algorithm that will count how many sets from S contain a (or how many sets from S a is a subset of).</p>
<p>Let's call a single test a comparison. The naive algorithm is of course checking each of the sets, which means exactly N comparisons. The challenge - can you do better? When will your solution outperform the naive solution?</p>
<p>I will give my solution in a few days. Submit your solutions in the comments, preferably in Python. You can write readable code using [ python ] [ /python ] blocks, just without the spaces.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.algorithm.co.il/blogs/index.php/computer-science/small-python-challenge-no-4-counting-sets/feed/</wfw:commentRss>
		<slash:comments>17</slash:comments>
		</item>
		<item>
		<title>Computing Large Determinants in Python</title>
		<link>http://www.algorithm.co.il/blogs/index.php/programming/python/computing-large-determinants-in-python/</link>
		<comments>http://www.algorithm.co.il/blogs/index.php/programming/python/computing-large-determinants-in-python/#comments</comments>
		<pubDate>Wed, 25 Mar 2009 19:38:08 +0000</pubDate>
		<dc:creator>lorg</dc:creator>
				<category><![CDATA[Algorithms]]></category>
		<category><![CDATA[Math]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[Research]]></category>
		<category><![CDATA[computer science]]></category>
		<category><![CDATA[Float]]></category>
		<category><![CDATA[Fractions]]></category>
		<category><![CDATA[Matrix Determinants]]></category>
		<category><![CDATA[Numerical Analysis]]></category>

		<guid isPermaLink="false">http://www.algorithm.co.il/blogs/?p=176</guid>
		<description><![CDATA[Story:
For my seminar work, I had to calculate the determinant of a large integer matrix.
In this case, large meant n>=500. You might say that this isn't very large and I would agree. However, it is large enough to overflow a float and reach +inf. Reaching +inf is bad: once you do, you lose all the [...]]]></description>
			<content:encoded><![CDATA[<p><strong>Story:</strong><br />
For my seminar work, I had to calculate the determinant of a large integer matrix.<br />
In this case, large meant n>=500. You might say that this isn't very large and I would agree. However, it is large enough to overflow a float and reach +inf. Reaching +inf is bad: once you do, you lose all the accuracy of the computation. Also, since determinant calculations use addition as well as subtraction, if +inf is reached in the middle of the calculation the value might never drop back, even if the determinant is a "small" number.</p>
<p>(Note: Even if the calculation hadn't reached +inf, but just some very large floating point number, the same phenomenon could have occurred.)</p>
<p>As I said, my matrix was composed of integers. Since a determinant is a sum of multiples of matrix elements, you would expect such a determinant to be an integer as well. It would be nice to take advantage of that fact.</p>
<p>How should one compute such a determinant? Well, luckily Python has support for arbitrarily large integers. Let's compute the determinant with them!<br />
Unfortunately, Python's numpy computes determinants using LU decomposition, which uses division - hence, floating point values.<br />
Well, never mind, I know how to calculate a determinant, right?<br />
Ten minutes later the naive determinant calculation by minors was implemented, with one "minor" setback -  it takes O(n!) time.<br />
Googling for integer determinants yielded some articles about division free algorithms, which weren't really easy to implement. There was one suggestion about using Rational numbers and Gauss Elimination, with pivots chosen to tame the growth of the nominator and denominator. </p>
<p>So, I hitched up a rational number class, using Python's arbitrarily large integers as nominator and denominator. Then, I got some code to do Gauss Elimination, although my pivoting wasn't the most fancy. This seemed to work, and I got my desired large determinants.</p>
<p><strong>Epilogue:</strong><br />
Not too long ago, I ran across <a href="http://code.google.com/p/mpmath/">mpmath</a>, a Python library for arbitrarily large floating point numbers. It is possible I could have used it instead of my own rational numbers. Next time I run into a relevant problem I'll keep this library in mind.<br />
Also, an even shorter while ago, I became aware that since 2.6 Python boasts a fractions module. This will sure come in handy in the future.</p>
<p><strong>Code:</strong><br />
<a href="http://www.algorithm.co.il/sitecode/intdet.py">Available here</a>. If you intend to use it in Python 2.6 and above, I suggest replacing my Rational class with Python's Fraction.<br />
(Note that I adapted this module to my needs. Therefore it has a timer that prints time estimations for computations, and it uses Psyco.)</p>
]]></content:encoded>
			<wfw:commentRss>http://www.algorithm.co.il/blogs/index.php/programming/python/computing-large-determinants-in-python/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Fractal Memory Usage and a Big Number</title>
		<link>http://www.algorithm.co.il/blogs/index.php/programming/python/fractal-memory-usage-and-a-big-number/</link>
		<comments>http://www.algorithm.co.il/blogs/index.php/programming/python/fractal-memory-usage-and-a-big-number/#comments</comments>
		<pubDate>Thu, 12 Jun 2008 18:31:50 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Algorithms]]></category>
		<category><![CDATA[Fractals]]></category>
		<category><![CDATA[Math]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[computer science]]></category>
		<category><![CDATA[exponentiation]]></category>
		<category><![CDATA[memory usage]]></category>

		<guid isPermaLink="false">http://www.algorithm.co.il/blogs/?p=110</guid>
		<description><![CDATA[In a previous post I said I'd talk about 4**(4**(4**4)).
First, about the number. I first saw it mentioned in a math lesson back in high-school, when the teacher wanted to demonstrate estimation abilities.
He wrote it on the board, like so:
4444
and then asked students to estimate how big that number is. Turns out this number is [...]]]></description>
			<content:encoded><![CDATA[<p>In a <a href="http://www.algorithm.co.il/blogs/index.php/programming/python/my-bad-memory-high-load-and-python/">previous post</a> I said I'd talk about 4**(4**(4**4)).<br />
First, about the number. I first saw it mentioned in a math lesson back in high-school, when the teacher wanted to demonstrate estimation abilities.<br />
He wrote it on the board, like so:</p>
<p><strong><big><big>4<sup>4<sup>4<sup>4</sup></sup></sup></big></big></strong></p>
<p>and then asked students to estimate how big that number is. Turns out this number is much bigger than most students thought. (For comparison, <a href="http://en.wikipedia.org/wiki/Observable_universe#Matter_content">the number of atoms in the observable universe is 10<sup>80</sup></a>.)</p>
<p>Given that this number is so big, it should come as no surprise that computing it will consume all available memory.<br />
What is interesting is the way the memory is consumed:</p>
<p><img src="http://www.algorithm.co.il/sitecode/exp_memory.png"></p>
<p>(It died with a MemoryError just before the next "jump".)</p>
<p>When I first saw this I was fascinated. To those interested it is generated by the long pow function in Python, implemented in longobject.c. According to the comment there, the algorithm is a left to right 5-ary exponentiation, taken from <a href="http://www.cacr.math.uwaterloo.ca/hac/about/chap14.pdf">"Handbook of Applied Cryptography"</a>.<br />
In short, the simpler algorithm "left-to-right binary exponentiation" (used for smaller exponents) repeatedly squares the accumulator, and according to the binary digits of the exponents, multiplies it by the base. 5-ary exponentiation basically does the same thing, but in each iteration it 'eats' five digits of the exponent instead of just one.</p>
<p>It might be very interesting to study algorithms and code according to their memory usage. Once at work I used a similar memory usage graph to optimize the memory usage of some algorithm that was eating too much memory. I don't remember the details as it happened a few years ago, but I do remember that I recognized the "type of the memory eating", which helped me to narrow the problem down to a specific area of code, where indeed the problem was located. (I consider this a case of programming-fu :)</p>
<p>Notes:<br />
1) The reason I'm talking about Python is because it has arbitrarily sized longs built-in.<br />
2) This graph was generated using Windows' task manager. On my Ubuntu machine it looks quite different, almost a straight line. Any guesses why?</p>
]]></content:encoded>
			<wfw:commentRss>http://www.algorithm.co.il/blogs/index.php/programming/python/fractal-memory-usage-and-a-big-number/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Issues in Writing a VM &#8211; Part 2</title>
		<link>http://www.algorithm.co.il/blogs/index.php/programming/python/issues-in-writing-a-vm-part-2/</link>
		<comments>http://www.algorithm.co.il/blogs/index.php/programming/python/issues-in-writing-a-vm-part-2/#comments</comments>
		<pubDate>Fri, 28 Mar 2008 23:16:59 +0000</pubDate>
		<dc:creator>lorg</dc:creator>
				<category><![CDATA[Algorithms]]></category>
		<category><![CDATA[Assembly]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Projects]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[computer science]]></category>
		<category><![CDATA[delay slot]]></category>
		<category><![CDATA[Disassembly]]></category>
		<category><![CDATA[Distorm]]></category>
		<category><![CDATA[Python generators]]></category>
		<category><![CDATA[vial]]></category>
		<category><![CDATA[VM]]></category>

		<guid isPermaLink="false">http://www.algorithm.co.il/blogs/index.php/programming/python/issues-in-writing-a-vm-part-2/</guid>
		<description><![CDATA[
Writing a VM capable of executing expression trees is different from writing a VM for executing assembly instructions. Here I'll cover several issues stemming from this difference.
The first group of issues involve generality. Supporting a specific instruction set is a straightforward job, even if a hard one. Vial has to support multiple platforms and that's [...]]]></description>
			<content:encoded><![CDATA[<p><img src="http://www.algorithm.co.il/sitecode/tim_screenshot_small.jpg" border="2" alt="The Incredible Machine" /></p>
<p>Writing a VM capable of executing expression trees is different from writing a VM for executing assembly instructions. Here I'll cover several issues stemming from this difference.</p>
<p>The first group of issues involve generality. Supporting a specific instruction set is a straightforward job, even if a hard one. Vial has to support multiple platforms and that's a little tricky. These are just a few of the problems:</p>
<ol>
<li><strong>Different registers for each instruction set</strong>. This one is easy enough to solve. Just have a node in the expression tree with some value to indicate the register.</li>
<li><strong>Register overlaps</strong>. A change to one register implies a change to its parents and its children. Consider RAX->EAX->AX->AH,AL. Changing EAX will affect all of the registers in the hierarchy.<br />
To handle this, we wrote a CPU class to keep all the info about the platform, including register overlaps.</li>
<li><strong>Delayed branches</strong>. Some platforms have branch delay slots. This means that after any branch instruction, right before the branch is taken, instructions in the delayed slots are executed anyway. For instance, SPARC has three delay slots, while MIPS has just one. This isn't an easy issue to solve, and for now we didn't tackle it. We've got a few ideas though.</li>
</ol>
<p>To make sure that our implementation is generic enough, we decided to write a skeleton disassembler implementation for MIPS as well.</p>
<p>The second group of issues involve the nature of expression trees versus instructions:</p>
<ol>
<li><strong>Stepping over statements or instructions</strong>? Each expression tree for an instruction usually holds more than one statement. For example, dec eax changes eax as well as the zero flag. Since some instructions like rep stosd may contain a long loop, being able to step over statements instead of expressions is preferable.
<p>The problem is, executing expression trees is done with a DFS-like walk. If implemented with recursion it makes pausing the walk for each step a bit complicated. However, recursion is the clearest way to write the execution code, and I'd rather not give it up.</p>
<p>My solution was to use Python generators. Each time a statement was executed, the function would yield, thus returning control to the calling function, while keeping its state intact.
 </li>
<li><strong>Instruction Pointer changes</strong>. The lower-level disassembler returns expression trees for each instruction. However, it does not return the jump to the next instruction as well. While this is the required behavior, it means that the VM should change the instruction pointer after executing each instruction.
<p>This is easier said than done: What should we do after jumps? Several possible solutions emerged. </p>
<p>The first was to append an IP change to each instruction's expression. Those changes will have to be appended only where needed.<br />
A second solution was to check if the IP was changed, and if it was not, change it. This solution however will not support instructions that jump to themselves.<br />
The last and our preferred solution was to check if the IP was touched. This solution is simple and very straightforward.</li>
</ol>
<p>There are many more issues I didn't write about, for example, self modifying code. I'll leave those issues for future articles.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.algorithm.co.il/blogs/index.php/programming/python/issues-in-writing-a-vm-part-2/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>Issues in writing a VM &#8211; Part 1</title>
		<link>http://www.algorithm.co.il/blogs/index.php/programming/issues-in-writing-a-vm-part-1/</link>
		<comments>http://www.algorithm.co.il/blogs/index.php/programming/issues-in-writing-a-vm-part-1/#comments</comments>
		<pubDate>Tue, 18 Mar 2008 21:03:20 +0000</pubDate>
		<dc:creator>lorg</dc:creator>
				<category><![CDATA[Assembly]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Projects]]></category>
		<category><![CDATA[Testing]]></category>
		<category><![CDATA[computer science]]></category>
		<category><![CDATA[Compilation]]></category>
		<category><![CDATA[Disassembly]]></category>
		<category><![CDATA[Distorm]]></category>
		<category><![CDATA[fuzzing]]></category>
		<category><![CDATA[vial]]></category>
		<category><![CDATA[VM]]></category>

		<guid isPermaLink="false">http://www.algorithm.co.il/blogs/index.php/programming/issues-in-writing-a-vm-part-1/</guid>
		<description><![CDATA[Arkon and I decided to write a VM for vial. First though, a short explanation on what is vial:
vial is a project aimed at writing a general disassembler that outputs expression trees instead of text. On top of vial, we intend to write various code-analysis tools. The expression trees in the output should be an [...]]]></description>
			<content:encoded><![CDATA[<p>Arkon and I decided to write a VM for vial. First though, a short explanation on what is vial:<br />
vial is a project aimed at writing a general disassembler that outputs expression trees instead of text. On top of vial, we intend to write various code-analysis tools. The expression trees in the output should be an accurate description of the all of the code's actions.<br />
(note: the x86 disassembler behind vial is Arkon's <a href="http://www.ragestorm.net/distorm/">diStorm</a>.) </p>
<p>So why do we need a VM? Apart from it being 'nice and all', it is <strong>critical</strong> for testing.</p>
<p>Some time ago, <a href="http://www.algorithm.co.il/blogs/index.php/programming/python/writing-a-quad-interpreter/">I described</a> writing a VM <a href="http://www.algorithm.co.il/blogs/index.php/programming/python/manually-fuzzing-my-own-compiler/">to test</a> a compiler I wrote as university homework. It is a similar issue here.<br />
The disassembler is written according to the x86 specification. If we just check its output against this specification, we are not doing much to verify the code's correctness. This is evident when you try to implement such a testing module - you end up writing another disassembler, and testing it against the original one. There has to be a different test method, one that does not directly rely on the specification. </p>
<p>Enter the VM. If you write a program, you can disassemble it, and then try to execute the disassembly. If it yields the same output as the original program - your test passed.<br />
This is a good testing method, because it can be easily automated, reach good code coverage, and it tests against known values.<br />
Consider the following illustration:</p>
<p><img src="http://www.algorithm.co.il/sitecode/vm_explanation.png" alt="Testing Process" /></p>
<p>We are testing here a complete process on the left hand, against a known valid value, the original program's output, on the right hand. All of the boxes on the left hand are tested along the way. Of course, one test may miss. For example, both the VM and the disassembler may generate wrong output for register overflows. We can try to cover as many such cases as possible by writing good tests for this testing framework. In this case, good tests are either c programs, or binary programs. This is essentially what I was doing when I <a href="http://www.algorithm.co.il/blogs/index.php/programming/python/manually-fuzzing-my-own-compiler/">manually fuzzed my own compiler</a>.</p>
<p>Once the VM is finished, we can start writing various optimizations for the disassembler's generated output. We can test these optimizations by checking the VM's output on the optimized code against the output on the original code. This makes the VM a critical milestone on the road ahead.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.algorithm.co.il/blogs/index.php/programming/issues-in-writing-a-vm-part-1/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
