Ruminationshttps://nangia.in/2013-09-15T00:05:00+05:30First Fibonacci Number with not Less than 1000 Digits2013-09-15T00:05:00+05:30Sandeep Nangiatag:nangia.in,2013-09-15:fibonacci-num-with-not-less-than-1000digits.html<h2>Problem</h2> <p>The Fibonacci sequence is defined as follows: </p> <ul> <li>The first Fibonacci number is 1.</li> <li>The second Fibonacci number is 1.</li> <li>After this any Fibonacci number is the sum of the preceding two Fibonacci numbers.</li> </ul> <p>Thus, the first 10 numbers of the Fibonacci sequence are 1, 1, 2, 3, 5, 8, 13, 21, 34, 55. </p> <p>Find the first Fibonacci sequence with not less than 1000 digits.</p> <p>This problem is slightly altered version of <a href="http://projecteuler.net/problem=25">Project Euler Problem 25</a>.</p> <h2>Solution in Clojure</h2> <div class="highlight"><pre><span class="p">(</span><span class="kd">defn </span><span class="nv">fib-next</span> <span class="p">[[</span><span class="nv">fib1</span> <span class="nv">fib2</span> <span class="nv">number</span><span class="p">]]</span> <span class="p">[</span><span class="nv">fib2</span> <span class="p">(</span><span class="nb">+ </span><span class="nv">fib1</span> <span class="nv">fib2</span><span class="p">)</span> <span class="p">(</span><span class="nb">inc </span><span class="nv">number</span><span class="p">)])</span> <span class="p">(</span><span class="k">def </span><span class="nv">fib-seq</span> <span class="p">(</span><span class="nb">iterate </span><span class="nv">fib-next</span> <span class="p">[</span><span class="mi">1</span><span class="nv">N</span> <span class="mi">1</span><span class="nv">N</span> <span class="mi">1</span><span class="nv">N</span><span class="p">]))</span> <span class="p">(</span><span class="kd">defn </span><span class="nv">lengthlessthan?</span> <span class="p">[[</span><span class="nv">fib1</span> <span class="nv">fib2</span> <span class="nv">number</span><span class="p">]]</span> <span class="p">(</span><span class="nb">&lt; </span><span class="p">(</span><span class="nf">.length</span> <span class="p">(</span><span class="nb">str </span><span class="nv">fib1</span><span class="p">))</span> <span class="mi">1000</span><span class="p">))</span> <span class="p">((</span><span class="nf">-&gt;&gt;</span> <span class="nv">fib-seq</span> <span class="p">(</span><span class="nb">drop-while </span><span class="nv">lengthlessthan?</span><span class="p">)</span> <span class="p">(</span><span class="nb">take </span><span class="mi">1</span><span class="p">)</span> <span class="p">(</span><span class="nf">first</span><span class="p">))</span> <span class="mi">2</span><span class="p">)</span> </pre></div> <h2>Description</h2> <p>To solve this, first we define a function <em>fib-next</em> which takes in a vector with three numbers: nth Fibonacci number, (n+1)the Fibonacci number and n. Given this number it calculates a new vector with (n+1) Fibonacci number, (n+2) Fibonacci number and (n+1). Using this function we define an infinite sequence <em>fib-seq</em> to calculate this vector using the initialization vector [1N 1N 1N]. Since, we are likely to be dealing with large numbers, hence with prefix N after 1.</p> <p>We define a function <em>lengthlessthan?</em> which returns true if the number of digits in a number are less than 1000 given a vector of the form generated by <em>fib-seq</em>. All that is being done is to convert the number into a string and then computing its length using <em>java.String.length()</em>.</p> <p>With these definitions out of the way, we just generate this infinite sequence <em>fib-seq</em> and drop all vectors such that the number of digits in Fibonacci number is less than 1000. We take the sequence to include just the first such number with length not less than 1000, separate it out using first and then find the 3rd number in this vector.</p>Deleting Windows 7 directory containing files with too long path names2013-09-02T20:22:00+05:30Sandeep Nangiatag:nangia.in,2013-09-02:deleting-windows-files-with-too-long-path-len.html<h2>Problem</h2> <p>The laptop that my employer has provided me has a program installed for upkeep of the laptop. So it keeps auto-updating appropriate patches, newly requested software etc. to my laptop. However, I have noticed a problem with this program. This software downloads stuff from company servers and then creates directories in c:\ with lot of contents on the hard disk and then forgets to delete them. Over a period of time, this consumes lot of disk space (I have counted hundreds of MBs once). I moved all such directories files to one directory c:\junk and then tried to delete this directory. But, I could not delete this directory as I got this error: "Destination Path Too Long". Looked into the directories and found that they had <strong>really long</strong> files names. I googled around and it seems that the <a href="http://support.microsoft.com/kb/320081">official solution from Microsoft</a> is to rename the files to smaller names. It's strange that Microsoft allows one to create such long named files but not easily delete them. Anyway, since they were consuming so much disk space, I decided to write this python (2.7) utility to rename files inside this directory to shorter names. Then I manually delete the directory c:\junk. </p> <h2>Solution</h2> <div class="highlight"><pre><span class="kn">from</span> <span class="nn">collections</span> <span class="kn">import</span> <span class="n">deque</span> <span class="kn">import</span> <span class="nn">os</span> <span class="kn">import</span> <span class="nn">os.path</span> <span class="n">directoryToBeDeleted</span> <span class="o">=</span> <span class="s">&quot;c:</span><span class="se">\\</span><span class="s">junk&quot;</span> <span class="n">fqueue</span> <span class="o">=</span> <span class="n">deque</span><span class="p">([</span> <span class="n">directoryToBeDeleted</span> <span class="p">])</span> <span class="k">while</span> <span class="n">fqueue</span><span class="o">.</span><span class="n">__len__</span><span class="p">()</span> <span class="o">!=</span> <span class="mi">0</span><span class="p">:</span> <span class="n">count</span> <span class="o">=</span> <span class="mi">0</span> <span class="n">afile</span> <span class="o">=</span> <span class="n">fqueue</span><span class="o">.</span><span class="n">popleft</span><span class="p">()</span> <span class="k">for</span> <span class="n">f</span> <span class="ow">in</span> <span class="n">os</span><span class="o">.</span><span class="n">listdir</span><span class="p">(</span><span class="n">afile</span><span class="p">):</span> <span class="n">source</span> <span class="o">=</span> <span class="n">afile</span> <span class="o">+</span> <span class="s">&quot;</span><span class="se">\\</span><span class="s">&quot;</span> <span class="o">+</span> <span class="n">f</span> <span class="n">target</span> <span class="o">=</span> <span class="n">afile</span> <span class="o">+</span> <span class="s">&quot;</span><span class="se">\\</span><span class="s">&quot;</span> <span class="o">+</span> <span class="nb">hex</span><span class="p">(</span><span class="n">count</span><span class="p">)[</span><span class="mi">2</span><span class="p">:]</span> <span class="k">print</span> <span class="s">&quot;Renaming </span><span class="si">%s</span><span class="s"> to </span><span class="si">%s</span><span class="s">&quot;</span> <span class="o">%</span> <span class="p">(</span><span class="n">source</span><span class="p">,</span> <span class="n">target</span><span class="p">)</span> <span class="n">os</span><span class="o">.</span><span class="n">rename</span><span class="p">(</span><span class="n">source</span><span class="p">,</span> <span class="n">target</span><span class="p">)</span> <span class="n">count</span> <span class="o">+=</span> <span class="mi">1</span> <span class="k">if</span> <span class="ow">not</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">isfile</span><span class="p">(</span><span class="n">target</span><span class="p">):</span> <span class="n">fqueue</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">target</span><span class="p">)</span> <span class="c"># Now manually delete the contents of the junk directory</span> </pre></div> <h2>Description</h2> <p>All this program does is a basic <a href="http://en.wikipedia.org/wiki/Breadth-first_search">Breadth First Search</a>. <em>fqueue</em> in this program is a double ended queue. Initially, at the start of the loop, the queue has just the original directory that we want to delete. In every <em>while</em> iteration, the program takes off one file or directory name from the left of the queue and then renames all the files and directories within this directory starting 0. To keep the numbers short, I used a hexadecimal numbering scheme. If sub-directories are found in this directory, they are added to the right of the double ended queue for the next <em>while</em> iteration.</p> <p>While I found this program adequate for my needs, one could potentially rename the files using a <a href="http://stackoverflow.com/questions/1181919/python-base-36-encoding">base 36 numbering scheme</a> to make for even shorter filenames. That might be helpful in case there are large number of files in the directories.</p> <p>I left the last step of deleting the directory as manual - because, I did not want to make a mistake. This is a dangerous script. And that's the reason, I chose not to send in the directory to be deleted via command line arguments. It then becomes too easy to make a mistake. Beware!</p> <p>I later heard of a program called robocopy which apparently can do this deletion easily. But, I don't have an easy way to install a new program on my employer provided laptop (has to be blessed by our IT department). So I guess, for me this is the way to go!</p>