<?xml version="1.0" encoding="UTF-8" standalone="yes"?><oembed><version><![CDATA[1.0]]></version><provider_name><![CDATA[The Osmosian Order of Plain English Programmers Welcomes You]]></provider_name><provider_url><![CDATA[http://osmosianplainenglishprogramming.blog]]></provider_url><author_name><![CDATA[gerryrzeppa]]></author_name><author_url><![CDATA[https://osmosianplainenglishprogramming.blog/author/gerryrzeppa/]]></author_url><title><![CDATA[Kobayashi Maru Primes]]></title><type><![CDATA[link]]></type><html><![CDATA[<header class="entry-header">
<h1 class="entry-title"></h1>
</header>
<div class="entry-content">
<p>It has been said that <em>“Great engineering strikes a balance between competing objectives.”</em> I believe this to be true, in both mechanical and software engineering. In the latter, the competing objectives are typically clarity, size, and speed.</p>
<p>So I thought it a great opportunity to apply this principle when a computer scientist in South America challenged me to write a Plain English program, based on the Sieve of Eratosthenes, that could count the number of primes less than 250,000 in less than a second (on a bottom-of-the-line computer from Walmart).</p>
<p>Now Plain English is not the fastest language on earth, because clarity trumps speed when the primary goal of a language is to be <em>natural</em>. But Plain English is a <em>reasonably </em>fast language, and by balancing competing objectives, we can usually find an acceptable solution to any problem laid before us.</p>
<p>In this case, we first needed to make the famous Sieve of Eratosthenes clear; easy to understand. So we started with Wikipedia’s description of the algorithm…</p>
<blockquote><p>To find all the prime numbers less than or equal to a given integer n by Eratosthenes’ method:<br />
1. Create a list of consecutive integers from 2 through n: (2, 3, 4, …, n).<br />
2. Initially, let p equal 2, the smallest prime number.<br />
3. Enumerate the multiples of p by counting to n from 2p in increments of p, and mark them in the list (these will be 2p, 3p, 4p, …; the p itself should not be marked).<br />
4. Find the first number greater than p in the list that is not marked. If there is no such number, stop. Otherwise, let p now equal this new number (which is the next prime), and repeat from step 3.</p></blockquote>
<p>…which in Plain English reads like this:</p>
<p><span style="color:#00ccff;">To make a list of prime numbers less than or equal to a number:</span><br />
<span style="color:#00ccff;"> Create the list of consecutive integers from 2 to the number. <span style="color:#000000;">\ wiki&#8217;s #1</span></span><br />
<span style="color:#00ccff;"> Get an entry from the list.<span style="color:#000000;"> \ wiki&#8217;s #2</span></span><br />
<span style="color:#00ccff;"> Loop. Mark higher multiples of the entry.<span style="color:#000000;"> \ wiki&#8217;s #3</span></span><br />
<span style="color:#00ccff;"> Get the entry for the next lowest possible prime. If the entry is not nil, repeat.<span style="color:#000000;"> \ wiki&#8217;s #4</span></span></p>
<p>That takes care of the <em>clarity </em>objective. If you’re wondering, the type definitions and support routines that make that actually work are equally clear:</p>
<p><span style="color:#00ccff;">An entry is a thing with a number and a non-prime flag.</span><br />
<span style="color:#00ccff;"> A list is some entries.</span></p>
<p><span style="color:#00ccff;">To create a list of consecutive integers from a number to another number:</span><br />
<span style="color:#00ccff;"> Privatize the number.</span><br />
<span style="color:#00ccff;"> Loop.</span><br />
<span style="color:#00ccff;"> If the number is greater than the other number, exit.</span><br />
<span style="color:#00ccff;"> Create an entry for the number.</span><br />
<span style="color:#00ccff;"> Append the entry to the list.</span><br />
<span style="color:#00ccff;"> Add 1 to the number.</span><br />
<span style="color:#00ccff;"> Repeat.</span></p>
<p><span style="color:#00ccff;">To create an entry for a number:</span><br />
<span style="color:#00ccff;"> Allocate memory for the entry.</span><br />
<span style="color:#00ccff;"> Put the number into the entry&#8217;s number.</span><br />
<span style="color:#00ccff;"> Clear the entry&#8217;s non-prime flag.</span></p>
<p><span style="color:#00ccff;">To mark higher multiples of an entry:</span><br />
<span style="color:#00ccff;"> Privatize the entry.</span><br />
<span style="color:#00ccff;"> Loop.</span><br />
<span style="color:#00ccff;"> Put the entry&#8217;s next into the entry.</span><br />
<span style="color:#00ccff;"> If the entry is nil, exit.</span><br />
<span style="color:#00ccff;"> If the entry&#8217;s number is evenly divisible by the original entry&#8217;s number,</span><br />
<span style="color:#00ccff;"> set the entry&#8217;s non-prime flag.</span><br />
<span style="color:#00ccff;"> Repeat.</span></p>
<p><span style="color:#00ccff;">To get an entry for the next lowest possible prime:</span><br />
<span style="color:#00ccff;"> Put the entry&#8217;s next into the entry.</span><br />
<span style="color:#00ccff;"> If the entry is nil, exit.</span><br />
<span style="color:#00ccff;"> If the entry&#8217;s non-prime flag is set, repeat.</span></p>
<p>So clarity, good. Size, good (the executable is only 150k). But what about speed? A little over 4 minutes to make the whole list for numbers between 1 and 250,000. Not good. Hmm… What would Captain Kirk do? What if we sacrificed a little size for speed? Why, after all, do we keep calculating primes over and over again when they never change? So I ran the program again, this time with an additional routine like this…</p>
<p><span style="color:#00ccff;">To make a prime string from a list:</span><br />
<span style="color:#00ccff;"> Put &#8220;N&#8221; into the prime string.</span><br />
<span style="color:#00ccff;"> Loop.</span><br />
<span style="color:#00ccff;"> Get an entry from the list.</span><br />
<span style="color:#00ccff;"> If the entry is nil, exit.</span><br />
<span style="color:#00ccff;"> If the entry&#8217;s non-prime flag is set, append &#8220;N&#8221; to the prime string; repeat.</span><br />
<span style="color:#00ccff;"> Append &#8220;Y&#8221; to the prime string.</span><br />
<span style="color:#00ccff;"> Repeat.</span></p>
<p>…to make a string with all the primes marked. Then I saved the string in a text file and pasted it into a library I called “Super fast prime number checker for numbers between 1 and 250,000.” This is what that library looks like:</p>
<p><span style="color:#00ccff;">The prime string is a string equal to &#8220;NYYNYNYNNNYNYN&#8230;&#8221;</span></p>
<p><span style="color:#00ccff;">To decide if a number is prime (fast check):</span><br />
<span style="color:#00ccff;"> If the number is less than 1, say no.</span><br />
<span style="color:#00ccff;"> If the number is greater than the prime string&#8217;s length, say no.</span><br />
<span style="color:#00ccff;"> Put the prime string&#8217;s first into a byte pointer.</span><br />
<span style="color:#00ccff;"> Add the number to the byte pointer.</span><br />
<span style="color:#00ccff;"> Subtract 1 from the byte pointer.</span><br />
<span style="color:#00ccff;"> If the byte pointer&#8217;s target is the big-Y byte, say yes.</span><br />
<span style="color:#00ccff;"> Say no.</span></p>
<p>The prime string in the source is, of course, much longer than the one shown above. And it could be 8 times shorter if we used bits instead of “Y”s to mark the primes. But it hurts my head to have to think that hard. At any rate, this program…</p>
<p><span style="color:#00ccff;">To run:</span><br />
<span style="color:#00ccff;"> Start up.</span><br />
<span style="color:#00ccff;"> Write &#8220;Working&#8230;&#8221; on the console.</span><br />
<span style="color:#00ccff;"> Start a timer.</span><br />
<span style="color:#00ccff;"> Get a count of prime numbers less than or equal to 250000.</span><br />
<span style="color:#00ccff;"> Stop the timer.</span><br />
<span style="color:#00ccff;"> Write the count then &#8221; prime numbers.&#8221; on the console.</span><br />
<span style="color:#00ccff;"> Write the timer&#8217;s string then &#8221; milliseconds.&#8221; on the console.</span><br />
<span style="color:#00ccff;"> Wait for the escape key.</span><br />
<span style="color:#00ccff;"> Shut down.</span></p>
<p><span style="color:#00ccff;">To get a count of prime numbers less than or equal to a number:</span><br />
<span style="color:#00ccff;"> Privatize the number.</span><br />
<span style="color:#00ccff;"> Clear the count.</span><br />
<span style="color:#00ccff;"> Loop.</span><br />
<span style="color:#00ccff;"> If the number is prime (fast check), add 1 to the count.</span><br />
<span style="color:#00ccff;"> Subtract 1 from the number.</span><br />
<span style="color:#00ccff;"> If the number is less than 2, break.</span><br />
<span style="color:#00ccff;"> Repeat.</span></p>
<p>…which is very <em>clear,</em> and reasonably <em>small </em>(about 400k), is also remarkably <em>fast</em>. It can count the 22,044 primes less than or equal to 250,000 in 16 milliseconds or less. And, since it’s (indirectly) based on the Sieve of Eratosthenes, it meets the requirements of the original specification!</p>
<p>I think Captain Kirk would approve.</p>
</div>
]]></html></oembed>