<?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"
	>

<channel>
	<title>not just random</title>
	<atom:link href="http://www.notjustrandom.com/blog/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.notjustrandom.com/blog</link>
	<description></description>
	<pubDate>Thu, 13 Nov 2008 03:11:55 +0000</pubDate>
	<generator>http://wordpress.org/?v=2.6.3</generator>
	<language>en</language>
			<item>
		<title>Matching circular string rotations</title>
		<link>http://www.notjustrandom.com/blog/2008/11/12/matching-circular-string-rotations/</link>
		<comments>http://www.notjustrandom.com/blog/2008/11/12/matching-circular-string-rotations/#comments</comments>
		<pubDate>Thu, 13 Nov 2008 03:11:55 +0000</pubDate>
		<dc:creator>Alex</dc:creator>
		
		<category><![CDATA[Algorithms]]></category>

		<category><![CDATA[python]]></category>

		<guid isPermaLink="false">http://www.notjustrandom.com/blog/?p=139</guid>
		<description><![CDATA[This post examines two questions:

Is one string a circular rotation of a second string?
Is one string a substring of a (potentially rotated) second string?

Previously discussed Z-values are used for a solution.
Circular string rotation?
Given a prefix p of string t and a suffix s of string t, such that p + s = t, then a [...]]]></description>
			<content:encoded><![CDATA[<p>This post examines two questions:</p>
<ol>
<li>Is one string a circular rotation of a second string?</li>
<li>Is one string a substring of a (potentially rotated) second string?</li>
</ol>
<p><a href="http://www.notjustrandom.com/blog/2008/11/01/the-z-algorithm/">Previously discussed Z-values</a> are used for a solution.</p>
<p><strong>Circular string rotation?</strong></p>
<p>Given a prefix p of string t and a suffix s of string t, such that p + s = t, then a circular string rotation r is a string of the form s + p. Thus, it is a string that consists of the suffix of string t, directly followed by the prefix of string t, such that the resulting string r has the same length as the original string t: |r| = |t|.</p>
<p>Example:</p>
<p>Original:<br />
t = &#8220;abcd&#8221;</p>
<p>Rotation:<br />
r = &#8220;cdab&#8221;, with p = &#8220;ab&#8221; and s = &#8220;cd&#8221;</p>
<p><strong>How can one string be shown to be a circular rotation of a second string?</strong></p>
<p>If it is, then the lengths of the two strings t and r have to be identical. Also, since t = p + s and the rotation r = s + p, then 2r = r + r = s + p + s + p = s + t + p. Thus, if r is a rotation of t, then t is included completely within 2r. Not only that, but if it is shown that r is a rotation of t, then if t is found within 2r, more specific information can be shown about the rotation, because p and s can easily be indicated, too.</p>
<p>Assuming access to a fast string matching routine, the mechanism to answer the question should be straightforward:</p>
<pre>
If |t| = |r| and t in r+r
Then Circular Rotation
Else No Circular Rotation
</pre>
<p><strong>Saving space</strong></p>
<p>It may not be desirable to create a new string that contains twice the data of r, particularly assuming very large instances of strings r and t. Since r  = s + p is available though, it is easy to imagine what 2r would look like, without actually creating a new string consisting of 2r. </p>
<p>The <a href="http://www.notjustrandom.com/blog/2008/11/01/the-z-algorithm/">previously mentioned Z algorithm</a> can be heavily modified to </p>
<ol>
<li>operate on two strings, and </li>
<li>allow for Z-values up to maximum of the string length, regardless of the index position, effectively allowing for a substring to begin towards the end of the string and continue at the beginning of the string.</li>
</ol>
<p><strong>getMaxSuffixZ</strong></p>
<p>Let getMaxSuffixZ be a process that takes as input two strings, t and r and returns a maximum Z-value <= |t|. This involves calculating Z-values for each position in r and returning the largest one. In this case the Z-values are not calculated based on a prefix of r. Rather, string t is considered the prefix. So, if r is a rotation of t and t = p + s, then r = s + p, so maxZ should return |p|. It then only makes sense for maxZ to pick that maximum Z-Value that represents a substring that stretches to the end of r.</p>
<p>Here is the modified implementation:</p>

<div class="wp_syntax"><div class="code"><pre class="python"><span style="color: #ff7700;font-weight:bold;">def</span> getMaxSuffixZ<span style="color: black;">&#40;</span>p, s<span style="color: black;">&#41;</span>:
	result = <span style="color: black;">&#123;</span><span style="color: black;">&#125;</span>
	l = <span style="color: #ff4500;">0</span>
	r =  <span style="color: #ff4500;">-1</span>
	<span style="color: #ff7700;font-weight:bold;">for</span> k <span style="color: #ff7700;font-weight:bold;">in</span> <span style="color: #008000;">range</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">0</span>, <span style="color: #008000;">len</span><span style="color: black;">&#40;</span>s<span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>:
		<span style="color: #ff7700;font-weight:bold;">if</span> k &gt; r:
			zk = <span style="color: #ff4500;">0</span>
			<span style="color: #ff7700;font-weight:bold;">for</span> si <span style="color: #ff7700;font-weight:bold;">in</span> <span style="color: #008000;">range</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">0</span>, <span style="color: #008000;">len</span><span style="color: black;">&#40;</span>s<span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>:
				<span style="color: #ff7700;font-weight:bold;">if</span> k + si &lt; <span style="color: #008000;">len</span><span style="color: black;">&#40;</span>s<span style="color: black;">&#41;</span> <span style="color: #ff7700;font-weight:bold;">and</span> \
					si &lt; <span style="color: #008000;">len</span><span style="color: black;">&#40;</span>p<span style="color: black;">&#41;</span> <span style="color: #ff7700;font-weight:bold;">and</span> \
					p<span style="color: black;">&#91;</span>si<span style="color: black;">&#93;</span> == s<span style="color: black;">&#91;</span>k + si<span style="color: black;">&#93;</span>:
					zk += <span style="color: #ff4500;">1</span>
				<span style="color: #ff7700;font-weight:bold;">else</span>:
					<span style="color: #ff7700;font-weight:bold;">break</span>
			<span style="color: #ff7700;font-weight:bold;">if</span> zk &gt; <span style="color: #ff4500;">0</span>:
				r = zk + k - <span style="color: #ff4500;">1</span>
				l = k
		<span style="color: #ff7700;font-weight:bold;">else</span>:
			kOld = k - l - <span style="color: #ff4500;">1</span>
			zOld = result<span style="color: black;">&#91;</span>kOld<span style="color: black;">&#93;</span>
			b = r - k + <span style="color: #ff4500;">1</span>
			<span style="color: #ff7700;font-weight:bold;">if</span> zOld &lt; b:
				zk = zOld
			<span style="color: #ff7700;font-weight:bold;">else</span>:
				zk = b
				<span style="color: #ff7700;font-weight:bold;">for</span> si <span style="color: #ff7700;font-weight:bold;">in</span> <span style="color: #008000;">range</span><span style="color: black;">&#40;</span>b, <span style="color: #008000;">len</span><span style="color: black;">&#40;</span>s<span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>:
					<span style="color: #ff7700;font-weight:bold;">if</span> k + si &lt; <span style="color: #008000;">len</span><span style="color: black;">&#40;</span>s<span style="color: black;">&#41;</span> \
						<span style="color: #ff7700;font-weight:bold;">and</span> si &lt; <span style="color: #008000;">len</span><span style="color: black;">&#40;</span>p<span style="color: black;">&#41;</span> \
						<span style="color: #ff7700;font-weight:bold;">and</span> p<span style="color: black;">&#91;</span>si<span style="color: black;">&#93;</span> \
						== s<span style="color: black;">&#91;</span>k + si<span style="color: black;">&#93;</span>:
						<span style="color: #ff7700;font-weight:bold;">pass</span>
					<span style="color: #ff7700;font-weight:bold;">else</span>:
						<span style="color: #ff7700;font-weight:bold;">break</span>
				zk = si
				r = zk + k - <span style="color: #ff4500;">1</span>
				l = k
		result<span style="color: black;">&#91;</span>k<span style="color: black;">&#93;</span> = zk
		<span style="color: #ff7700;font-weight:bold;">if</span> zk == <span style="color: #008000;">len</span><span style="color: black;">&#40;</span>p<span style="color: black;">&#41;</span> - k:
			<span style="color: #ff7700;font-weight:bold;">return</span> zk
	<span style="color: #ff7700;font-weight:bold;">return</span> <span style="color: #ff4500;">0</span></pre></div></div>

<p>This returns the expected results at least for this sample set:</p>

<div class="wp_syntax"><div class="code"><pre class="python"><span style="color: #ff7700;font-weight:bold;">assert</span> getMaxSuffixZ<span style="color: black;">&#40;</span>s, <span style="color: #483d8b;">&quot;&quot;</span><span style="color: black;">&#41;</span> == <span style="color: #ff4500;">0</span>
<span style="color: #ff7700;font-weight:bold;">assert</span> getMaxSuffixZ<span style="color: black;">&#40;</span>s, <span style="color: #483d8b;">&quot;a&quot;</span><span style="color: black;">&#41;</span> == <span style="color: #ff4500;">0</span>
<span style="color: #ff7700;font-weight:bold;">assert</span> getMaxSuffixZ<span style="color: black;">&#40;</span>s, <span style="color: #483d8b;">&quot;b&quot;</span><span style="color: black;">&#41;</span> == <span style="color: #ff4500;">0</span>
<span style="color: #ff7700;font-weight:bold;">assert</span> getMaxSuffixZ<span style="color: black;">&#40;</span>s, <span style="color: #483d8b;">&quot;defabc&quot;</span><span style="color: black;">&#41;</span> == <span style="color: #ff4500;">3</span>
<span style="color: #ff7700;font-weight:bold;">assert</span> getMaxSuffixZ<span style="color: black;">&#40;</span>s, <span style="color: #483d8b;">&quot;defabcd&quot;</span><span style="color: black;">&#41;</span> == <span style="color: #ff4500;">0</span>
<span style="color: #ff7700;font-weight:bold;">assert</span> getMaxSuffixZ<span style="color: black;">&#40;</span>s, <span style="color: #483d8b;">&quot;abcdef&quot;</span><span style="color: black;">&#41;</span> == <span style="color: #ff4500;">6</span>
<span style="color: #ff7700;font-weight:bold;">assert</span> getMaxSuffixZ<span style="color: black;">&#40;</span>s, <span style="color: #483d8b;">&quot;fabcde&quot;</span><span style="color: black;">&#41;</span> == <span style="color: #ff4500;">5</span>
<span style="color: #ff7700;font-weight:bold;">print</span> <span style="color: #483d8b;">'all tests passed.'</span>
&nbsp;
all tests passed.</pre></div></div>

<p>Let z = getMaxSuffixZ(t, r). z is the prefix of t (and the suffix of r). If z > 0 then t[0..z-1] = r[z..|r|]. Similarly getMaxSuffixZ(r, t) yields the prefix of r (and the suffix of t).</p>

<div class="wp_syntax"><div class="code"><pre class="python">s = <span style="color: #483d8b;">&quot;abcdef&quot;</span>
<span style="color: #ff7700;font-weight:bold;">assert</span> getMaxSuffixZ<span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;&quot;</span>, s<span style="color: black;">&#41;</span> == <span style="color: #ff4500;">0</span>
<span style="color: #ff7700;font-weight:bold;">assert</span> getMaxSuffixZ<span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;a&quot;</span>, s<span style="color: black;">&#41;</span> == <span style="color: #ff4500;">1</span>
<span style="color: #ff7700;font-weight:bold;">assert</span> getMaxSuffixZ<span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;b&quot;</span>, s<span style="color: black;">&#41;</span> == <span style="color: #ff4500;">0</span>
<span style="color: #ff7700;font-weight:bold;">assert</span> getMaxSuffixZ<span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;defabc&quot;</span>, s<span style="color: black;">&#41;</span> == <span style="color: #ff4500;">3</span>
<span style="color: #ff7700;font-weight:bold;">assert</span> getMaxSuffixZ<span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;defabcd&quot;</span>, s<span style="color: black;">&#41;</span> == <span style="color: #ff4500;">0</span>
<span style="color: #ff7700;font-weight:bold;">assert</span> getMaxSuffixZ<span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;abcdef&quot;</span>, s<span style="color: black;">&#41;</span> == <span style="color: #ff4500;">6</span>
<span style="color: #ff7700;font-weight:bold;">assert</span> getMaxSuffixZ<span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;fabcde&quot;</span>, s<span style="color: black;">&#41;</span> == <span style="color: #ff4500;">1</span>
<span style="color: #ff7700;font-weight:bold;">print</span> <span style="color: #483d8b;">'all tests passed.'</span>
&nbsp;
all tests passed.</pre></div></div>

<p>If r is a rotation of t, then getMaxSuffixZ(t, r) + getMaxSuffixZ(r, t) = |t| = |r|. If t = r, then getMaxSuffixZ(t, r) = getMaxSuffixZ(r, t) = |t| = |r|. This leads to the following flow:</p>
<pre>
If |t| = |r|
Then
    zTr = getMaxSuffixZ(t, r)
    If zTr = |t|:
    Then Circular Rotation (t = r)
    Else
        If zTr = getMaxSuffixZ(r, t)
        Then Circular Rotation
        Else No Circular Rotation
Else No Circular Rotation
</pre>
<p><strong>getMaxZ</strong></p>
<p>Let getMaxZ have the same attributes of getMaxSuffixZ, with one exception: When finding matching substrings that begin at position k and reach to the end of the string s, the algorithm continues comparisons at the beginning of string s up to a maximum of position k-1. It no longer makes sense to stop at the first substring that reaches to the end of the string, as later substrings could have a longer reach into the beginning of the string. It does make sense to return a result as soon as a z-value is found that equals the length of the prefix.</p>

<div class="wp_syntax"><div class="code"><pre class="python"><span style="color: #ff7700;font-weight:bold;">def</span> getMaxZ<span style="color: black;">&#40;</span>p, s<span style="color: black;">&#41;</span>:
	result = <span style="color: black;">&#123;</span><span style="color: black;">&#125;</span>
	l = <span style="color: #ff4500;">0</span>
	r =  <span style="color: #ff4500;">-1</span>
	maxZk = <span style="color: #ff4500;">0</span>
	<span style="color: #ff7700;font-weight:bold;">for</span> k <span style="color: #ff7700;font-weight:bold;">in</span> <span style="color: #008000;">range</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">0</span>, <span style="color: #008000;">len</span><span style="color: black;">&#40;</span>s<span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>:
		<span style="color: #ff7700;font-weight:bold;">if</span> k &gt; r:
			zk = <span style="color: #ff4500;">0</span>
			<span style="color: #ff7700;font-weight:bold;">for</span> si <span style="color: #ff7700;font-weight:bold;">in</span> <span style="color: #008000;">range</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">0</span>, <span style="color: #008000;">len</span><span style="color: black;">&#40;</span>s<span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>:
				<span style="color: #ff7700;font-weight:bold;">if</span> k + si &lt; <span style="color: #008000;">len</span><span style="color: black;">&#40;</span>s<span style="color: black;">&#41;</span> <span style="color: #ff7700;font-weight:bold;">and</span> \
					si &lt; <span style="color: #008000;">len</span><span style="color: black;">&#40;</span>p<span style="color: black;">&#41;</span> <span style="color: #ff7700;font-weight:bold;">and</span> \
					p<span style="color: black;">&#91;</span>si<span style="color: black;">&#93;</span> == s<span style="color: black;">&#91;</span>k + si<span style="color: black;">&#93;</span>:
					zk += <span style="color: #ff4500;">1</span>
				<span style="color: #ff7700;font-weight:bold;">else</span>:
					<span style="color: #ff7700;font-weight:bold;">break</span>
			<span style="color: #ff7700;font-weight:bold;">if</span> zk &gt; <span style="color: #ff4500;">0</span>:
				r = zk + k - <span style="color: #ff4500;">1</span>
				l = k
				<span style="color: #ff7700;font-weight:bold;">if</span> r == <span style="color: #008000;">len</span><span style="color: black;">&#40;</span>s<span style="color: black;">&#41;</span> - <span style="color: #ff4500;">1</span>:
					r2 = <span style="color: #ff4500;">0</span>
					<span style="color: #ff7700;font-weight:bold;">for</span> si <span style="color: #ff7700;font-weight:bold;">in</span> <span style="color: #008000;">range</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">0</span>, k<span style="color: black;">&#41;</span>:
						<span style="color: #ff7700;font-weight:bold;">if</span> zk &lt; <span style="color: #008000;">len</span><span style="color: black;">&#40;</span>p<span style="color: black;">&#41;</span> <span style="color: #ff7700;font-weight:bold;">and</span> \
						p<span style="color: black;">&#91;</span>zk<span style="color: black;">&#93;</span> == s<span style="color: black;">&#91;</span>si<span style="color: black;">&#93;</span>:
							zk += <span style="color: #ff4500;">1</span>
							r2 += <span style="color: #ff4500;">1</span>
						<span style="color: #ff7700;font-weight:bold;">else</span>:
							<span style="color: #ff7700;font-weight:bold;">break</span>
		<span style="color: #ff7700;font-weight:bold;">else</span>:
			kOld = k - l - <span style="color: #ff4500;">1</span>
			zOld = result<span style="color: black;">&#91;</span>kOld<span style="color: black;">&#93;</span>
			b = r - k + <span style="color: #ff4500;">1</span>
			<span style="color: #ff7700;font-weight:bold;">if</span> zOld &lt; b:
				zk = zOld
			<span style="color: #ff7700;font-weight:bold;">else</span>:
				zk = b
				<span style="color: #ff7700;font-weight:bold;">for</span> si <span style="color: #ff7700;font-weight:bold;">in</span> <span style="color: #008000;">range</span><span style="color: black;">&#40;</span>b, <span style="color: #008000;">len</span><span style="color: black;">&#40;</span>s<span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>:
					<span style="color: #ff7700;font-weight:bold;">if</span> k + si &lt; <span style="color: #008000;">len</span><span style="color: black;">&#40;</span>s<span style="color: black;">&#41;</span> \
						<span style="color: #ff7700;font-weight:bold;">and</span> si &lt; <span style="color: #008000;">len</span><span style="color: black;">&#40;</span>p<span style="color: black;">&#41;</span> \
						<span style="color: #ff7700;font-weight:bold;">and</span> p<span style="color: black;">&#91;</span>si<span style="color: black;">&#93;</span> \
						== s<span style="color: black;">&#91;</span>k + si<span style="color: black;">&#93;</span>:
						<span style="color: #ff7700;font-weight:bold;">pass</span>
					<span style="color: #ff7700;font-weight:bold;">else</span>:
						<span style="color: #ff7700;font-weight:bold;">break</span>
				zk = si
				r = zk + k - <span style="color: #ff4500;">1</span>
				l = k
				<span style="color: #ff7700;font-weight:bold;">if</span> r == <span style="color: #008000;">len</span><span style="color: black;">&#40;</span>s<span style="color: black;">&#41;</span> - <span style="color: #ff4500;">1</span>:
					r2 = <span style="color: #ff4500;">0</span>
					<span style="color: #ff7700;font-weight:bold;">for</span> si <span style="color: #ff7700;font-weight:bold;">in</span> <span style="color: #008000;">range</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">0</span>, k<span style="color: black;">&#41;</span>:
						<span style="color: #ff7700;font-weight:bold;">if</span> zk &lt; <span style="color: #008000;">len</span><span style="color: black;">&#40;</span>p<span style="color: black;">&#41;</span> <span style="color: #ff7700;font-weight:bold;">and</span> \
						p<span style="color: black;">&#91;</span>zk<span style="color: black;">&#93;</span> == s<span style="color: black;">&#91;</span>si<span style="color: black;">&#93;</span>:
							zk += <span style="color: #ff4500;">1</span>
							r2 += <span style="color: #ff4500;">1</span>
						<span style="color: #ff7700;font-weight:bold;">else</span>:
							<span style="color: #ff7700;font-weight:bold;">break</span>
		result<span style="color: black;">&#91;</span>k<span style="color: black;">&#93;</span> = zk
		<span style="color: #ff7700;font-weight:bold;">if</span> zk &gt;= <span style="color: #008000;">len</span><span style="color: black;">&#40;</span>s<span style="color: black;">&#41;</span> - k:
			<span style="color: #ff7700;font-weight:bold;">if</span> zk &gt; maxZk:
				maxZk = zk
		<span style="color: #ff7700;font-weight:bold;">if</span> zk == <span style="color: #008000;">len</span><span style="color: black;">&#40;</span>p<span style="color: black;">&#41;</span>:
			<span style="color: #ff7700;font-weight:bold;">return</span> zk
	<span style="color: #ff7700;font-weight:bold;">return</span> maxZk</pre></div></div>

<p>Tests show the correct results:</p>

<div class="wp_syntax"><div class="code"><pre class="python">s = <span style="color: #483d8b;">&quot;abcdef&quot;</span>
<span style="color: #ff7700;font-weight:bold;">assert</span> getMaxZ<span style="color: black;">&#40;</span>s, s<span style="color: black;">&#41;</span> == <span style="color: #ff4500;">6</span>
<span style="color: #ff7700;font-weight:bold;">assert</span> getMaxZ<span style="color: black;">&#40;</span>s, <span style="color: #483d8b;">&quot;fabcde&quot;</span><span style="color: black;">&#41;</span> == <span style="color: #ff4500;">6</span>
<span style="color: #ff7700;font-weight:bold;">assert</span> getMaxZ<span style="color: black;">&#40;</span>s, <span style="color: #483d8b;">&quot;fgabcde&quot;</span><span style="color: black;">&#41;</span> == <span style="color: #ff4500;">6</span>
<span style="color: #ff7700;font-weight:bold;">assert</span> getMaxZ<span style="color: black;">&#40;</span>s, <span style="color: #483d8b;">&quot;a&quot;</span><span style="color: black;">&#41;</span> == <span style="color: #ff4500;">1</span>
<span style="color: #ff7700;font-weight:bold;">assert</span> getMaxZ<span style="color: black;">&#40;</span>s, <span style="color: #483d8b;">&quot;ba&quot;</span><span style="color: black;">&#41;</span> == <span style="color: #ff4500;">2</span>
<span style="color: #ff7700;font-weight:bold;">assert</span> getMaxZ<span style="color: black;">&#40;</span>s, <span style="color: #483d8b;">&quot;&quot;</span><span style="color: black;">&#41;</span> == <span style="color: #ff4500;">0</span>
<span style="color: #ff7700;font-weight:bold;">assert</span> getMaxZ<span style="color: black;">&#40;</span>s, <span style="color: #483d8b;">&quot;xyz&quot;</span><span style="color: black;">&#41;</span> == <span style="color: #ff4500;">0</span>
<span style="color: #ff7700;font-weight:bold;">assert</span> getMaxZ<span style="color: black;">&#40;</span>s, <span style="color: #483d8b;">&quot;defabcabcdabc&quot;</span><span style="color: black;">&#41;</span> == <span style="color: #ff4500;">6</span>
<span style="color: #ff7700;font-weight:bold;">assert</span> getMaxZ<span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;&quot;</span>, <span style="color: #483d8b;">&quot;&quot;</span><span style="color: black;">&#41;</span> == <span style="color: #ff4500;">0</span>
<span style="color: #ff7700;font-weight:bold;">assert</span> getMaxZ<span style="color: black;">&#40;</span>s, <span style="color: #483d8b;">&quot;defabc&quot;</span><span style="color: black;">&#41;</span> == <span style="color: #ff4500;">6</span>
<span style="color: #ff7700;font-weight:bold;">print</span> <span style="color: #483d8b;">'all tests passed.'</span>
&nbsp;
all tests passed.</pre></div></div>

<p>Following the above manner, the resulting flow looks like this:</p>
<pre>
If |t| = |r| and maxZ(t, r) = |t|
Then Circular Rotation
Else No Circular Rotation
</pre>
<p><strong>Matching substrings in string rotations</strong></p>
<p>Given the above discussion, a mechanism can be shown that allows the matching of substrings in circular string rotations. To illustrate the problem, in a string t = &#8220;abcd&#8221; it would then be possible to find substrings such as &#8220;abc&#8221;, &#8220;cda&#8221;, &#8220;da&#8221;, &#8220;dab&#8221;, etc.</p>
<p>The above algorithm can be applied directly:</p>
<pre>
Let t = text and p = substring to search
If getMaxZ(p, t) = |p|
Then p found in t
Else p not found in t
</pre>
<p>Likewise, getMaxZ can be applied to this problem directly:</p>

<div class="wp_syntax"><div class="code"><pre class="python"><span style="color: #ff7700;font-weight:bold;">def</span> showFound<span style="color: black;">&#40;</span>p, s<span style="color: black;">&#41;</span>:
	<span style="color: #ff7700;font-weight:bold;">if</span> getMaxZ<span style="color: black;">&#40;</span>p, s<span style="color: black;">&#41;</span> == <span style="color: #008000;">len</span><span style="color: black;">&#40;</span>p<span style="color: black;">&#41;</span>:
		<span style="color: #ff7700;font-weight:bold;">print</span> <span style="color: #483d8b;">&quot;%s found in %s&quot;</span> % <span style="color: black;">&#40;</span>p, s<span style="color: black;">&#41;</span>
	<span style="color: #ff7700;font-weight:bold;">else</span>:
		<span style="color: #ff7700;font-weight:bold;">print</span> <span style="color: #483d8b;">&quot;%s not found in %s&quot;</span> % <span style="color: black;">&#40;</span>p, s<span style="color: black;">&#41;</span>
&nbsp;
showFound<span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;ab&quot;</span>, s<span style="color: black;">&#41;</span>
showFound<span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;fa&quot;</span>, s<span style="color: black;">&#41;</span>
showFound<span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;abcdef&quot;</span>, s<span style="color: black;">&#41;</span>
showFound<span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;x&quot;</span>, s<span style="color: black;">&#41;</span>
showFound<span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;abc&quot;</span>, <span style="color: #483d8b;">&quot;&quot;</span><span style="color: black;">&#41;</span>
showFound<span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;efabcd&quot;</span>, s<span style="color: black;">&#41;</span>
showFound<span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;efgabc&quot;</span>, s<span style="color: black;">&#41;</span>
showFound<span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;abd&quot;</span>, s<span style="color: black;">&#41;</span></pre></div></div>

<p>The results look correct.</p>
<pre>
ab found in abcdef
fa found in abcdef
abcdef found in abcdef
x not found in abcdef
abc not found in
efabcd found in abcdef
efgabc not found in abcdef
abd not found in abcdef
</pre>
<p>It would make sense to add modifications to allow detecting all instances (up to a specifiable number) of substring matches along with their positions.</p>
<p><strong>Next?</strong></p>
<p>Run-time analysis. And lots of code cleanup!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.notjustrandom.com/blog/2008/11/12/matching-circular-string-rotations/feed/</wfw:commentRss>
		</item>
		<item>
		<title>AI Landscape</title>
		<link>http://www.notjustrandom.com/blog/2008/11/03/ai-landscape/</link>
		<comments>http://www.notjustrandom.com/blog/2008/11/03/ai-landscape/#comments</comments>
		<pubDate>Tue, 04 Nov 2008 03:50:30 +0000</pubDate>
		<dc:creator>Alex</dc:creator>
		
		<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://www.notjustrandom.com/blog/?p=130</guid>
		<description><![CDATA[AI Magazine recently published the following poster.
It is a nice visualization of some of the many areas of life that are impacted by current AI.
]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.aaai.org/Magazine/magazine.php">AI Magazine</a> recently published the following poster.</p>
<a href="http://www.aaai.org/Magazine/ailandscape.php"><img src="http://www.notjustrandom.com/blog/wp-content/uploads/2008/11/ailandscape-300x235.jpg" alt="AI Landscape" title="ailandscape" width="300" height="235" class="size-medium wp-image-129" /></a>
<p>It is a nice visualization of some of the many areas of life that are impacted by current AI.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.notjustrandom.com/blog/2008/11/03/ai-landscape/feed/</wfw:commentRss>
		</item>
		<item>
		<title>The Z Algorithm</title>
		<link>http://www.notjustrandom.com/blog/2008/11/01/the-z-algorithm/</link>
		<comments>http://www.notjustrandom.com/blog/2008/11/01/the-z-algorithm/#comments</comments>
		<pubDate>Sat, 01 Nov 2008 22:26:24 +0000</pubDate>
		<dc:creator>Alex</dc:creator>
		
		<category><![CDATA[Algorithms]]></category>

		<category><![CDATA[Z]]></category>

		<category><![CDATA[python]]></category>

		<guid isPermaLink="false">http://www.notjustrandom.com/blog/?p=128</guid>
		<description><![CDATA[In Algorithms on Strings, Trees and Sequences, Dan Gusfield presents the Z algorithm. 
A string prefix P is a substring of S that begins at S[0]. The Z algorithm calculates for each position k > 0 in S the maximum length of P that is matched by a substring starting at k. The algorithm performs [...]]]></description>
			<content:encoded><![CDATA[<p>In <a href="http://www.amazon.com/Algorithms-Strings-Trees-Sequences-Computational/dp/0521585198">Algorithms on Strings, Trees and Sequences</a>, Dan Gusfield presents the Z algorithm. </p>
<p>A string prefix P is a substring of S that begins at S[0]. The Z algorithm calculates for each position k > 0 in S the maximum length of P that is matched by a substring starting at k. The algorithm performs in linear time by keeping track of previously calculated values and recognizing, if the character at a currently examined start position is within a previously detected substring.</p>
<p><strong>An example</strong></p>
<p>Here is a string S and its Z-values for each index position k:</p>
<p>S = &#8216;aabcaabxaaaz&#8217;</p>
<table>
<tr>
<th width="35%">k
<th width="35%">s[k]
<th width="30%">Z</p>
<tr>
<td>0
<td>a
<td>n/a</p>
<tr>
<td>1
<td>a
<td>1</p>
<tr>
<td>2
<td>b
<td>0</p>
<tr>
<td>3
<td>c
<td>0</p>
<tr>
<td>4
<td>a
<td>3</p>
<tr>
<td>5
<td>a
<td>1</p>
<tr>
<td>6
<td>b
<td>0</p>
<tr>
<td>7
<td>x
<td>0</p>
<tr>
<td>8
<td>a
<td>2</p>
<tr>
<td>9
<td>a
<td>2</p>
<tr>
<td>10
<td>a
<td>1</p>
<tr>
<td>11
<td>z
<td>0<br />
</table>
<p><strong>Step by step</strong></p>
<p>Let&#8217;s look at a these one at a time to show how easily the Z-values can be computed.</p>
<p><strong>k = 1</strong></p>
<p>Then s[0] = s[1], but s[1] != [2], so Z[1] = 1. The matched substring has the boundaries l = 1 and r = 1, so s[l..r] = s[1..1] = &#8216;a&#8217;</p>
<p><strong>k = 2</strong></p>
<p>Then k > r, which means s[2] is outside the previously discovered substring. s[0] != s[2], so<br />
Z[2] = 0.</p>
<p><strong>k = 3</strong></p>
<p>In the same manner, if k = 3, s[0] != s[3], so Z[3] = 0.</p>
<p><strong>k = 4</strong></p>
<p>Then s[0] = s[4], s[1] = s[5], s[2] = s[6], but s[3] != s[7], so Z[4] = 3. The matched substring has the boundaries l = 4 and r = 6, so s[l..r] = s[4..6] = &#8216;aab&#8217;</p>
<p><strong>k = 5</strong></p>
<p>Then k <= r: s[5] is within a previously discovered substring. The previously discovered substring starts at k - l = 5 - 4 = 1. The Z-value found at that position is Z[1] = 1. Since that value is smaller than the length of the remaining substring S[k..r], there is no need to perform other character comparisons. Z[5] = Z[1] = 1. l and r remain unchanged.</p>
<p><strong>k = 6</strong></p>
<p>In the same manner, if k = 6, then Z[6] = z[2] = 0. </p>
<p><strong>k = 7</strong></p>
<p>Then k > r, s[0] != s[7], so Z[7] = 0.</p>
<p><strong>k = 8</strong></p>
<p>Then k > r, s[0] = s[8], s[1] = s[9] and s[2] != s[10], so Z[8] = 2. The matched substring has the boundaries l = 8 and r = 9, so s[l..r] = s[8..9] = &#8216;aa&#8217;.</p>
<p><strong>k = 9</strong></p>
<p>Then k <= r, so s[k] is within a previously discovered substring. The previously discovered substring starts at k - l = 9 - 8 = 1. The Z-value found at that position is Z[1] = 1. That value is not smaller than the length of the remaining substring S[k..r] = s[9..9] = 'a', so additional character comparisons need to be performed. Let b = r - k + 1 = 9 - 9 + 1. Z[9] will be >= b. s[b] = s[1] = s[k + b] = s[10], but s[2] != s[11], so Z[9] = 2. The new substring has the boundaries l = 9 and r = 10.</p>
<p><strong>k = 10</strong></p>
<p>Then k = r, so s[k] is within the previously discovered substring of s[l..r]. The z-value for that string is Z[k - l] = Z[10-9] = Z[1] = 1. Since that value is equal to the length of the remainder of the substring s[k..r], additional comparisons are performed, but since s[2] != s[11], Z[10] = Z[1] = 1.</p>
<p><strong>k = 11</strong></p>
<p>Then k < r and since s[0] != s[11], Z[11] = 0.</p>
<p><strong>Implementation</strong></p>
<p>Here is the implementation of the algorithm (as outlined in the book) in Python:</p>

<div class="wp_syntax"><div class="code"><pre class="python"><span style="color: #ff7700;font-weight:bold;">def</span> getZ<span style="color: black;">&#40;</span>s<span style="color: black;">&#41;</span>:
	result = <span style="color: black;">&#123;</span><span style="color: black;">&#125;</span>
&nbsp;
	l = r = <span style="color: #ff4500;">0</span>
	<span style="color: #ff7700;font-weight:bold;">for</span> k <span style="color: #ff7700;font-weight:bold;">in</span> <span style="color: #008000;">range</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">1</span>, <span style="color: #008000;">len</span><span style="color: black;">&#40;</span>s<span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>:
		<span style="color: #ff7700;font-weight:bold;">if</span> k &gt; r:
			zk = <span style="color: #ff4500;">0</span>
			<span style="color: #ff7700;font-weight:bold;">for</span> si <span style="color: #ff7700;font-weight:bold;">in</span> <span style="color: #008000;">range</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">0</span>, <span style="color: #008000;">len</span><span style="color: black;">&#40;</span>s<span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>:
				<span style="color: #ff7700;font-weight:bold;">if</span> k + si &lt; <span style="color: #008000;">len</span><span style="color: black;">&#40;</span>s<span style="color: black;">&#41;</span> <span style="color: #ff7700;font-weight:bold;">and</span> \
					s<span style="color: black;">&#91;</span>si<span style="color: black;">&#93;</span> == s<span style="color: black;">&#91;</span>k + si<span style="color: black;">&#93;</span>:
					<span style="color: #ff7700;font-weight:bold;">pass</span>
				<span style="color: #ff7700;font-weight:bold;">else</span>:
					<span style="color: #ff7700;font-weight:bold;">break</span>
			<span style="color: #ff7700;font-weight:bold;">if</span> si &gt; <span style="color: #ff4500;">0</span>:
				zk = si
				r = zk + k - <span style="color: #ff4500;">1</span>
				l = k
		<span style="color: #ff7700;font-weight:bold;">else</span>:
			kOld = k - l
			zOld = result<span style="color: black;">&#91;</span>kOld<span style="color: black;">&#93;</span>
			b = r - k + <span style="color: #ff4500;">1</span>
			<span style="color: #ff7700;font-weight:bold;">if</span> zOld &lt; b:
				zk = zOld
			<span style="color: #ff7700;font-weight:bold;">else</span>:
				zk = b
&nbsp;
				<span style="color: #ff7700;font-weight:bold;">for</span> si <span style="color: #ff7700;font-weight:bold;">in</span> <span style="color: #008000;">range</span><span style="color: black;">&#40;</span>b, <span style="color: #008000;">len</span><span style="color: black;">&#40;</span>s<span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>:
					<span style="color: #ff7700;font-weight:bold;">if</span> k + si &lt; <span style="color: #008000;">len</span><span style="color: black;">&#40;</span>s<span style="color: black;">&#41;</span> \
						<span style="color: #ff7700;font-weight:bold;">and</span> s<span style="color: black;">&#91;</span>si<span style="color: black;">&#93;</span> \
						== s<span style="color: black;">&#91;</span>k + si<span style="color: black;">&#93;</span>:
						<span style="color: #ff7700;font-weight:bold;">pass</span>
					<span style="color: #ff7700;font-weight:bold;">else</span>:
						<span style="color: #ff7700;font-weight:bold;">break</span>
				zk = si
				r = zk + k - <span style="color: #ff4500;">1</span>
				l = k
		result<span style="color: black;">&#91;</span>k<span style="color: black;">&#93;</span> = zk
	<span style="color: #ff7700;font-weight:bold;">return</span> result</pre></div></div>

<p>That code deserves some cleanup, but it does yield the correct result:</p>

<div class="wp_syntax"><div class="code"><pre class="python">s = <span style="color: #483d8b;">'aabcaabxaaaz'</span>
z = getZ<span style="color: black;">&#40;</span>s<span style="color: black;">&#41;</span>
<span style="color: #ff7700;font-weight:bold;">for</span> k <span style="color: #ff7700;font-weight:bold;">in</span> <span style="color: #008000;">range</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">1</span>, <span style="color: #008000;">len</span><span style="color: black;">&#40;</span>s<span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>:
	<span style="color: #ff7700;font-weight:bold;">print</span> k, z<span style="color: black;">&#91;</span>k<span style="color: black;">&#93;</span>
<span style="color: #ff4500;">1</span> <span style="color: #ff4500;">1</span>
<span style="color: #ff4500;">2</span> <span style="color: #ff4500;">0</span>
<span style="color: #ff4500;">3</span> <span style="color: #ff4500;">0</span>
<span style="color: #ff4500;">4</span> <span style="color: #ff4500;">3</span>
<span style="color: #ff4500;">5</span> <span style="color: #ff4500;">1</span>
<span style="color: #ff4500;">6</span> <span style="color: #ff4500;">0</span>
<span style="color: #ff4500;">7</span> <span style="color: #ff4500;">0</span>
<span style="color: #ff4500;">8</span> <span style="color: #ff4500;">2</span>
<span style="color: #ff4500;">9</span> <span style="color: #ff4500;">2</span>
<span style="color: #ff4500;">10</span> <span style="color: #ff4500;">1</span>
<span style="color: #ff4500;">11</span> <span style="color: #ff4500;">0</span></pre></div></div>

<p><strong>Next?</strong></p>
<p>The Z algorithm can be used as a precursor for additional string analysis. With little modification it can also be changed to work as a simple, linear exact matching algorithm.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.notjustrandom.com/blog/2008/11/01/the-z-algorithm/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Holiday Inn Express Marketing</title>
		<link>http://www.notjustrandom.com/blog/2008/10/20/holiday-inn-express-marketing/</link>
		<comments>http://www.notjustrandom.com/blog/2008/10/20/holiday-inn-express-marketing/#comments</comments>
		<pubDate>Mon, 20 Oct 2008 18:18:14 +0000</pubDate>
		<dc:creator>Alex</dc:creator>
		
		<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://www.notjustrandom.com/blog/?p=126</guid>
		<description><![CDATA[The freestyle battle rap version.

]]></description>
			<content:encoded><![CDATA[<p>The freestyle battle rap version.</p>
<p><object width="425" height="344"><param name="movie" value="http://www.youtube.com/v/D-PzDk_brV0&#038;hl=en&#038;fs=1"></param><param name="allowFullScreen" value="true"></param><embed src="http://www.youtube.com/v/D-PzDk_brV0&#038;hl=en&#038;fs=1" type="application/x-shockwave-flash" allowfullscreen="true" width="425" height="344"></embed></object></p>
]]></content:encoded>
			<wfw:commentRss>http://www.notjustrandom.com/blog/2008/10/20/holiday-inn-express-marketing/feed/</wfw:commentRss>
		</item>
		<item>
		<title>debate facts</title>
		<link>http://www.notjustrandom.com/blog/2008/10/19/debate-facts/</link>
		<comments>http://www.notjustrandom.com/blog/2008/10/19/debate-facts/#comments</comments>
		<pubDate>Mon, 20 Oct 2008 03:40:32 +0000</pubDate>
		<dc:creator>Alex</dc:creator>
		
		<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://www.notjustrandom.com/blog/?p=125</guid>
		<description><![CDATA[Lately, it has been interesting to follow the presidential debates. As media fact checks reveal, not all statements uttered during the debates are factually correct. This is disappointing for the viewer, who may want to get a clearer understanding of each candidate&#8217;s position.
Wouldn&#8217;t it be nice if this fact check occurred in real time and [...]]]></description>
			<content:encoded><![CDATA[<p>Lately, it has been interesting to follow <a href="http://en.wikipedia.org/wiki/United_States_presidential_election_debates">the presidential debates</a>. As media fact checks reveal, not all statements uttered during the debates are factually correct. This is disappointing for the viewer, who may want to get a clearer understanding of each candidate&#8217;s position.</p>
<p>Wouldn&#8217;t it be nice if this fact check occurred in real time and the results could directly impact the flow of the debate? Maybe a team of researchers could continuously examine and verify any claim made and report results back to the debate moderator. If a claim was found to be false, the moderator could call the candidate on it right then and there. </p>
<p>Alternatively, siren sounds and/or intrusively blinking yellow or red lights may be suitable.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.notjustrandom.com/blog/2008/10/19/debate-facts/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Where to go when</title>
		<link>http://www.notjustrandom.com/blog/2008/09/21/where-to-go-when/</link>
		<comments>http://www.notjustrandom.com/blog/2008/09/21/where-to-go-when/#comments</comments>
		<pubDate>Sun, 21 Sep 2008 20:52:32 +0000</pubDate>
		<dc:creator>Alex</dc:creator>
		
		<category><![CDATA[google maps]]></category>

		<category><![CDATA[travel]]></category>

		<category><![CDATA[world reviewer]]></category>

		<guid isPermaLink="false">http://www.notjustrandom.com/blog/?p=124</guid>
		<description><![CDATA[At the end of last year, when the days around here were short, gray and wet, I brought home a copy of Where To Go When. The book describes vacation trips, sorted by month and contains sample itineraries, price ranges as well as lots and lots of beautiful photos. It&#8217;s a large-format, visually pleasing book [...]]]></description>
			<content:encoded><![CDATA[<p>At the end of last year, when the days around here were short, gray and wet, I brought home a copy of <a href="http://www.amazon.com/Where-When-Eyewitness-Travel-Guides/dp/0756630738">Where To Go When</a>. The book describes vacation trips, sorted by month and contains sample itineraries, price ranges as well as lots and lots of beautiful photos. It&#8217;s a large-format, visually pleasing book that belongs on a coffee table and always invites browsing and daydreaming of future trips or possible adventures.</p>
<p>Major travel websites tend to work best when customers already have a pretty good idea what kind of trip they are looking for. It is a fairly active and probably increasingly crowded market though. More and more, companies are emerging that offer web services that aim to help customers discover trip or vacation ideas.</p>
<p>Intended date ranges along with desired weather are useful criteria for a vacation planning. Unfortunately, it turns out that those combinations are as of yet fairly underutilized among travel websites. I recently came across <a href="http://www.worldreviewer.com/">World Reviewer</a>. They present weather data by month using an intuitive google maps mashup on their <a href="http://www.worldreviewer.com/world-weather/">World weather</a> page. </p>
<p>They do have other interesting features on their site, but the world weather visualization really stood out to me. I think, major travel websites will probably do well including similar features as additional travel planning tools.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.notjustrandom.com/blog/2008/09/21/where-to-go-when/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Geodreieck?</title>
		<link>http://www.notjustrandom.com/blog/2008/07/09/geodreieck/</link>
		<comments>http://www.notjustrandom.com/blog/2008/07/09/geodreieck/#comments</comments>
		<pubDate>Wed, 09 Jul 2008 19:59:23 +0000</pubDate>
		<dc:creator>Alex</dc:creator>
		
		<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://www.notjustrandom.com/blog/?p=123</guid>
		<description><![CDATA[I was recently in a similar predicament as Simon describes in No “Geodreieck” in the UK?, the ARISTO brand. I have not been able to find the mentioned tool locally, nor at the usual online locations here in the states.
Very surprising.
It actually wasn&#8217;t easy to find a German office supplies online store that ships worldwide [...]]]></description>
			<content:encoded><![CDATA[<p>I was recently in a similar predicament as Simon describes in <a href="http://ninau.net/wordpress/design/2008-02/no-geodreieck-in-the-uk-the-aristo-brand">No “Geodreieck” in the UK?, the ARISTO brand</a>. I have not been able to find the mentioned tool locally, nor at the usual online locations here in the states.</p>
<p>Very surprising.</p>
<p>It actually wasn&#8217;t easy to find a German office supplies online store that ships worldwide either. <a href="http://www.klammeraffe24.de/">Klammeraffe24.de</a> appears to be the solution. Let&#8217;s see how long delivery will take.</p>
<p>Update: They arrived on July 25.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.notjustrandom.com/blog/2008/07/09/geodreieck/feed/</wfw:commentRss>
		</item>
		<item>
		<title>startup school 2008 video feed</title>
		<link>http://www.notjustrandom.com/blog/2008/04/19/startup-school-2008-video-feed/</link>
		<comments>http://www.notjustrandom.com/blog/2008/04/19/startup-school-2008-video-feed/#comments</comments>
		<pubDate>Sat, 19 Apr 2008 23:03:01 +0000</pubDate>
		<dc:creator>Alex</dc:creator>
		
		<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://www.notjustrandom.com/blog/2008/04/19/startup-school-2008-video-feed/</guid>
		<description><![CDATA[I applied and received an invite for startup school, but eventually decided against making the trip down to Palo Alto. There has just been too much going on lately.
This is very convenient though: There is a live video feed available. Very cool.
]]></description>
			<content:encoded><![CDATA[<p>I applied and received an invite for <a href="http://www.startupschool.org">startup school</a>, but eventually decided against making the trip down to Palo Alto. There has just been too much going on lately.</p>
<p>This is very convenient though: There is a <a href="http://www.justin.tv/hackertv">live video feed</a> available. Very cool.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.notjustrandom.com/blog/2008/04/19/startup-school-2008-video-feed/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Sphere has been acquired by AOL</title>
		<link>http://www.notjustrandom.com/blog/2008/04/15/sphere-has-been-acquired-by-aol/</link>
		<comments>http://www.notjustrandom.com/blog/2008/04/15/sphere-has-been-acquired-by-aol/#comments</comments>
		<pubDate>Tue, 15 Apr 2008 18:45:39 +0000</pubDate>
		<dc:creator>Alex</dc:creator>
		
		<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://www.notjustrandom.com/blog/2008/04/15/sphere-has-been-acquired-by-aol/</guid>
		<description><![CDATA[It is official now. Sphere has been acquired by AOL. There is additional coverage over on Techmeme.
This is great news and I am very happy about it.
Before I go any further, I want to specifically thank my wife Jenny for her support during the last two years. We&#8217;ve been busy. There were incidents, when work [...]]]></description>
			<content:encoded><![CDATA[<p>It is official now. <a href="http://www.sphere.com">Sphere</a> has been <a href="http://corp.aol.com/press_releases/2008/04/aol-acquires-sphere">acquired</a> by <a href="http://www.aol.com">AOL</a>. There is additional coverage over on <a href="http://www.techmeme.com/080415/p2#a080415p2">Techmeme</a>.</p>
<p>This is great news and I am very happy about it.</p>
<p>Before I go any further, I want to specifically thank my wife Jenny for her support during the last two years. We&#8217;ve been busy. There were incidents, when work caused me to work long hours or affected evenings or weekends. She also had to (involuntary) witness a lot of ranting, brainstorming, problem solving as well as feature designing. More than once did she volunteer for late caffeine and snack runs. I know, she would categorically dismiss her role in this, but I am blown away by the amount of patience she is able to muster. So, seriously: Thank you, Jenny!</p>
<p>It has been a pretty exciting ride and it looks like it will continue to be that way. Yes, great people, lots of interesting problems to solve, fun things to learn, etc. - those who know me well have probably heard me talk similarly about Sphere before. There is real talent here, real energy and I don&#8217;t think this will change anytime soon.</p>
<p>I am looking forward to continue working with my colleagues and friends at Sphere and seeing our technology integrated at AOL.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.notjustrandom.com/blog/2008/04/15/sphere-has-been-acquired-by-aol/feed/</wfw:commentRss>
		</item>
		<item>
		<title>previous and next ads?</title>
		<link>http://www.notjustrandom.com/blog/2008/04/03/previous-and-next-ads/</link>
		<comments>http://www.notjustrandom.com/blog/2008/04/03/previous-and-next-ads/#comments</comments>
		<pubDate>Thu, 03 Apr 2008 16:22:30 +0000</pubDate>
		<dc:creator>Alex</dc:creator>
		
		<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://www.notjustrandom.com/blog/2008/04/03/previous-and-next-ads/</guid>
		<description><![CDATA[Just came across the following on LinkedIn:


Note the two arrows on the bottom left. Yes, their function is indeed to show a next/previous list of related advertisement. 
Hm, really? Speaking as a user, this feature is not something I ever found myself hoping for. Now that it&#8217;s there, I will probably try my best to [...]]]></description>
			<content:encoded><![CDATA[<p>Just came across the following on LinkedIn:</p>
<blockquote><p><a href='http://www.notjustrandom.com/blog/wp-content/uploads/2008/04/moreads.jpg' title='moreads'><img src='http://www.notjustrandom.com/blog/wp-content/uploads/2008/04/moreads.jpg' alt='moreads' width="90%"/></a>
</p></blockquote>
<p>Note the two arrows on the bottom left. Yes, their function is indeed to show a next/previous list of related advertisement. </p>
<p>Hm, really? Speaking as a user, this feature is not something I ever found myself hoping for. Now that it&#8217;s there, I will probably try my best to ignore it.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.notjustrandom.com/blog/2008/04/03/previous-and-next-ads/feed/</wfw:commentRss>
		</item>
	</channel>
</rss>
