<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	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/"
		>
<channel>
	<title>Comments on: Recursion as a performance boost!</title>
	<atom:link href="http://www.dailydoseofexcel.com/archives/2009/01/02/recursion-as-a-performance-boost/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.dailydoseofexcel.com/archives/2009/01/02/recursion-as-a-performance-boost/</link>
	<description>Daily posts of Excel tips…and other stuff</description>
	<lastBuildDate>Wed, 08 Feb 2012 23:58:05 +0000</lastBuildDate>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.2.1</generator>
	<item>
		<title>By: Michael</title>
		<link>http://www.dailydoseofexcel.com/archives/2009/01/02/recursion-as-a-performance-boost/#comment-40195</link>
		<dc:creator>Michael</dc:creator>
		<pubDate>Fri, 10 Jul 2009 03:11:00 +0000</pubDate>
		<guid isPermaLink="false">http://www.dailydoseofexcel.com/?p=1933#comment-40195</guid>
		<description>&lt;p&gt;Hi Tim -&lt;/p&gt;
&lt;p&gt;And welcome to the Euler conversations.&lt;/p&gt;
&lt;p&gt;Josh has helped you with your specifics.  I&#039;ll point out that there is a bug in posting code inside VB tags.  Inside those tags, angle bracket pairs are treated as HTML tags, and everything between a starting &quot;less than&quot; and a following &quot;greater than&quot; is treated as unknown HTML and thrown away.&lt;/p&gt;
&lt;p&gt;If you look at your code as it appears above, I&#039;ll bet some money that the line&lt;/p&gt;
&lt;p&gt;If ChainLength(n)  0 Then&lt;/p&gt;
&lt;p&gt;really has a &quot;not equals&quot; angle bracket pair inside that got thrown away.  Not a big deal here, but sometimes this bug can span lines of code.  Does make it shorter ;-)&lt;/p&gt;
&lt;p&gt;Something to watch for.  You can see Doug complaining about it up top.&lt;/p&gt;
&lt;p&gt;...mrt&lt;/p&gt;
</description>
		<content:encoded><![CDATA[<p>Hi Tim -</p>
<p>And welcome to the Euler conversations.</p>
<p>Josh has helped you with your specifics.  I&#8217;ll point out that there is a bug in posting code inside VB tags.  Inside those tags, angle bracket pairs are treated as HTML tags, and everything between a starting &#8220;less than&#8221; and a following &#8220;greater than&#8221; is treated as unknown HTML and thrown away.</p>
<p>If you look at your code as it appears above, I&#8217;ll bet some money that the line</p>
<p>If ChainLength(n)  0 Then</p>
<p>really has a &#8220;not equals&#8221; angle bracket pair inside that got thrown away.  Not a big deal here, but sometimes this bug can span lines of code.  Does make it shorter <img src='http://www.dailydoseofexcel.com/wp-includes/images/smilies/icon_wink.gif' alt=';-)' class='wp-smiley' /> </p>
<p>Something to watch for.  You can see Doug complaining about it up top.</p>
<p>&#8230;mrt</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: JoshG</title>
		<link>http://www.dailydoseofexcel.com/archives/2009/01/02/recursion-as-a-performance-boost/#comment-40189</link>
		<dc:creator>JoshG</dc:creator>
		<pubDate>Thu, 09 Jul 2009 16:42:00 +0000</pubDate>
		<guid isPermaLink="false">http://www.dailydoseofexcel.com/?p=1933#comment-40189</guid>
		<description>&lt;p&gt;The problem is that the Mod function likes Longs, and n exceeds the limit of the Long data type.  I have a couple of sugestions for you involving the &quot;If n mod 2 = 0 Then&quot; statement.  First off, you don&#039;t need the ElseIf part there; n mod 2 can only be 1 or 0 so a simple Else will suffice.  That way you don&#039;t have to waste time taking the Mod twice.  &lt;/p&gt;
&lt;p&gt;For your overflow problem, you can go back to the definition of the Mod function.&lt;br&gt;
Mod(n,d) = n - d * INT(n/d)&lt;br&gt;
Thus your statement would look like: If n - 2 * Int(n / 2) = 0 Then&lt;br&gt;
This works for this particular problem and solves the problem in 1.4 seconds on my machine.  &lt;/p&gt;
&lt;p&gt;A Double will get you 15 digits of precision, but will also be vulnerable to floating point rounding errors.  A common theme with PE is to require more than 15 digits of precision.  A number of people here like the Currency data type.  I prefer the Decimal data type (27 digits of precision and no floating point errors), though it is exceedingly slow.  By comparison simply using the above formula with Decimal data took about 6.5 seconds.&lt;/p&gt;
&lt;p&gt;Nicely done solution, and I hope this helps.&lt;/p&gt;
&lt;p&gt;-Josh&lt;/p&gt;
</description>
		<content:encoded><![CDATA[<p>The problem is that the Mod function likes Longs, and n exceeds the limit of the Long data type.  I have a couple of sugestions for you involving the &#8220;If n mod 2 = 0 Then&#8221; statement.  First off, you don&#8217;t need the ElseIf part there; n mod 2 can only be 1 or 0 so a simple Else will suffice.  That way you don&#8217;t have to waste time taking the Mod twice.  </p>
<p>For your overflow problem, you can go back to the definition of the Mod function.<br />
Mod(n,d) = n &#8211; d * INT(n/d)<br />
Thus your statement would look like: If n &#8211; 2 * Int(n / 2) = 0 Then<br />
This works for this particular problem and solves the problem in 1.4 seconds on my machine.  </p>
<p>A Double will get you 15 digits of precision, but will also be vulnerable to floating point rounding errors.  A common theme with PE is to require more than 15 digits of precision.  A number of people here like the Currency data type.  I prefer the Decimal data type (27 digits of precision and no floating point errors), though it is exceedingly slow.  By comparison simply using the above formula with Decimal data took about 6.5 seconds.</p>
<p>Nicely done solution, and I hope this helps.</p>
<p>-Josh</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Tim Martin</title>
		<link>http://www.dailydoseofexcel.com/archives/2009/01/02/recursion-as-a-performance-boost/#comment-40183</link>
		<dc:creator>Tim Martin</dc:creator>
		<pubDate>Thu, 09 Jul 2009 05:39:00 +0000</pubDate>
		<guid isPermaLink="false">http://www.dailydoseofexcel.com/?p=1933#comment-40183</guid>
		<description>&lt;p&gt;I tried a recursive approach that stores known solutions to lesser seed values in an array and as expected it works orders of magnitude faster that the brute force method.  &lt;/p&gt;
&lt;p&gt;My problem is I am new to VBA and I am stuck with what will likely be an easy solution in the end.  I have a problem with my code when the the Collatz chain sequence creates an overflow error for n (seed number 113383 is the first occurance)&lt;/p&gt;
&lt;p&gt;As suggestions?&lt;/p&gt;
&lt;p&gt;My code is:&lt;/p&gt;
&lt;div style=&quot;overflow: auto; white-space: nowrap;&quot; class=&quot;codecolorer-container vb default&quot;&gt;&lt;div style=&quot;white-space: nowrap;&quot; class=&quot;vb codecolorer&quot;&gt;&lt;span class=&quot;kw1&quot;&gt;Sub&lt;/span&gt; Euler_Problem_14()&lt;br&gt;
&lt;br&gt;
&lt;span class=&quot;co1&quot;&gt;&#039; The following iterative sequence is defined for the set of positive integers:&lt;br&gt;
&lt;/span&gt;&lt;span class=&quot;co1&quot;&gt;&#039;&lt;br&gt;
&lt;/span&gt;&lt;span class=&quot;co1&quot;&gt;&#039; n -&gt; n/2 (n is even)&lt;br&gt;
&lt;/span&gt;&lt;span class=&quot;co1&quot;&gt;&#039; n -&gt; 3n + 1 (n is odd)&lt;br&gt;
&lt;/span&gt;&lt;span class=&quot;co1&quot;&gt;&#039;&lt;br&gt;
&lt;/span&gt;&lt;span class=&quot;co1&quot;&gt;&#039; Using the rule above and starting with 13, we generate the following sequence:&lt;br&gt;
&lt;/span&gt;&lt;span class=&quot;co1&quot;&gt;&#039;&lt;br&gt;
&lt;/span&gt;&lt;span class=&quot;co1&quot;&gt;&#039; 13 -&gt; 40 -&gt; 20 -&gt; 10 -&gt; 5 -&gt; 16 -&gt; 8 -&gt; 4 -&gt; 2 -&gt; 1&lt;br&gt;
&lt;/span&gt;&lt;span class=&quot;co1&quot;&gt;&#039;&lt;br&gt;
&lt;/span&gt;&lt;span class=&quot;co1&quot;&gt;&#039; it can be seen that this sequence (starting at 13 and finishing at 1) contains&lt;br&gt;
&lt;/span&gt;&lt;span class=&quot;co1&quot;&gt;&#039; 10 terms. Although it has not been proved yet (Collatz Problem), it is thought&lt;br&gt;
&lt;/span&gt;&lt;span class=&quot;co1&quot;&gt;&#039; that all starting numbers finish at 1.&lt;br&gt;
&lt;/span&gt;&lt;span class=&quot;co1&quot;&gt;&#039;&lt;br&gt;
&lt;/span&gt;&lt;span class=&quot;co1&quot;&gt;&#039; Which starting number, under one million, produces the longest chain?&lt;br&gt;
&lt;/span&gt;&lt;span class=&quot;co1&quot;&gt;&#039;&lt;br&gt;
&lt;/span&gt;&lt;span class=&quot;co1&quot;&gt;&#039; NOTE: Once the chain starts the terms are allowed to go above one million.&lt;br&gt;
&lt;/span&gt; &#160; &#160;&lt;br&gt;
&#160; &#160; &lt;span class=&quot;kw1&quot;&gt;On&lt;/span&gt; &lt;span class=&quot;kw1&quot;&gt;Error&lt;/span&gt; &lt;span class=&quot;kw1&quot;&gt;GoTo&lt;/span&gt; 0&lt;br&gt;
&#160; &#160; &lt;span class=&quot;kw1&quot;&gt;Dim&lt;/span&gt; T &#160; &#160; &#160; &lt;span class=&quot;kw1&quot;&gt;As&lt;/span&gt; &lt;span class=&quot;kw1&quot;&gt;Single&lt;/span&gt;&lt;br&gt;
&#160; &#160; &lt;span class=&quot;kw1&quot;&gt;Dim&lt;/span&gt; answer_seed &lt;span class=&quot;kw1&quot;&gt;As&lt;/span&gt; &lt;span class=&quot;kw1&quot;&gt;Double&lt;/span&gt;&lt;br&gt;
&#160; &#160; &lt;span class=&quot;kw1&quot;&gt;Dim&lt;/span&gt; answer_max_step &lt;span class=&quot;kw1&quot;&gt;As&lt;/span&gt; &lt;span class=&quot;kw1&quot;&gt;Double&lt;/span&gt;&lt;br&gt;
&#160; &#160; &lt;span class=&quot;kw1&quot;&gt;Dim&lt;/span&gt; &lt;span class=&quot;kw1&quot;&gt;step&lt;/span&gt; &lt;span class=&quot;kw1&quot;&gt;As&lt;/span&gt; &lt;span class=&quot;kw1&quot;&gt;Double&lt;/span&gt;&lt;br&gt;
&#160; &#160; &lt;span class=&quot;kw1&quot;&gt;Dim&lt;/span&gt; seed_n &lt;span class=&quot;kw1&quot;&gt;As&lt;/span&gt; &lt;span class=&quot;kw1&quot;&gt;Double&lt;/span&gt;&lt;br&gt;
&#160; &#160; &lt;span class=&quot;kw1&quot;&gt;Dim&lt;/span&gt; UpperBound &lt;span class=&quot;kw1&quot;&gt;As&lt;/span&gt; &lt;span class=&quot;kw1&quot;&gt;Double&lt;/span&gt;&lt;br&gt;
&#160; &#160; &lt;span class=&quot;kw1&quot;&gt;Dim&lt;/span&gt; n &lt;span class=&quot;kw1&quot;&gt;As&lt;/span&gt; &lt;span class=&quot;kw1&quot;&gt;Double&lt;/span&gt;&lt;br&gt;
&#160; &#160; &lt;span class=&quot;kw1&quot;&gt;Dim&lt;/span&gt; ChainLength() &lt;span class=&quot;kw1&quot;&gt;As&lt;/span&gt; &lt;span class=&quot;kw1&quot;&gt;Double&lt;/span&gt;&lt;br&gt;
&#160; &#160; &lt;br&gt;
&#160; &#160; UpperBound = 100000&lt;br&gt;
&#160; &#160; &lt;br&gt;
&#160; &#160; &lt;span class=&quot;kw1&quot;&gt;ReDim&lt;/span&gt; ChainLength(1 &lt;span class=&quot;kw1&quot;&gt;To&lt;/span&gt; UpperBound)&lt;br&gt;
&#160; &#160; seed_n = 2&lt;br&gt;
&#160; &#160; &lt;span class=&quot;kw1&quot;&gt;step&lt;/span&gt; = 1&lt;br&gt;
&#160; &#160; T = Timer&lt;br&gt;
&#160; &#160;&lt;br&gt;
&#160; &#160; &lt;span class=&quot;kw1&quot;&gt;Do&lt;/span&gt;&lt;br&gt;
&#160; &#160; &#160; &#160; n = seed_n&lt;br&gt;
&#160; &#160; &#160; &#160; &lt;span class=&quot;kw1&quot;&gt;Do&lt;/span&gt; &lt;span class=&quot;kw1&quot;&gt;While&lt;/span&gt; n &#160;1&lt;br&gt;
&#160; &#160; &#160; &#160; &#160; &#160; &lt;span class=&quot;kw1&quot;&gt;If&lt;/span&gt; n &lt;= UpperBound &lt;span class=&quot;kw1&quot;&gt;Then&lt;/span&gt;&lt;br&gt;
&#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &lt;span class=&quot;kw1&quot;&gt;If&lt;/span&gt; ChainLength(n) &#160;0 &lt;span class=&quot;kw1&quot;&gt;Then&lt;/span&gt;&lt;br&gt;
&#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; ChainLength(seed_n) = ChainLength(n) + &lt;span class=&quot;kw1&quot;&gt;step&lt;/span&gt;&lt;br&gt;
&#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &lt;span class=&quot;kw1&quot;&gt;If&lt;/span&gt; ChainLength(seed_n) &gt; answer_max_step &lt;span class=&quot;kw1&quot;&gt;Then&lt;/span&gt;&lt;br&gt;
&#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; answer_max_step = ChainLength(seed_n)&lt;br&gt;
&#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; answer_seed = seed_n&lt;br&gt;
&#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &lt;span class=&quot;kw1&quot;&gt;End&lt;/span&gt; &lt;span class=&quot;kw1&quot;&gt;If&lt;/span&gt;&lt;br&gt;
&#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &lt;span class=&quot;kw1&quot;&gt;Exit&lt;/span&gt; &lt;span class=&quot;kw1&quot;&gt;Do&lt;/span&gt;&lt;br&gt;
&#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &lt;span class=&quot;kw1&quot;&gt;End&lt;/span&gt; &lt;span class=&quot;kw1&quot;&gt;If&lt;/span&gt;&lt;br&gt;
&#160; &#160; &#160; &#160; &#160; &#160; &lt;span class=&quot;kw1&quot;&gt;End&lt;/span&gt; &lt;span class=&quot;kw1&quot;&gt;If&lt;/span&gt;&lt;br&gt;
&#160; &#160; &#160; &#160; &#160; &#160; &lt;span class=&quot;kw1&quot;&gt;If&lt;/span&gt; n &lt;span class=&quot;kw1&quot;&gt;Mod&lt;/span&gt; 2 = 0 &lt;span class=&quot;kw1&quot;&gt;Then&lt;/span&gt;&lt;br&gt;
&#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; n = n / 2&lt;br&gt;
&#160; &#160; &#160; &#160; &#160; &#160; &lt;span class=&quot;kw1&quot;&gt;ElseIf&lt;/span&gt; n &lt;span class=&quot;kw1&quot;&gt;Mod&lt;/span&gt; 2 &#160;0 &lt;span class=&quot;kw1&quot;&gt;Then&lt;/span&gt;&lt;br&gt;
&#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; n = 3 * n + 1&lt;br&gt;
&#160; &#160; &#160; &#160; &#160; &#160; &lt;span class=&quot;kw1&quot;&gt;End&lt;/span&gt; &lt;span class=&quot;kw1&quot;&gt;If&lt;/span&gt;&lt;br&gt;
&#160; &#160; &#160; &#160; &#160; &#160; &lt;span class=&quot;kw1&quot;&gt;step&lt;/span&gt; = &lt;span class=&quot;kw1&quot;&gt;step&lt;/span&gt; + 1&lt;br&gt;
&#160; &#160; &#160; &#160; &lt;span class=&quot;kw1&quot;&gt;Loop&lt;/span&gt;&lt;br&gt;
&#160; &#160; &#160; &#160; &lt;span class=&quot;kw1&quot;&gt;If&lt;/span&gt; n = 1 &lt;span class=&quot;kw1&quot;&gt;Then&lt;/span&gt;&lt;br&gt;
&#160; &#160; &#160; &#160; &#160; &#160; ChainLength(seed_n) = &lt;span class=&quot;kw1&quot;&gt;step&lt;/span&gt;&lt;br&gt;
&#160; &#160; &#160; &#160; &#160; &#160; &lt;span class=&quot;kw1&quot;&gt;If&lt;/span&gt; ChainLength(seed_n) &gt; answer_max_step &lt;span class=&quot;kw1&quot;&gt;Then&lt;/span&gt;&lt;br&gt;
&#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; answer_max_step = ChainLength(seed_n)&lt;br&gt;
&#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; answer_seed = seed_n&lt;br&gt;
&#160; &#160; &#160; &#160; &#160; &#160; &lt;span class=&quot;kw1&quot;&gt;End&lt;/span&gt; &lt;span class=&quot;kw1&quot;&gt;If&lt;/span&gt;&lt;br&gt;
&#160; &#160; &#160; &#160; &lt;span class=&quot;kw1&quot;&gt;End&lt;/span&gt; &lt;span class=&quot;kw1&quot;&gt;If&lt;/span&gt;&lt;br&gt;
&#160; &#160; &#160; &#160; seed_n = seed_n + 1&lt;br&gt;
&#160; &#160; &#160; &#160; &lt;span class=&quot;kw1&quot;&gt;step&lt;/span&gt; = 0&lt;br&gt;
&#160; &#160; &lt;span class=&quot;kw1&quot;&gt;Loop&lt;/span&gt; &lt;span class=&quot;kw1&quot;&gt;Until&lt;/span&gt; seed_n = UpperBound&lt;br&gt;
&#160; &#160;&lt;br&gt;
&#160; &#160; Debug.&lt;span class=&quot;kw1&quot;&gt;Print&lt;/span&gt; &lt;span class=&quot;st0&quot;&gt;&quot;Seed: &quot;&lt;/span&gt;; answer_seed&lt;br&gt;
&#160; &#160; Debug.&lt;span class=&quot;kw1&quot;&gt;Print&lt;/span&gt; &lt;span class=&quot;st0&quot;&gt;&quot;Steps:&quot;&lt;/span&gt;; answer_max_step&lt;br&gt;
&#160; &#160; Debug.&lt;span class=&quot;kw1&quot;&gt;Print&lt;/span&gt; &lt;span class=&quot;st0&quot;&gt;&quot;Time: &quot;&lt;/span&gt;; Timer - T&lt;br&gt;
&lt;br&gt;
&lt;span class=&quot;kw1&quot;&gt;End&lt;/span&gt; &lt;span class=&quot;kw1&quot;&gt;Sub&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;
</description>
		<content:encoded><![CDATA[<p>I tried a recursive approach that stores known solutions to lesser seed values in an array and as expected it works orders of magnitude faster that the brute force method.  </p>
<p>My problem is I am new to VBA and I am stuck with what will likely be an easy solution in the end.  I have a problem with my code when the the Collatz chain sequence creates an overflow error for n (seed number 113383 is the first occurance)</p>
<p>As suggestions?</p>
<p>My code is:</p>
<div style="overflow: auto; white-space: nowrap;" class="codecolorer-container vb default">
<div style="white-space: nowrap;" class="vb codecolorer"><span class="kw1">Sub</span> Euler_Problem_14()</p>
<p><span class="co1">&#8216; The following iterative sequence is defined for the set of positive integers:<br />
</span><span class="co1">&#8216;<br />
</span><span class="co1">&#8216; n -&amp;gt; n/2 (n is even)<br />
</span><span class="co1">&#8216; n -&amp;gt; 3n + 1 (n is odd)<br />
</span><span class="co1">&#8216;<br />
</span><span class="co1">&#8216; Using the rule above and starting with 13, we generate the following sequence:<br />
</span><span class="co1">&#8216;<br />
</span><span class="co1">&#8216; 13 -&amp;gt; 40 -&amp;gt; 20 -&amp;gt; 10 -&amp;gt; 5 -&amp;gt; 16 -&amp;gt; 8 -&amp;gt; 4 -&amp;gt; 2 -&amp;gt; 1<br />
</span><span class="co1">&#8216;<br />
</span><span class="co1">&#8216; it can be seen that this sequence (starting at 13 and finishing at 1) contains<br />
</span><span class="co1">&#8216; 10 terms. Although it has not been proved yet (Collatz Problem), it is thought<br />
</span><span class="co1">&#8216; that all starting numbers finish at 1.<br />
</span><span class="co1">&#8216;<br />
</span><span class="co1">&#8216; Which starting number, under one million, produces the longest chain?<br />
</span><span class="co1">&#8216;<br />
</span><span class="co1">&#8216; NOTE: Once the chain starts the terms are allowed to go above one million.<br />
</span> &nbsp; &nbsp;<br />
&nbsp; &nbsp; <span class="kw1">On</span> <span class="kw1">Error</span> <span class="kw1">GoTo</span> 0<br />
&nbsp; &nbsp; <span class="kw1">Dim</span> T &nbsp; &nbsp; &nbsp; <span class="kw1">As</span> <span class="kw1">Single</span><br />
&nbsp; &nbsp; <span class="kw1">Dim</span> answer_seed <span class="kw1">As</span> <span class="kw1">Double</span><br />
&nbsp; &nbsp; <span class="kw1">Dim</span> answer_max_step <span class="kw1">As</span> <span class="kw1">Double</span><br />
&nbsp; &nbsp; <span class="kw1">Dim</span> <span class="kw1">step</span> <span class="kw1">As</span> <span class="kw1">Double</span><br />
&nbsp; &nbsp; <span class="kw1">Dim</span> seed_n <span class="kw1">As</span> <span class="kw1">Double</span><br />
&nbsp; &nbsp; <span class="kw1">Dim</span> UpperBound <span class="kw1">As</span> <span class="kw1">Double</span><br />
&nbsp; &nbsp; <span class="kw1">Dim</span> n <span class="kw1">As</span> <span class="kw1">Double</span><br />
&nbsp; &nbsp; <span class="kw1">Dim</span> ChainLength() <span class="kw1">As</span> <span class="kw1">Double</span><br />
&nbsp; &nbsp; <br />
&nbsp; &nbsp; UpperBound = 100000<br />
&nbsp; &nbsp; <br />
&nbsp; &nbsp; <span class="kw1">ReDim</span> ChainLength(1 <span class="kw1">To</span> UpperBound)<br />
&nbsp; &nbsp; seed_n = 2<br />
&nbsp; &nbsp; <span class="kw1">step</span> = 1<br />
&nbsp; &nbsp; T = Timer<br />
&nbsp; &nbsp;<br />
&nbsp; &nbsp; <span class="kw1">Do</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; n = seed_n<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">Do</span> <span class="kw1">While</span> n &nbsp;1<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">If</span> n &amp;lt;= UpperBound <span class="kw1">Then</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">If</span> ChainLength(n) &nbsp;0 <span class="kw1">Then</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ChainLength(seed_n) = ChainLength(n) + <span class="kw1">step</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">If</span> ChainLength(seed_n) &amp;gt; answer_max_step <span class="kw1">Then</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; answer_max_step = ChainLength(seed_n)<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; answer_seed = seed_n<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">End</span> <span class="kw1">If</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">Exit</span> <span class="kw1">Do</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">End</span> <span class="kw1">If</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">End</span> <span class="kw1">If</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">If</span> n <span class="kw1">Mod</span> 2 = 0 <span class="kw1">Then</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; n = n / 2<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">ElseIf</span> n <span class="kw1">Mod</span> 2 &nbsp;0 <span class="kw1">Then</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; n = 3 * n + 1<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">End</span> <span class="kw1">If</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">step</span> = <span class="kw1">step</span> + 1<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">Loop</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">If</span> n = 1 <span class="kw1">Then</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ChainLength(seed_n) = <span class="kw1">step</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">If</span> ChainLength(seed_n) &amp;gt; answer_max_step <span class="kw1">Then</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; answer_max_step = ChainLength(seed_n)<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; answer_seed = seed_n<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">End</span> <span class="kw1">If</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">End</span> <span class="kw1">If</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; seed_n = seed_n + 1<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">step</span> = 0<br />
&nbsp; &nbsp; <span class="kw1">Loop</span> <span class="kw1">Until</span> seed_n = UpperBound<br />
&nbsp; &nbsp;<br />
&nbsp; &nbsp; Debug.<span class="kw1">Print</span> <span class="st0">&#8220;Seed: &#8220;</span>; answer_seed<br />
&nbsp; &nbsp; Debug.<span class="kw1">Print</span> <span class="st0">&#8220;Steps:&#8221;</span>; answer_max_step<br />
&nbsp; &nbsp; Debug.<span class="kw1">Print</span> <span class="st0">&#8220;Time: &#8220;</span>; Timer &#8211; T</p>
<p><span class="kw1">End</span> <span class="kw1">Sub</span></div>
</div>
]]></content:encoded>
	</item>
	<item>
		<title>By: Jonah Feld</title>
		<link>http://www.dailydoseofexcel.com/archives/2009/01/02/recursion-as-a-performance-boost/#comment-36874</link>
		<dc:creator>Jonah Feld</dc:creator>
		<pubDate>Tue, 06 Jan 2009 04:32:00 +0000</pubDate>
		<guid isPermaLink="false">http://www.dailydoseofexcel.com/?p=1933#comment-36874</guid>
		<description>&lt;p&gt;After playing around with this, my plan doesn&#039;t work. Even with the correct decision path in hand, backing up from 1, I can only get the first eighteen numbers correct with simple decision criteria. My criteria for choosing R2 was: n mod 2 = 0 and R2(n) mod 3 = 2.&lt;/p&gt;
&lt;p&gt;Even if there&#039;s a reliable way to choose when to use R2 instead of R1, there&#039;s not a great way of knowing at what point n will never drop back below 1,000,000.&lt;/p&gt;
</description>
		<content:encoded><![CDATA[<p>After playing around with this, my plan doesn&#8217;t work. Even with the correct decision path in hand, backing up from 1, I can only get the first eighteen numbers correct with simple decision criteria. My criteria for choosing R2 was: n mod 2 = 0 and R2(n) mod 3 = 2.</p>
<p>Even if there&#8217;s a reliable way to choose when to use R2 instead of R1, there&#8217;s not a great way of knowing at what point n will never drop back below 1,000,000.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Jonah Feld</title>
		<link>http://www.dailydoseofexcel.com/archives/2009/01/02/recursion-as-a-performance-boost/#comment-36871</link>
		<dc:creator>Jonah Feld</dc:creator>
		<pubDate>Tue, 06 Jan 2009 01:27:00 +0000</pubDate>
		<guid isPermaLink="false">http://www.dailydoseofexcel.com/?p=1933#comment-36871</guid>
		<description>&lt;p&gt;I think the move to make is to solve the problem in reverse. The recursive solution still does tons of calculations to come up with the answer.&lt;/p&gt;
&lt;p&gt;This is a big hint:&lt;br&gt;
Although it has not been proved yet (Collatz Problem), it is thought that all starting numbers finish at 1.&lt;/p&gt;
&lt;p&gt;So, start at 1 and work backwards trying to find the longest chain. &lt;/p&gt;
&lt;p&gt;The functions:&lt;br&gt;
F1: n ? n/2 (n is even)&lt;br&gt;
F2: n ? 3n + 1 (n is odd)&lt;/p&gt;
&lt;p&gt;The functions in reverse are:&lt;br&gt;
R1: n ? n*2&lt;br&gt;
R2: n ? (n-1) / 3&lt;/p&gt;
&lt;p&gt;The trick is to know when to choose R2 instead of R1. You don&#039;t have to make this choice very often. I&#039;ll work on this and post again later.&lt;/p&gt;
</description>
		<content:encoded><![CDATA[<p>I think the move to make is to solve the problem in reverse. The recursive solution still does tons of calculations to come up with the answer.</p>
<p>This is a big hint:<br />
Although it has not been proved yet (Collatz Problem), it is thought that all starting numbers finish at 1.</p>
<p>So, start at 1 and work backwards trying to find the longest chain. </p>
<p>The functions:<br />
F1: n ? n/2 (n is even)<br />
F2: n ? 3n + 1 (n is odd)</p>
<p>The functions in reverse are:<br />
R1: n ? n*2<br />
R2: n ? (n-1) / 3</p>
<p>The trick is to know when to choose R2 instead of R1. You don&#8217;t have to make this choice very often. I&#8217;ll work on this and post again later.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: fzz</title>
		<link>http://www.dailydoseofexcel.com/archives/2009/01/02/recursion-as-a-performance-boost/#comment-36818</link>
		<dc:creator>fzz</dc:creator>
		<pubDate>Sun, 04 Jan 2009 05:55:00 +0000</pubDate>
		<guid isPermaLink="false">http://www.dailydoseofexcel.com/?p=1933#comment-36818</guid>
		<description>&lt;p&gt;Recursion isn&#039;t the same thing as accumulating previous results.&lt;/p&gt;
&lt;p&gt;Tushar Mehta&#039;s lookup approach is slow due to the function calls to CheckOneNbr as well as error trapping accesses to the SeqCount collection. While it takes a reference in the VBA Project, WSH Dictionary objects fly compared to plain vanilla VBA collection objects.&lt;/p&gt;
&lt;p&gt;My results agree with Doug Jenkins&#039;s: brute force takes about 11 seconds.&lt;/p&gt;
&lt;p&gt;The point about cheating by interating from 999999 to 2 is foolish. Unless one has a mathematical proof that the answer would be towards the high end of the range, one must try all values in the range either largest to smallest or smallest to largest.&lt;/p&gt;
&lt;p&gt;Finally, Right(Rslt, 1) Mod 2 to avoid overflow is losing tactic when the goal is performance. For that matter,&lt;/p&gt;
&lt;p&gt;If Rslt / 2 - Int(Rslt / 2) = 0 Then Rslt = Rslt / 2 _&lt;br&gt;
Else: Rslt = 3 * Rslt + 1&lt;/p&gt;
&lt;p&gt;(why the : after Else?) performs the Rslt / 2 test more often than needed. Better something like&lt;/p&gt;
&lt;p&gt;Rslt = Rslt / 2#&lt;br&gt;
If Int(Rslt)  Rslt Then Rslt = 6# * Rslt + 1#&lt;/p&gt;
&lt;p&gt;1 divide rather than 2 in every loop, no additional divide when Rslt starts off even, and the same number of multiply and add operations when Rslt starts off odd.&lt;/p&gt;
</description>
		<content:encoded><![CDATA[<p>Recursion isn&#8217;t the same thing as accumulating previous results.</p>
<p>Tushar Mehta&#8217;s lookup approach is slow due to the function calls to CheckOneNbr as well as error trapping accesses to the SeqCount collection. While it takes a reference in the VBA Project, WSH Dictionary objects fly compared to plain vanilla VBA collection objects.</p>
<p>My results agree with Doug Jenkins&#8217;s: brute force takes about 11 seconds.</p>
<p>The point about cheating by interating from 999999 to 2 is foolish. Unless one has a mathematical proof that the answer would be towards the high end of the range, one must try all values in the range either largest to smallest or smallest to largest.</p>
<p>Finally, Right(Rslt, 1) Mod 2 to avoid overflow is losing tactic when the goal is performance. For that matter,</p>
<p>If Rslt / 2 &#8211; Int(Rslt / 2) = 0 Then Rslt = Rslt / 2 _<br />
Else: Rslt = 3 * Rslt + 1</p>
<p>(why the : after Else?) performs the Rslt / 2 test more often than needed. Better something like</p>
<p>Rslt = Rslt / 2#<br />
If Int(Rslt)  Rslt Then Rslt = 6# * Rslt + 1#</p>
<p>1 divide rather than 2 in every loop, no additional divide when Rslt starts off even, and the same number of multiply and add operations when Rslt starts off odd.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Doug Jenkins</title>
		<link>http://www.dailydoseofexcel.com/archives/2009/01/02/recursion-as-a-performance-boost/#comment-36816</link>
		<dc:creator>Doug Jenkins</dc:creator>
		<pubDate>Sun, 04 Jan 2009 01:47:00 +0000</pubDate>
		<guid isPermaLink="false">http://www.dailydoseofexcel.com/?p=1933#comment-36816</guid>
		<description>&lt;p&gt;The dreaded greater/less than strikes again.&lt;/p&gt;
&lt;p&gt;The rest of the code is as shown at Tushar&#039;s link.&lt;/p&gt;
&lt;p&gt;I also meant to comment that making similar changes to the recursive routine does not seem to help significantly.  I&#039;m not sure why not.&lt;/p&gt;
</description>
		<content:encoded><![CDATA[<p>The dreaded greater/less than strikes again.</p>
<p>The rest of the code is as shown at Tushar&#8217;s link.</p>
<p>I also meant to comment that making similar changes to the recursive routine does not seem to help significantly.  I&#8217;m not sure why not.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Doug Jenkins</title>
		<link>http://www.dailydoseofexcel.com/archives/2009/01/02/recursion-as-a-performance-boost/#comment-36815</link>
		<dc:creator>Doug Jenkins</dc:creator>
		<pubDate>Sun, 04 Jan 2009 01:27:00 +0000</pubDate>
		<guid isPermaLink="false">http://www.dailydoseofexcel.com/?p=1933#comment-36815</guid>
		<description>&lt;p&gt;Was the link to problem 14 supposed to be recursive? :)&lt;/p&gt;
&lt;p&gt;I used a simple brute force solution that solved in about 11 seconds on my computer, compared with about 70 seconds for your recursive solution, and about twice as long for the non-recursive routine.  One reason was that I only checked odd starting numbers, but checking every number only doubles the time to about 22 seconds.&lt;/p&gt;
&lt;p&gt;I modified your non-recursive code as shown below, which reduced the solution time to about 7 seconds!  It seems that the CDec() or mod functions were taking a lot of time.  I still haven&#039;t worked out why your code is so much faster than mine (which was essentially the same).&lt;/p&gt;
&lt;p&gt;&lt;code lang=&quot;vb&quot;&gt;&lt;br&gt;
Sub Euler014s()&lt;br&gt;
    Dim I As Long&lt;br&gt;
    Dim ProcTime As Single, MaxRslt As Integer, MaxStartNbr As Long&lt;br&gt;
    ProcTime = Timer&lt;br&gt;
    MaxRslt = 1: MaxStartNbr = 1&lt;br&gt;
    For I = 3 To 1000000 - 1 Step 2&lt;br&gt;
        Dim Rslt As Double, ThisSeqLen As Long&lt;br&gt;
        &#039; Rslt = CDec(I): ThisSeqLen = 1&lt;br&gt;
        Rslt = I: ThisSeqLen = 1&lt;br&gt;
        Do While Rslt  1&lt;br&gt;
            &#039;If Right(Rslt, 1) Mod 2 = 0 Then Rslt = Rslt / 2 _&lt;/code&gt;&lt;/p&gt;
&lt;code lang=&quot;vb&quot;&gt;
&lt;p&gt;            If Rslt / 2 - Int(Rslt / 2) = 0 Then Rslt = Rslt / 2 _&lt;br&gt;
            Else: Rslt = 3 * Rslt + 1&lt;br&gt;
            ThisSeqLen = ThisSeqLen + 1&lt;br&gt;
            Loop&lt;br&gt;
        If MaxRslt&lt;/p&gt;&lt;/code&gt;
&lt;p&gt;&lt;/p&gt;
</description>
		<content:encoded><![CDATA[<p>Was the link to problem 14 supposed to be recursive? <img src='http://www.dailydoseofexcel.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>I used a simple brute force solution that solved in about 11 seconds on my computer, compared with about 70 seconds for your recursive solution, and about twice as long for the non-recursive routine.  One reason was that I only checked odd starting numbers, but checking every number only doubles the time to about 22 seconds.</p>
<p>I modified your non-recursive code as shown below, which reduced the solution time to about 7 seconds!  It seems that the CDec() or mod functions were taking a lot of time.  I still haven&#8217;t worked out why your code is so much faster than mine (which was essentially the same).</p>
<p><div class="codecolorer-container vb default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="vb codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">&lt;br&gt;<br />
<span style="color: #E56717; font-weight: bold;">Sub</span> Euler014s()&lt;br&gt;<br />
&nbsp; &nbsp; <span style="color: #151B8D; font-weight: bold;">Dim</span> I <span style="color: #151B8D; font-weight: bold;">As</span> Long&lt;br&gt;<br />
&nbsp; &nbsp; <span style="color: #151B8D; font-weight: bold;">Dim</span> ProcTime <span style="color: #151B8D; font-weight: bold;">As</span> <span style="color: #F660AB; font-weight: bold;">Single</span>, MaxRslt <span style="color: #151B8D; font-weight: bold;">As</span> <span style="color: #F660AB; font-weight: bold;">Integer</span>, MaxStartNbr <span style="color: #151B8D; font-weight: bold;">As</span> Long&lt;br&gt;<br />
&nbsp; &nbsp; ProcTime = Timer&lt;br&gt;<br />
&nbsp; &nbsp; MaxRslt = 1: MaxStartNbr = 1&lt;br&gt;<br />
&nbsp; &nbsp; <span style="color: #8D38C9; font-weight: bold;">For</span> I = 3 <span style="color: #8D38C9; font-weight: bold;">To</span> 1000000 - 1 <span style="color: #8D38C9; font-weight: bold;">Step</span> 2&lt;br&gt;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #151B8D; font-weight: bold;">Dim</span> Rslt <span style="color: #151B8D; font-weight: bold;">As</span> <span style="color: #F660AB; font-weight: bold;">Double</span>, ThisSeqLen <span style="color: #151B8D; font-weight: bold;">As</span> Long&lt;br&gt;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #008000;">' Rslt = CDec(I): ThisSeqLen = 1&lt;br&gt;<br />
</span> &nbsp; &nbsp; &nbsp; &nbsp;Rslt = I: ThisSeqLen = 1&lt;br&gt;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #8D38C9; font-weight: bold;">Do</span> <span style="color: #8D38C9; font-weight: bold;">While</span> Rslt &nbsp;1&lt;br&gt;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; '<span style="color: #8D38C9; font-weight: bold;">If</span> Right(Rslt, 1) <span style="color: #151B8D; font-weight: bold;">Mod</span> 2 = 0 <span style="color: #8D38C9; font-weight: bold;">Then</span> Rslt = Rslt / 2 _</div></div>
</p>
<div class="codecolorer-container vb default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="vb codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">&lt;p&gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #8D38C9; font-weight: bold;">If</span> Rslt / 2 - Int(Rslt / 2) = 0 <span style="color: #8D38C9; font-weight: bold;">Then</span> Rslt = Rslt / 2 _&lt;br&gt;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #8D38C9; font-weight: bold;">Else</span>: Rslt = 3 * Rslt + 1&lt;br&gt;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ThisSeqLen = ThisSeqLen + 1&lt;br&gt;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Loop&lt;br&gt;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #8D38C9; font-weight: bold;">If</span> MaxRslt&lt;/p&gt;</div></div></p>
]]></content:encoded>
	</item>
</channel>
</rss>

