<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	xmlns:georss="http://www.georss.org/georss" xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#" xmlns:media="http://search.yahoo.com/mrss/"
	>

<channel>
	<title>Musemantic</title>
	<atom:link href="http://alexstangl.wordpress.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://alexstangl.wordpress.com</link>
	<description>Musings on technology and more</description>
	<lastBuildDate>Wed, 05 May 2010 03:18:08 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.com/</generator>
<cloud domain='alexstangl.wordpress.com' port='80' path='/?rsscloud=notify' registerProcedure='' protocol='http-post' />
<image>
		<url>http://s2.wp.com/i/buttonw-com.png</url>
		<title>Musemantic</title>
		<link>http://alexstangl.wordpress.com</link>
	</image>
	<atom:link rel="search" type="application/opensearchdescription+xml" href="http://alexstangl.wordpress.com/osd.xml" title="Musemantic" />
	<atom:link rel='hub' href='http://alexstangl.wordpress.com/?pushpress=hub'/>
		<item>
		<title>Finding minimum qualified subset in Haskell</title>
		<link>http://alexstangl.wordpress.com/2010/04/27/finding-minimum-qualified-subset-in-haskell/</link>
		<comments>http://alexstangl.wordpress.com/2010/04/27/finding-minimum-qualified-subset-in-haskell/#comments</comments>
		<pubDate>Tue, 27 Apr 2010 23:12:39 +0000</pubDate>
		<dc:creator>alexstangl</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[Haskell]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[subset]]></category>

		<guid isPermaLink="false">http://alexstangl.wordpress.com/?p=67</guid>
		<description><![CDATA[I recently stumbled upon an interesting blog post about efficiently selecting a minimal subset of a potentially large set. It references a paper that discusses different ways of enumerating subsets. The crux is to select k items out of n. One classic approach is lexicographical order, enumerating all n-bit integers from 0..2n-1. Each integer maps [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=alexstangl.wordpress.com&amp;blog=8530621&amp;post=67&amp;subd=alexstangl&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>I recently stumbled upon an <a href="http://www.thelowlyprogrammer.com/2010/04/indexing-and-enumerating-subsets-of.html">interesting blog post</a> about efficiently selecting a minimal subset of a potentially large set. It references a <a href="http://applied-math.org/subset.pdf">paper</a> that discusses different ways of enumerating subsets. The crux is to select k items out of n. One classic approach is lexicographical order, enumerating all n-bit integers from 0..2<sup>n</sup>-1. Each integer maps to a subset made by including from the n items those whose corresponding bit in the integer is 1. Another variant uses Gray code. The paper focuses on a different approach, called the Banker&#8217;s Sequence, a straightforward algorithm to generate all subsets, working from smallest up to largest.</p>
<p>The blog post discusses the challenge of creating a function banker(n, k, i) that returns an n-bit binary vector representing the i<sup>th</sup> subset of length k. The binary vector will have k 1 bits and n-k 0 bits. The author of the blog post provides a Java implementation capable of quickly generating vectors for specified positions.</p>
<p>I thought it would be interesting to experiment with this in Haskell. Here is what I came up with:</p>
<pre>import Data.Foldable (foldl')

-- factorial of n
fact n = foldl' (*) 1 [1..n]

-- # of combinations of n things, taken k at a time (AKA binomial coefficient)
comb :: Integer -&gt; Integer -&gt; Integer
comb n k = (foldl' (*) 1 [(n-k+1)..n]) `div` fact k

-- return boolean vector for ith subset of size k from total n items
banker :: Int -&gt; Int -&gt; Integer -&gt; [Int]
banker n k i = take n $ bankerR n k i [] ++ repeat 0
bankerR n k i acc = let k' = k - 1
                        (prefix, rangeLow, n') = bankpart n k' i
                        acc' = acc ++ prefix
                        i' = i - rangeLow
                    in if k' == 0
                         then acc'
                         else bankerR n' k' i' acc'

bankpart :: Int -&gt; Int -&gt; Integer -&gt; ([Int], Integer, Int)
bankpart n k i = let !rangeHi = comb (fromIntegral (n-1)) (fromIntegral k)
                 in bankR1 n (n-k) 0 rangeHi [1]
  where
    bankR1 n nminusk rangeLow rangeHi acc =
      let n' = n - 1
          nminusk' = nminusk - 1
          rangeHi' = (rangeHi * (fromIntegral nminusk)) `div` (fromIntegral n)
          rangeLow' = rangeLow + rangeHi
          acc' = 0:acc
      in if i &lt; rangeLow'
        then (acc, rangeLow, n')
        else bankR1 n' nminusk' rangeLow' rangeHi' acc'</pre>
<p>This is a fairly straightforward implementation of the algorithm suggested on the blog post. I started to think of ways to cleanup/improve the code. Some ideas include returning a Bool vector rather than 1s and 0s, consider collapsing the double recursion into a single recursive loop, and consider adding bang patterns to force strict evaluation for possible speed improvement. I actually had bang patterns in initially (a habit I got in while solving Project Euler problems in Haskell), but took them out and didn&#8217;t notice much performance difference, although I wasn&#8217;t measuring.</p>
<p>Then I looked over the PDF paper again and realized the whole point to this exercise is to efficiently iterate over the subsets, finding the minimal subset that satisfies a certain criterion. I realized that implementing banker(n, k, i)  (and presumably needing to wrap that in a couple loops, including one that varies k from 0..n) is not thinking about this in a good lazy functional programming way. Far better to directly provide a lazy list of all subsets, from smallest to largest, then filter this with a predicate, and then the head of the resulting list is the minimal subset we are looking for.</p>
<p>So here&#8217;s what I came with for this:</p>
<pre>
import Data.Maybe (listToMaybe)

-- return smallest sublist of l satisfying filter predicate
minFilterSubset :: ([a] -&gt; Bool) -&gt; [a] -&gt; Int -&gt; Maybe [a]
minFilterSubset p l minLen = listToMaybe $ filterSubsets p l minLen

-- return sub-lists of l, in increasing order of size, that satisfy predicate
filterSubsets :: ([a] -&gt; Bool) -&gt; [a] -&gt; Int -&gt; [[a]]
filterSubsets p l minLen = filter p $ subsets l minLen

-- return sub-lists of l, in increasing order of size
subsets :: [a] -&gt; Int -&gt; [[a]]
subsets l minLen = let maxlen = length l
                       subsetsR len = if len &gt; maxlen
                                        then []
                                        else subsetsRR l len ++ subsetsR (len+1)
                   in subsetsR minLen
subsetsRR _ 0 = [[]]
subsetsRR [] _ = []
subsetsRR (l:ls) curlen = (map (l:) $ subsetsRR ls (curlen-1))
                              ++ subsetsRR ls curlen
</pre>
<p>No need for factorials or really any numerical manipulation. This seems to operate reasonably quickly. I initially wrote it without the minLen argument since in principle it is not necessary: the predicate can test the length. But for large values of n, if you have a good idea of non-zero lower bound on subset size, it can save a lot of time, and it seems fairly natural to include minLen as an argument.</p>
<p>This does not allow you to immediately jump immediately to the 160,000,000,000,000,000,000,000,000,000th subset of 12 items chosen out of 10,000. But do we really want that? Supposedly we&#8217;re looking for the minimal subset, so we&#8217;ll be iterating over these subsets, from smallest to largest, looking for the first one that satisfies some criteria. The Haskell implementation implements this directly, cleanly, and elegantly. If I get a chance, I will try to set up some test scenarios, that incorporate the actual iteration over subsets and quantify the performance of the Haskell code with the Java code.</p>
<p>Is any of this new or novel? I doubt it. The PDF paper and blog refers to the Banker&#8217;s sequence as though it is a best-kept secret, however the recursive algorithm seems so obvious, and reminiscent of permutation generators, that I would not be surprised to find this already implemented in some library, although maybe not referring to it as Banker&#8217;s sequence. If you know of this implemented in some Haskell library, please let me know.</p>
<p></p>
<p>
<h4>Addendum 5/4/2010</h4>
</p>
<p>I noticed back in the original blog entry and comments that Calvin Miracle actually wants the <i>maximal</i> subset satisfying the criteria, not the minimal. So I thought about how to accommodate that without a lot of repeated code. This seems to do the trick, and allows you to specify a minimum or maximum size to start with, depending upon which direction you are coming from. Still seems like duplicated code, could probably be factored out to use min, max, and delta, however it&#8217;s not clear that would be better. What do you think?</p>
<pre>
import Data.Maybe (listToMaybe)

-- return smallest sublist of l satisfying filter predicate
minFilterSubset :: ([a] -&gt; Bool) -&gt; [a] -&gt; Int -&gt; Maybe [a]
minFilterSubset p l minLen = listToMaybe $ filter p $ subsetsSmallToLarge l minLen

-- return largest sublist of l satisfying filter predicate
maxFilterSubset :: ([a] -&gt; Bool) -&gt; [a] -&gt; Int -&gt; Maybe [a]
maxFilterSubset p l maxLen = listToMaybe $ filter p $ subsetsLargeToSmall l maxLen

-- return sub-lists of l, in increasing order of size
subsetsSmallToLarge :: [a] -&gt; Int -&gt; [[a]]
subsetsSmallToLarge l minLen = concatMap (subsetsR l) [minLen..length l]

-- return sub-lists of l, in decreasing order of size, from maxLen to 0
subsetsLargeToSmall :: [a] -&gt; Int -&gt; [[a]]
subsetsLargeToSmall l maxLen = concatMap (subsetsR l) [maxLen, maxLen-1..0]

subsetsR _ 0 = [[]]
subsetsR [] _ = []
subsetsR (l:ls) curlen = (map (l:) $ subsetsR ls (curlen-1)) ++ subsetsR ls curlen
</pre>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/alexstangl.wordpress.com/67/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/alexstangl.wordpress.com/67/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/alexstangl.wordpress.com/67/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/alexstangl.wordpress.com/67/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/alexstangl.wordpress.com/67/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/alexstangl.wordpress.com/67/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/alexstangl.wordpress.com/67/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/alexstangl.wordpress.com/67/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/alexstangl.wordpress.com/67/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/alexstangl.wordpress.com/67/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/alexstangl.wordpress.com/67/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/alexstangl.wordpress.com/67/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/alexstangl.wordpress.com/67/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/alexstangl.wordpress.com/67/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=alexstangl.wordpress.com&amp;blog=8530621&amp;post=67&amp;subd=alexstangl&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://alexstangl.wordpress.com/2010/04/27/finding-minimum-qualified-subset-in-haskell/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/56924cdfc551b65852fe6e7ad9f78f41?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">alexstangl</media:title>
		</media:content>
	</item>
		<item>
		<title>SICP Chapter 1 solutions in Haskell</title>
		<link>http://alexstangl.wordpress.com/2010/03/20/sicp-chapter-1-solutions-in-haskell/</link>
		<comments>http://alexstangl.wordpress.com/2010/03/20/sicp-chapter-1-solutions-in-haskell/#comments</comments>
		<pubDate>Sat, 20 Mar 2010 14:53:55 +0000</pubDate>
		<dc:creator>alexstangl</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[Haskell]]></category>
		<category><![CDATA[SICP]]></category>

		<guid isPermaLink="false">http://alexstangl.wordpress.com/?p=61</guid>
		<description><![CDATA[Exercise 1.1 (not translated) 10 12 8 3 6 3 4 19 false 4 16 6 16 Exercise 1.2 Normally in Haskell you would express this using infix notation: (5 + 4 + (2 - (3 - (6 + 4/5)))) / (3 * (6 - 2) * (2 - 7)) but it is possible to [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=alexstangl.wordpress.com&amp;blog=8530621&amp;post=61&amp;subd=alexstangl&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<h3>Exercise 1.1 (not translated)</h3>
<p>10<br />
12<br />
8<br />
3<br />
6<br />
3<br />
4<br />
19<br />
false<br />
4<br />
16<br />
6<br />
16</p>
<h3>Exercise 1.2</h3>
<p>Normally in Haskell you would express this using infix notation:</p>
<pre>
(5 + 4 + (2 - (3 - (6 + 4/5)))) / (3 * (6 - 2) * (2 - 7))
</pre>
<p>but it is possible to express it alternately using prefix notation:</p>
<pre>
(/) ((+) ((+) 5 4) ((-) 2 ((-) 3 ((+) 6 ((/) 4 5))))) ((*) 3 ((*) ((-) 6 2) ((-) 2 7)))
</pre>
<h3>Exercise 1.3</h3>
<pre>
max2 a b c = let list = [a, b, c]
                 sqs = map (^ 2) list
                 minsq = (minimum list) ^ 2
             in sum sqs - minsq
</pre>
<h3>Exercise 1.4</h3>
<p>Evaluates to a plus the absolute value of b</p>
<h3>Exercise 1.5</h3>
<p>Applicative order evaluation would go into an infinite loop, trying to evaluate the (p) argument, which would keep evaluating to (p), never making any progress. Normal order does not need to fully evaluate the operands first, so it is fine with just leaving in (p). Eventually the if predicate evaluates to true, and it returns the consequent, 0, never needing to evaluate the (p), and so avoiding the infinite loop problem. (Instead of infinite loop, applicative order may actually blow up with a stack or memory overflow problem.) We would describe either of these as divergent, or &perp; (&#8220;bottom&#8221;).</p>
<h3>Exercise 1.6</h3>
<p>The square root program written using &#8220;new-if&#8221; would never complete successfully, either entering an infinite loop, or blowing up due to exhausting stack space. This is because when it evaluates the first &#8220;new-if&#8221; it has to evaluate both operands since it is now not a special form. Evaluating the second operand, involves a call one level deeper, again involving a &#8220;new-if&#8221;, with the exact same requirement to evaluate both operands. We have infinite regress, and can never break out until we abort due to running out of some resource like stack space.</p>
<h3>Exercise 1.7</h3>
<p>With relatively large numbers, the arbitrary 0.001 absolute value tolerance cutoff works well, because the guess is much larger than 0.001, so getting the guess correct to within +/- 0.001 produces pretty good results. With very small numbers, however, 0.001 is considered large relative to the numbers, so it breaks down in terms of providing &#8220;pretty good&#8221; results. For example, even a guess of 0 would be considered within tolerance of x = 0.0005, but sqrt(0.0005) == 0 would arguably be a poor answer. A guess of 0.0007 would also be within tolerance of 0.0005, another poor answer.</p>
<p>Computers represent floating point numbers with a limited-precision mantissa and an exponent, similar to &#8220;scientific notation&#8221;, e.g. 2.3 x 10<sup>8</sup>. Very large numbers do not have precision down to the decimal point, much less past it. So it is quite possible to get into a situation where we reach our best guess, but the difference is considered &gt; 0.001, and due to the limited precision the next guess doesn&#8217;t put us any closer to the answer, but perhaps we oscillate between two guess values, never breaking out because it never sees a value that it thinks is within 0.001 tolerance. Alternately, it does return a result, but one that is a lousy answer. For example, the initial good-enough? has sqrt returning about 0.0323 as sqrt of 0.0001 and about 0.03126 as sqrt of 0.000001.</p>
<p>Initial translation of Scheme version to Haskell:</p>
<pre>
avg a b = (a + b) / 2
sqr a = a * a

improve guess x = avg guess (x / guess)
good_enough guess x = abs ((sqr guess) - x) &lt; 0.001

sqrt_iter guess x = if good_enough guess x
                    then guess
                    else let !guess' = improve guess x
                         in sqrt_iter guess' x
sqrt = sqrt_iter 1.0
</pre>
<p>Improved version:</p>
<pre>
avg a b = (a + b) / 2.0
sqr a = a * a

improve guess x = avg guess (x / guess)
good_enough guess prevGuess = abs ((guess - prevGuess) / guess) &lt; 0.001

sqrt x = sqrt_iter 1.0 (-10.0)
  where
    sqrt_iter guess prevGuess = if good_enough guess prevGuess
                                then guess
                                else let !guess' = improve guess x
                                     in sqrt_iter guess' guess
</pre>
<p>This version does indeed work better on very large and small numbers.</p>
<h3>Exercise 1.8</h3>
<pre>
-- Use (x / y^2 + 2y) / 3 for successive approximation of cube root
-- Uses -10 as a dummy distant "prevGuess"
cubert x = cubertR 1.0 (-10.0)
  where cubertR guess prevGuess = if goodEnough guess prevGuess
                                  then guess
                                  else let !guess' = improve guess
                                       in cubertR guess' guess
        goodEnough guess prevGuess = abs (guess - prevGuess) / guess &lt; 0.0001
        improve guess = ((x / guess / guess) + guess + guess) / 3.0
</pre>
<h3>Exercise 1.9 (not translating these trivial examples to Clojure)</h3>
<pre>
(define (+ a b)
  (if (= a 0)
    b
    (inc (+ (dec a) b))))

(+ 4 5)
(inc (+ (dec 4) 5))
(inc (+ 3 5))
(inc (inc (+ (dec 3) 5)))
(inc (inc (+ 2 5)))
(inc (inc (inc (+ (dec 2) 5))))
(inc (inc (inc (+ 1 5))))
(inc (inc (inc (inc (+ (dec 1) 5)))))
(inc (inc (inc (inc (+ 0 5)))))
(inc (inc (inc (inc 5))))
(inc (inc (inc 6)))
(inc (inc 7))
(inc 8)
9

(define (+ a b)
  (if (= a 0)
    b
    (+ (dec a) (inc b))))

(+ 4 5)
(+ (dec 4) (inc 5))
(+ 3 6)
(+ (dec 3) (inc 6))
(+ 2 7)
(+ (dec 2) (inc 7))
(+ 1 8)
(+ (dec 1) (inc 8))
(+ 0 9)
9
</pre>
<p>The first process is linear recursive. The second process is linear iterative.</p>
<h3>Exercise 1.10</h3>
<pre>
-- Compute Ackermann function version from SICP Exercise 1.10
-- Cannot name function A due to language restrictions
a x 0 = 0
a 0 y = 2 * y
a _ 1 = 2
a x y = a (x-1) (a x (y-1))

f = a 0
g = a 1
h = a 2
</pre>
<p>a 1 10 = 1024<br />
a 2 4 = 65536<br />
a 3 3 = 65536</p>
<p>For positive integer values of n,<br />
f n computes 2n<br />
g n computes 2<sup>n</sup><br />
h n computes 2^^n (tetration, 2 exponentiated by itself n times, e.g. 2^^4 =<br />
2<sup>2<sup>2<sup>2</sup></sup></sup></p>
<h3>Exercise 1.11</h3>
<pre>
-- compute f where f(n) = n if n &lt; 3 and f(n-1) + 2f(n-2) + 3f(n-3) if n &gt;= 3
-- as a recursive process and a linear process

frecur n | n &lt; 3 = n
         | otherwise = frecur (n-1) + 2*frecur(n-2) + 3*frecur(n-3)

fiter n | n &lt; 3 = n
        | otherwise = fiterR 3 2 1 0
  where fiterR x a b c = let !fx = a + 2*b + 3*c
                         in if x == n
                            then fx
                            else let !x' = x+1
                                 in fiterR x' fx a b
</pre>
<h3>Exercise 1.12</h3>
<pre>
-- Compute (row, column) element of Pascal's triangle where row &amp; column are
-- both 1-based and assuming both are ranged correctly (i.e., no error detection here)

pascal _ 1 = 1
pascal row col | row == col = 1
               | otherwise = let !prevrow = row-1
                                 !prevcol = col-1
                             in pascal prevrow prevcol + pascal prevrow col
</pre>
<h3>Exercise 1.13</h3>
<p>&Phi; = (1 + &radic;<span style="text-decoration:overline;">5</span>)/2<br />
&Psi; = (1 &#8211; &radic;<span style="text-decoration:overline;">5</span>)/2</p>
<p>Fib(0) = 0<br />
Fib(1) = 1<br />
otherwise Fib(n) = Fib(n-1) + Fib(n-2)<br />
^ all of these, by definition<br />
&Phi;<sup>2</sup> = (1 + &Phi;)<br />
&Psi;<sup>2</sup> = (1 + &Psi;)</p>
<p>Fib&#8217;(n) = (&Phi;^n &#8211; &Psi;^n)/&radic;<span style="text-decoration:overline;">5</span><br />
Fib&#8217;(0) = (&Phi;^0 &#8211; &Psi;^0)/&radic;<span style="text-decoration:overline;">5</span> = (1 &#8211; 1)/&radic;<span style="text-decoration:overline;">5</span> = 0/&radic;<span style="text-decoration:overline;">5</span> = 0<br />
Fib&#8217;(1) = (&Phi;^1 &#8211; &Psi;^1)/&radic;<span style="text-decoration:overline;">5</span> = &radic;<span style="text-decoration:overline;">5</span>/&radic;<span style="text-decoration:overline;">5</span> = 1<br />
So far, Fib&#8217; is same as Fib. In order for this to hold true in general,<br />
Fib&#8217;(n) = Fib&#8217;(n-1) + Fib&#8217;(n-2)<br />
  = (&Phi;<sup>n-1</sup> &#8211; &Psi;<sup>n-1</sup> + &Phi;<sup>n-2</sup> &#8211; &Psi;<sup>n-2</sup>)/&radic;<span style="text-decoration:overline;">5</span><br />
  = ((&Phi; + 1)*&Phi;<sup>n-2</sup> &#8211; (&Psi; + 1)*&Psi;<sup>n-2</sup>)/&radic;<span style="text-decoration:overline;">5</span><br />
  = ((&Phi;<sup>2</sup>)*&Phi;<sup>(n-2)</sup> &#8211; (&Psi;<sup>2</sup>)*&Psi;<sup>(n-2</sup>)/&radic;<span style="text-decoration:overline;">5</span><br />
  = (&Phi;<sup>n</sup> &#8211; &Psi;<sup>n</sup>)/&radic;<span style="text-decoration:overline;">5</span></p>
<p>  therefore Fib(n) = (&Phi;<sup>n</sup> &#8211; &Psi;<sup>n</sup>)/&radic;<span style="text-decoration:overline;">5</span> holds true in the general case.</p>
<p>Since this equation determines Fib(n) exactly, and |&Psi;<sup>n</sup>| &lt; 0.5 for all integer n &gt; 1<br />
then for all n &gt; 1, &Phi;<sup>n</sup>/&radic;<span style="text-decoration:overline;">5</span> differs from Fib(n) by less than 0.5.<br />
Therefore, for all integer n &gt; 1, closest integer to &Phi;<sup>n</sup>/&radic;<span style="text-decoration:overline;">5</span> must be Fib(n).<br />
For n = 0, &Phi;^n/&radic;<span style="text-decoration:overline;">5</span> is approximately .447, and for n = 1, &Phi;<sup>n</sup>/&radic;<span style="text-decoration:overline;">5</span> is<br />
approximately 0.7236, so closest integers are 0 and 1, respectively, therefore for<br />
all integer n &gt;= 0, closest integer to &Phi;<sup>n</sup>/&radic;<span style="text-decoration:overline;">5</span> is equal to Fib(n).</p>
<h3>Exercise 1.14</h3>
<p>see Clojure version for the solution to this</p>
<h3>Exercise 1.15</h3>
<pre>
cube x = x^3
p x = 3*x - 4 * cube x
sine angle | abs angle &lt;= 0.1 = angle
           | otherwise = p $ sine (angle / 3.0)
</pre>
<p>p is executed 5 times when executing (sine 12.15)</p>
<p>angle is divided by 3 each iteration until it reaches 0.1 or below, so the # of iterations is equal to about logarithm base 3 of 10*angle. The code cannot use tail call optimization, so both the order of growth of space and the number of steps is &theta;(log a).</p>
<h3>Exercise 1.16</h3>
<pre>
-- compute b^n in a fast iterative fashion
fast_expt :: (Fractional a, Integral b) =&gt; a -&gt; b -&gt; a
fast_expt b n = fast_exptR 1.0 b n
  where fast_exptR a b 0 = a
        fast_exptR a b n | even n = let !b' = b*b
                                        !n' = n `div` 2
                                    in fast_exptR a b' n'
                         | otherwise = let !a' = a*b
                                           !n' = n-1
                                       in fast_exptR a' b n'
</pre>
<h3>Exercise 1.17</h3>
<pre>
-- compute a*b in a fast fashion

-- double/halve are theoretically our primitives, in addition to +
-- In principle they could for example be a bit shift,
-- but we just use * and / here.
double n = n*2
halve n = n `div` 2

fast_mul a 0 = 0
fast_mul a b | even b = fast_mul (double a) (halve b)
             | otherwise = a + fast_mul a (b-1)
</pre>
<h3>Exercise 1.18</h3>
<pre>
-- compute a*b in a fast fashion

-- double/halve are theoretically our primitives, in addition to +
-- In principle they could for example be a bit shift,
-- but we just use * and / here.
double n = n*2
halve n = n `div` 2

fast_mul a b = fast_mulR 0 a b
fast_mulR s a 0 = s
fast_mulR s a b | even b = let !a' = double a
                               !b' = halve b
                           in fast_mulR s a' b'
                | otherwise = let !s' = s+a
                                  !b' = b-1
                              in fast_mulR s' a b'
</pre>
<h3>Exercise 1.19</h3>
<p>Starting with (a0, b0), and applying Tpq once we get (qb0 + qa0 + pa0, pb0 + qa0),<br />
or a1 = qb0 + qa0 + pa0, b1 = pb0 + qa0. Applying Tpq a second time we get (qb1 + qa1 + pa1, pb1 + qa1), <br />
or a2 = b0(pq + qq + pq) + a0(qq + qq + pq + pq + pp), b2 = b0(pp + qq) + a0(pq + qq + pq)</p>
<p>We want a2 = q&#8217;b0 + q&#8217;a0 + p&#8217;a0, b2 = p&#8217;b0 + q&#8217;a0<br />
therefore if we take p&#8217; = pp + qq, and q&#8217; = 2pq + qq, it works out in one transformation.</p>
<pre>
-- compute nth Fibonacci number efficiently
fib n = fibR 1 0 0 1 n
  where fibR _ b _ _ 0 = b
        fibR a b p q count | even count = let !p' = p*p + q*q
                                              !q' = 2*p*q + q*q
                                              !count' = count `div` 2
                                          in fibR a b p' q' count'
                           | otherwise = let !a' = b*q + a*q + a*p
                                             !b' = b*p + a*q
                                             !count' = count - 1
                                         in fibR a' b' p q count'
</pre>
<h3>Exercise 1.20</h3>
<pre>
(define (gcd a b)
  (if (= b 0)
      a
      (gcd b (remainder a b))))

Evaluating (gcd 206 40) in normal order:
(gcd
  206
  40)
(if (= 40 0)
  206
  (gcd
    40
    (remainder 206 40)))
(gcd
  40
  (remainder 206 40))
(if (= (remainder 206 40) 0)
  40
  (gcd
    (remainder 206 40)
    (remainder 40 (remainder 206 40))))
(if (= 6 0)        ; 1 remainder performed here
  40
  (gcd
    (remainder 206 40)
    (remainder 40 (remainder 206 40))))
(gcd
  (remainder 206 40)
  (remainder 40 (remainder 206 40)))
(if (= (remainder 40 (remainder 206 40)) 0)
  (remainder 206 40)
  (gcd
    (remainder 40 (remainder 206 40))
    (remainder (remainder 206 40) (remainder 40 (remainder 206 40)))))
(if (= (remainder 40 6) 0)    ; 1 remainder performed here
  (remainder 206 40)
  (gcd
    (remainder 40 (remainder 206 40))
    (remainder (remainder 206 40) (remainder 40 (remainder 206 40)))))
(if (= 4 0)                   ; 1 remainder performed here
  (remainder 206 40)
  (gcd
    (remainder 40 (remainder 206 40))
    (remainder (remainder 206 40) (remainder 40 (remainder 206 40)))))
(gcd
  (remainder 40 (remainder 206 40))
  (remainder (remainder 206 40) (remainder 40 (remainder 206 40))))
(if (= (remainder (remainder 206 40) (remainder 40 (remainder 206 40))) 0)
  (remainder 40 (remainder 206 40))
  (gcd
    (remainder (remainder 206 40) (remainder 40 (remainder 206 40)))
    (remainder (remainder 40 (remainder 206 40)) (remainder (remainder 206 40) (remainder 40 (remainder 206 40))))))
(if (= (remainder 6 (remainder 40 6)) 0)    ; 2 remainders performed here
  (remainder 40 (remainder 206 40))
  (gcd
    (remainder (remainder 206 40) (remainder 40 (remainder 206 40)))
    (remainder (remainder 40 (remainder 206 40)) (remainder (remainder 206 40) (remainder 40 (remainder 206 40))))))
(if (= (remainder 6 4) 0)                   ; 1 remainder performed here
  (remainder 40 (remainder 206 40))
  (gcd
    (remainder (remainder 206 40) (remainder 40 (remainder 206 40)))
    (remainder (remainder 40 (remainder 206 40)) (remainder (remainder 206 40) (remainder 40 (remainder 206 40))))))
(if (= 2 0)                                 ; 1 remainder performed here
  (remainder 40 (remainder 206 40))
  (gcd
    (remainder (remainder 206 40) (remainder 40 (remainder 206 40)))
    (remainder (remainder 40 (remainder 206 40)) (remainder (remainder 206 40) (remainder 40 (remainder 206 40))))))
(gcd
  (remainder (remainder 206 40) (remainder 40 (remainder 206 40)))
  (remainder (remainder 40 (remainder 206 40)) (remainder (remainder 206 40) (remainder 40 (remainder 206 40))))))
(if (= (remainder (remainder 40 (remainder 206 40)) (remainder (remainder 206 40) (remainder 40 (remainder 206 40)))) 0)
  (remainder (remainder 206 40) (remainder 40 (remainder 206 40)))
  (gcd
    (remainder (remainder 40 (remainder 206 40)) (remainder (remainder 206 40) (remainder 40 (remainder 206 40))))
    (remainder 
      (remainder (remainder 206 40) (remainder 40 (remainder 206 40)))
      (remainder (remainder 40 (remainder 206 40)) (remainder (remainder 206 40) (remainder 40 (remainder 206 40)))))))
(if (= (remainder (remainder 40 6) (remainder 6 (remainder 40 6))) 0)       ; 3 remainders performed here
  (remainder (remainder 206 40) (remainder 40 (remainder 206 40)))
  (gcd
    (remainder (remainder 40 (remainder 206 40)) (remainder (remainder 206 40) (remainder 40 (remainder 206 40))))
    (remainder 
      (remainder (remainder 206 40) (remainder 40 (remainder 206 40)))
      (remainder (remainder 40 (remainder 206 40)) (remainder (remainder 206 40) (remainder 40 (remainder 206 40)))))))
(if (= (remainder 4 (remainder 6 4)) 0)                                     ; 2 remainders performed here
  (remainder (remainder 206 40) (remainder 40 (remainder 206 40)))
  (gcd
    (remainder (remainder 40 (remainder 206 40)) (remainder (remainder 206 40) (remainder 40 (remainder 206 40))))
    (remainder 
      (remainder (remainder 206 40) (remainder 40 (remainder 206 40)))
      (remainder (remainder 40 (remainder 206 40)) (remainder (remainder 206 40) (remainder 40 (remainder 206 40)))))))
(if (= (remainder 4 2) 0)                                                   ; 1 remainder performed here
  (remainder (remainder 206 40) (remainder 40 (remainder 206 40)))
  (gcd
    (remainder (remainder 40 (remainder 206 40)) (remainder (remainder 206 40) (remainder 40 (remainder 206 40))))
    (remainder 
      (remainder (remainder 206 40) (remainder 40 (remainder 206 40)))
      (remainder (remainder 40 (remainder 206 40)) (remainder (remainder 206 40) (remainder 40 (remainder 206 40)))))))
(if (= 0 0)                                                                 ; 1 remainder performed here
  (remainder (remainder 206 40) (remainder 40 (remainder 206 40)))
  (gcd
    (remainder (remainder 40 (remainder 206 40)) (remainder (remainder 206 40) (remainder 40 (remainder 206 40))))
    (remainder 
      (remainder (remainder 206 40) (remainder 40 (remainder 206 40)))
      (remainder (remainder 40 (remainder 206 40)) (remainder (remainder 206 40) (remainder 40 (remainder 206 40)))))))
(remainder (remainder 206 40) (remainder 40 (remainder 206 40)))
(remainder 6 (remainder 40 6))                                              ; 2 remainders performed here
(remainder 6 4)                                                             ; 1 remainder performed here
2                                                                           ; 1 remainder performed here

Evaluating (gcd 206 40) in applicative order:
(gcd
  206
  40)
(if (= 40 0)
  206
  (gcd 40 (remainder 206 40)))
(gcd 40 (remainder 206 40)))
(gcd 40 6)                                                                  ; 1 remainder performed here
(if (= 6 0)
  40
  (gcd 6 (remainder 40 6)))
(gcd 6 (remainder 40 6))
(gcd 6 4)                                                                   ; 1 remainder performed here
(if (= 4 0)
  6
  (gcd 4 (remainder 6 4)))
(gcd 4 (remainder 6 4))
(gcd 4 2)                                                                   ; 1 remainder performed here
(if (= 2 0)
  4
  (gcd 2 (remainder 4 2)))
(gcd 2 (remainder 4 2))
(gcd 2 0)                                                                   ; 1 remainder performed here
(if (= 0 0)
  2
  (gcd 0 (remainder 2 0)))
2
</pre>
<p>Total of 18 remainders performed in normal order evaluation of (gcd 206 40)<br />
Only 4 remainders performed in applicative order evaluation of (gcd 206 40)</p>
<h3>Exercise 1.21</h3>
<pre>
-- find smallest divisor of n
square n = n*n
divides a b = mod b a == 0

find_divisor n test_divisor | square test_divisor &gt; n = n
                            | divides test_divisor n = test_divisor
                            | otherwise = let !test_divisor' = test_divisor+1
                                          in find_divisor n test_divisor'

smallest_divisor n = find_divisor n 2
</pre>
<p>Smallest divisors of 199, 1999, and 19999 are 199, 1999, and 7, respectively.</p>
<h3>Exercise 1.23 and Exercise 1.24</h3>
<p>I wrote a Haskell program using getClockTime, but it did not seem to show any elapsed time. I speculate that it updates its wall clock time during idle time, and if there is no idle time, it doesn&#8217;t get updated.</p>
<p>I switched to trying to use the GHC profiler, but found it uses a 20 ms. &#8220;tick&#8221;, far too coarse to measure timing of individual calls to prime, or even 3 calls to prime.</p>
<p>Nevertheless, I would expect the algorithms to approximately run twice as fast, with half the number of test steps, with maybe some difference due to constant factors.</p>
<h3>Exercise 1.25</h3>
<p>Alyssa&#8217;s suggestion to simply use fast-expt in conjunction with remainder would work in principle, however it is likely to be considerably slower than our expmod version. The reason for this is that we are using arbitrary precision integer math, hence operations on values with more digits take longer. Our expmod implementation applies remainder at each step, keeping values from growing very large, so the overall operation should take less time than waiting until the end to apply remainder once to a large value.</p>
<h3>Exercise 1.26</h3>
<p>By using explicit multiplication instead of square, each operand of the multiplication has to get evaluated independently. So whereas we only make one recursive call to expmod with the &#8220;square&#8221; implementation, with the multiplication implementation, we would actually make 2. The whole principle of halving the problem space has been nullified, and the &theta;(log n) becomes &theta;(n).</p>
<h3>Exercise 1.27</h3>
<pre>
square n = n*n
expmod _ 0 _ = 1
expmod base exp m | even exp = mod (square (expmod base (exp `div` 2) m)) m
                  | otherwise = mod (base * (expmod base (exp-1) m)) m

test_carmichael n = testCarmichaelR 1
  where testCarmichaelR a | a == n = True
                          | expmod a n n == mod a n = testCarmichaelR (a+1)
                          | otherwise = False
</pre>
<p>This does indeed return true for all the Carmichael numbers mentioned in footnote 47.</p>
<h3>Exercise 1.28</h3>
<pre>
import System.Random

-- squaring step in expmod, we check to see if we have discovered a ``nontrivial square root of 1 modulo n,''
-- that is, a number not equal to 1 or n - 1 whose square is equal to 1 modulo n. It is possible to prove that if
-- such a nontrivial square root of 1 exists, then n is not prime. It is also possible to prove that if n is an odd
square n = n*n
expmod _ 0 _ = 1
expmod base exp m | even exp = let !root = expmod base (exp `div` 2) m
                                   !sqr = mod (square root) m
                               in if root /= 1 &amp;&amp; root /= (m-1) &amp;&amp; sqr == 1
                                     then 0    -- found nontrivial root of 1
                                     else sqr
                  | otherwise = mod (base * (expmod base (exp-1) m)) m

miller_rabin_test :: Int -&gt; IO Bool
miller_rabin_test n = do randint &lt;- getStdRandom (randomR (1,(n-1)))
                         return $ try_it randint
                           where try_it a = expmod a n n == a

fast_prime :: Int -&gt; Int -&gt; IO Bool
fast_prime n 0 = return True
fast_prime n times = do mr_result &lt;- miller_rabin_test n
                        if mr_result
                           then do let !times' = times-1
                                   fast_prime n times'
                           else return False

prime :: Int -&gt; IO Bool
prime n = fast_prime n 4
</pre>
<h3>Exercise 1.29</h3>
<p>Computing integral via repeated samples over interval:</p>
<pre>
sumf term a next b | a &gt; b = 0
                   | otherwise = let !a' = next a
                                 in term a + sumf term a' next b

integral_sample f a b dx = (sumf f (a + dx / 2.0) add_dx b) * dx
  where add_dx x = x+dx
</pre>
<pre>
-- SICP Exercise 1.29, Compute integral of f from a to b using n samples, via Simpson's Rule

-- Compute coefficient for term for evaluation
coefficient :: Integral a =&gt; a -&gt; a -&gt; a
coefficient 0 _ = 1
coefficient n total_n | n == total_n = 1
                      | even n = 2
                      | otherwise = 4

sum_simp :: (Fractional a, Integral b) =&gt; (a -&gt; a) -&gt; a -&gt; a -&gt; b -&gt; a
sum_simp f a h n = sumSimpR 0 0
  where sumSimpR k acc | k &gt; n = acc
                       | otherwise = let !k' = k+1
                                         !acc' = acc + (fromIntegral (coefficient k n)) * (f (a + (fromIntegral k)*h))
                                     in sumSimpR k' acc'

integral :: (Fractional a, Integral b) =&gt; (a -&gt; a) -&gt; a -&gt; a -&gt; b -&gt; a
integral f a b n = let !h = (b-a) / fromIntegral n
                   in (sum_simp f a h n)*h / 3
</pre>
<p>Simpson&#8217;s Rule seems to converge to a solution very quickly for cube in the range 0 to 1.<br />
At n = 2, it returns exactly 0.25. At n = 100 and n = 1000 it returns 0.25000000000000006.<br />
The repeated sampling code doesn&#8217;t converge quite as well. At dx = 0.01 it returns<br />
0.24998750000000042 and at dx = 0.001 it returns 0.249999875000001.</p>
<h3>Exercise 1.30</h3>
<pre>
-- Iterative function to sum terms from a to b
sumf term a next b = sumfR a 0
  where sumfR a result | a &gt; b = result
                       | otherwise = let !a' = next a
                                         !result' = result + term a
                                     in sumfR a' result'
</pre>
<h3>Exercise 1.31</h3>
<pre>
-- Iterative function to multiply terms from a to b
productf :: (Integral a, Fractional b) =&gt; (a -&gt; b) -&gt; a -&gt; (a -&gt; a) -&gt; a -&gt; b
productf term a next b = productR a 1.0
  where productR a result | a &gt; b = result
                          | otherwise = let !a' = next a
                                            !result' = result * term a
                                        in productR a' result'

pi_div_4 :: (Integral a, Fractional b) =&gt; a -&gt; b
pi_div_4 nterms = productf piterm 0 (+1) nterms
  where piterm n | even n = (fromIntegral n + 2.0) / (fromIntegral n + 3.0)
                 | otherwise = (fromIntegral n + 3.0) / (fromIntegral n + 2.0)
</pre>
<p>part b, recursive version of productf:</p>
<pre>
-- Recursive function to multiply terms from a to b
productf term a next b | a &gt; b = 1.0
                       | otherwise = let !a' = next a
                                     in term a * productf term a' next b
</pre>
<h3>Exercise 1.32</h3>
<p>Both sum and product iterate over a range of numbers, applying a certain operation to each number in turn, to generate a term, and then applying a binary merge operation to merge the current term into the accumulated result. For sum, the merge operation is + and for product, the merge operation is *. In each case, the accumulator must be initialized with the appropriate identity element for the operation. For sum, the identity element is 0, and for product, the identity element is 1. SICP calls this identity element the null-value or base value.</p>
<p>Part a, written in an iterative style</p>
<pre>
-- accumulate a collection of terms from a to b using a combiner function
accumulate combiner null_value term a next b = accumulateR null_value a
  where accumulateR acc n | n &gt; b = acc
                          | otherwise = let !acc' = combiner acc (term n)
                                            !n' = next n
                                        in accumulateR acc' n'

sumf term a next b = accumulate (+) 0 term a next b
productf term a next b = accumulate (*) 1 term a next b
</pre>
<p>Part b, written in a recursive style</p>
<pre>
-- accumulate a collection of terms from a to b using a combiner function
accumulate combiner null_value term a next b | a &gt; b = null_value
                                             | otherwise = let !a' = next a
                                                               !thisTerm = term a
                                                           in combiner (accumulate combiner null_value term a' next b) thisTerm

sumf term a next b = accumulate (+) 0 term a next b
productf term a next b = accumulate (*) 1 term a next b
</pre>
<h3>Exercise 1.33</h3>
<pre>
-- accumulate a filtered collection of terms from a to b using a combiner
filtered_accumulate combiner null_value term a next b filterp = filter_accR null_value a
  where filter_accR acc n | n &gt; b = acc
                          | otherwise = let !curTerm = term n
                                            !n' = next n
                                        in if filterp curTerm
                                              then let !acc' = combiner acc curTerm
                                                   in filter_accR acc' n'
                                              else filter_accR acc n'

sum_prime_squares a b = filtered_accumulate combiner 0 id a (+1) b isPrime
  where combiner acc n = acc + n*n

-- compute product of all positive integers less than n that are relatively prime to n
prod_relative_primes n = filtered_accumulate (*) 1 id 1 (+1) (n-1) filterp
  where filterp i = (gcd i n) == 1
        gcd a 0 = a
        gcd a b = gcd b (mod a b)

-- find smallest divisor of n
square n = n*n
divides a b = mod b a == 0

find_divisor n test_divisor | square test_divisor &gt; n = n
                            | divides test_divisor n = test_divisor
                            | otherwise = let !test_divisor' = test_divisor+1
                                          in find_divisor n test_divisor'

smallest_divisor n = find_divisor n 2
isPrime n = smallest_divisor n == n
</pre>
<h3>Exercise 1.34</h3>
<pre>
f g = g 2
</pre>
<p>Trying to evaluate f f fails because of Haskell&#8217;s strong typing. For f, it expects an argument of function that takes in integral argument. Instead we are passing it a function that takes a function argument, and it cannot coerce the value.</p>
<h3>Exercise 1.35</h3>
<p>Fixed point of x -&gt; 1 + 1/x is the value x such that x = 1 + 1/x.<br />
We are given &Phi;<sup>2</sup> = &Phi; + 1 by definition of the golden ratio. Dividing<br />
each side by &Phi; we get &Phi; = 1 + 1/&Phi;, and can immediately see that<br />
&Phi; serves as a fixed point for x -&gt; 1 + 1/x.</p>
<pre>
tolerance = 0.00001
fixed_point f first_guess = try first_guess
  where try guess = let !guess' = f guess
                    in if closeEnough guess guess'
                          then guess'
                          else try guess'
        closeEnough v1 v2 = abs (v1-v2) &lt; tolerance
</pre>
<pre>
*Main&gt; fixed_point (\x -&gt; 1.0 + 1.0/x) 1.0
1.6180327868852458
</pre>
<h3>Exercise 1.36</h3>
<pre>
import Debug.Trace (trace)

tolerance = 0.00001
fixed_point f first_guess = try first_guess
  where try guess = let !guess' = f (trace ("guess = " ++ show guess) guess)
                    in if closeEnough guess guess'
                          then guess'
                          else try guess'
        closeEnough v1 v2 = abs (v1-v2) &lt; tolerance

*Main&gt; fixed_point (\x -&gt; log 1000 / log x) 10
guess = 10.0
guess = 2.9999999999999996
guess = 6.2877098228681545
guess = 3.7570797902002955
guess = 5.218748919675316
guess = 4.1807977460633134
guess = 4.828902657081293
guess = 4.386936895811029
guess = 4.671722808746095
guess = 4.481109436117821
guess = 4.605567315585735
guess = 4.522955348093164
guess = 4.577201597629606
guess = 4.541325786357399
guess = 4.564940905198754
guess = 4.549347961475409
guess = 4.5596228442307565
guess = 4.552843114094703
guess = 4.55731263660315
guess = 4.554364381825887
guess = 4.556308401465587
guess = 4.555026226620339
guess = 4.55587174038325
guess = 4.555314115211184
guess = 4.555681847896976
guess = 4.555439330395129
guess = 4.555599264136406
guess = 4.555493789937456
guess = 4.555563347820309
guess = 4.555517475527901
guess = 4.555547727376273
guess = 4.555527776815261
guess = 4.555540933824255
4.555532257016376
*Main&gt; 
</pre>
<p>Now, with average damping:</p>
<pre>
*Main&gt; fixed_point (\x -&gt; (x + (log 1000 / log x)) / 2) 10
guess = 10.0
guess = 6.5
guess = 5.095215099176933
guess = 4.668760681281611
guess = 4.57585730576714
guess = 4.559030116711325
guess = 4.55613168520593
guess = 4.555637206157649
guess = 4.55555298754564
guess = 4.555538647701617
4.555536206185039
*Main&gt;
</pre>
<p>It only took 11 steps with average damping, versus 34 steps without damping.</p>
<h3>Exercise 1.37</h3>
<p>Recursive version</p>
<pre>
-- Evaluate continued fraction based upon n and d which return terms for
-- the numerator and denominator, and k is number of terms (indexed by 1).
cont_frac n d k = contR 1
  where contR i | i == k = (n i) / (d i)
                | otherwise = (n i) / ((d i) + contR (i+1))
</pre>
<p>It takes k of 10 to approximate golden ratio to 4 decimal digits:</p>
<pre>
*Main&gt; cont_frac (const 1.0) (const 1.0) 10
0.6179775280898876
</pre>
<p>Iterative version:</p>
<pre>
-- Evaluate continued fraction based upon n and d which return terms for
-- the numerator and denominator, and k is number of terms (indexed by 1).
-- this version uses an iterative process
cont_frac n d k = cont_fracR k 0
  where cont_fracR 0 acc = acc
        cont_fracR i acc = let !i' = i-1
                               !acc' = (n i) / ((d i) + acc)
                           in cont_fracR i' acc'
</pre>
<h3>Exercise 1.38</h3>
<pre>
-- compute e via Euler's continued fraction, using k steps
-- all Ni = 1, Di = 1,2,1,1,4,1,1,6,1,1,8,...
compute_e :: (Integral a, Fractional b) =&gt; a -&gt; b
compute_e k = 2.0 + cont_frac (const 1.0) d k
  where d i | i `mod` 3 == 2 = fromIntegral (i + i + 2) / 3.0
            | otherwise = 1.0

-- Evaluate continued fraction based upon n and d which return terms for
-- the numerator and denominator, and k is number of terms (indexed by 1).
-- this version uses an iterative process
cont_frac :: (Integral a, Fractional b) =&gt; (a -&gt; b) -&gt; (a -&gt; b) -&gt; a -&gt; b
cont_frac n d k = cont_fracR k 0.0
  where cont_fracR 0 acc = acc
        cont_fracR i acc = let !i' = i-1
                               !acc' = (n i) / ((d i) + acc)
                           in cont_fracR i' acc'
</pre>
<h3>Exercise 1.39</h3>
<pre>
-- compute tangent function via Lambert's continued fraction
-- N1 = r; all other Ni = -r^2;  Di = 2i-1;  x is angle in radians; k is # steps
tan_cf :: (Integral a, Fractional b) =&gt; b -&gt; a -&gt; b
tan_cf x k = let mxx = -x * x
                 n 1 = x
                 n _ = mxx
             in cont_frac n (\i -&gt; 2.0 * fromIntegral i - 1.0) k

-- Evaluate continued fraction based upon n and d which return terms for
-- the numerator and denominator, and k is number of terms (indexed by 1).
-- this version uses an iterative process
cont_frac :: (Integral a, Fractional b) =&gt; (a -&gt; b) -&gt; (a -&gt; b) -&gt; a -&gt; b
cont_frac n d k = cont_fracR k 0.0
  where cont_fracR 0 acc = acc
        cont_fracR i acc = let !i' = i-1
                               !acc' = (n i) / ((d i) + acc)
                           in cont_fracR i' acc'
</pre>
<h3>Exercise 1.40</h3>
<pre>
-- return function that computes f(x) -&gt; x^3 + ax^2 + bx + c"
cubic a b c x = x^3 + a*x^2 + b*x + c
</pre>
<h3>Exercise 1.41</h3>
<pre>
-- takes 1-arg procedure and returns procedure that applies original twice
double f = f . f
</pre>
<p>((double (double double)) (+ 1)) 5   equals 21</p>
<h3>Exercise 1.42</h3>
<pre>
-- compose f after g: create function that takes x and returns f(g(x))
compose = (.)
</pre>
<h3>Exercise 1.43</h3>
<pre>
-- nth repeated application of f
repeated f n = (\x -&gt; if n == 0
                         then x
                         else (f . (repeated f (n-1))) x)
</pre>
<h3>Exercise 1.44</h3>
<pre>
-- nth repeated application of f
repeated f n = (\x -&gt; if n == 0
                         then x
                         else (f . (repeated f (n-1))) x)

-- create smoothed version that averages f(x) with f(x-dx) and f(x+dx)
dx = 0.0001
smooth f x = (f (x-dx) + f x + f (x+dx)) / 3

-- create the n-fold smoothed function based upon f
smooth_repeated f n = (repeated smooth n) f
</pre>
<h3>Exercise 1.45</h3>
<p>Experimentation when I was working the exercise in Clojure with fixed-point instrumented with debugging println empirically shows that the number of applications of average damping required for the nth root calculation increases by 1 each time n reaches another power of 2. For n = 2, 1 application required, but for n = 32, 5 applications are required. For n = 31, 4 applications required. So a should be equal to the floor of log-base-2 of n.</p>
<p>This leads to the following code in Haskell:</p>
<pre>
-- return a modified version of function that averages its value with its arg
average_damp :: Fractional a =&gt; (a -&gt; a) -&gt; a -&gt; a
average_damp f x = (x + f x) / 2.0

tolerance = 0.00001
fixed_point f first_guess = try first_guess
  where try guess = let !guess' = f guess
                    in if closeEnough guess guess'
                          then guess'
                          else try guess'
        closeEnough v1 v2 = abs (v1-v2) &lt; tolerance

-- nth repeated application of f
repeated :: (Integral b) =&gt; (a -&gt; a) -&gt; b -&gt; (a -&gt; a)
repeated f n = (\x -&gt; if n == 0
                         then x
                         else (f . (repeated f (n-1))) x)

-- return floor of log base 2 of n for positive n
floor_log2 n = floor_log2R 0 2
  where floor_log2R l ll | ll &gt; n = n
                         | otherwise = let !l' = l+1
                                           !ll' = 2*ll
                                       in floor_log2R l' ll'

-- find nth root of x using repeated applications of average damping
nthroot n x = fixed_point ((repeated average_damp (floor_log2 n)) (\y -&gt; x / y^(n-1))) 2.0
</pre>
<h3>Exercise 1.46</h3>
<pre>
tolerance=0.00001

-- perform iterative improvements of guess until it's good enough
iterative_improve goodEnough improve initialGuess = iterR initialGuess (improve initialGuess)
  where iterR prevGuess newGuess | goodEnough newGuess prevGuess = newGuess
                                 | otherwise = let !newGuess' = improve newGuess
                                               in iterR newGuess newGuess'

-- return true when successive guesses are within one hundredth of one percent of each other
goodEnough guess prevGuess = abs ((guess - prevGuess) / guess) &lt; 0.0001

-- calculate square root of x via iterative improvement
sqrt x = (iterative_improve goodEnough improveSqrt) 1.0
  where improveSqrt guess = (guess + x/guess) / 2.0

-- implement fixed-point using iterative improvement
fixed_point f firstGuess = (iterative_improve goodEnough (\x -&gt; f x)) firstGuess
</pre>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/alexstangl.wordpress.com/61/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/alexstangl.wordpress.com/61/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/alexstangl.wordpress.com/61/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/alexstangl.wordpress.com/61/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/alexstangl.wordpress.com/61/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/alexstangl.wordpress.com/61/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/alexstangl.wordpress.com/61/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/alexstangl.wordpress.com/61/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/alexstangl.wordpress.com/61/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/alexstangl.wordpress.com/61/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/alexstangl.wordpress.com/61/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/alexstangl.wordpress.com/61/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/alexstangl.wordpress.com/61/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/alexstangl.wordpress.com/61/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=alexstangl.wordpress.com&amp;blog=8530621&amp;post=61&amp;subd=alexstangl&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://alexstangl.wordpress.com/2010/03/20/sicp-chapter-1-solutions-in-haskell/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/56924cdfc551b65852fe6e7ad9f78f41?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">alexstangl</media:title>
		</media:content>
	</item>
		<item>
		<title>SICP Chapter 1 solutions in Clojure</title>
		<link>http://alexstangl.wordpress.com/2010/03/16/sicp-chap-1-exercises-in-clojure/</link>
		<comments>http://alexstangl.wordpress.com/2010/03/16/sicp-chap-1-exercises-in-clojure/#comments</comments>
		<pubDate>Tue, 16 Mar 2010 04:03:25 +0000</pubDate>
		<dc:creator>alexstangl</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[Clojure]]></category>
		<category><![CDATA[SICP]]></category>

		<guid isPermaLink="false">http://alexstangl.wordpress.com/?p=25</guid>
		<description><![CDATA[Exercise 1.1 10 12 8 3 6 #&#8217;user/a {using def instead of define} #&#8217;user/b 19 false 4 16 {different syntax for Clojure: (cond (= a 4) 6 (= b 4) (+ 6 7 a) true 25)} 6 16 {different syntax, as above: (* (cond (&#62; a b) a (&#60; a b) b true -1) (+ [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=alexstangl.wordpress.com&amp;blog=8530621&amp;post=25&amp;subd=alexstangl&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<h3>Exercise 1.1</h3>
<p>10<br />
12<br />
8<br />
3<br />
6<br />
#&#8217;user/a  {using def instead of define}<br />
#&#8217;user/b<br />
19<br />
false<br />
4<br />
16   {different syntax for Clojure:  (cond (= a 4) 6 (= b 4) (+ 6 7 a) true 25)}<br />
6<br />
16   {different syntax, as above: (* (cond (&gt; a b) a (&lt; a b) b true -1) (+ a 1)) }</p>
<h3>Exercise 1.2</h3>
<p>(assuming fraction is correctly read as 4/5)</p>
<pre>(/ (+ 5 4 (- 2 (- 3 (+ 6 (/ 4 5))))) (* 3 (- 6 2) (- 2 7)))</pre>
<h3>Exercise 1.3</h3>
<pre>(defn sum-squares [a b] (+ (* a a) (* b b)))
(defn sum-max2-squares [a b c]
  (cond (&gt; a b) (if (&gt; b c)
                    (sum-squares a b)
                    (sum-squares a c))
        (&lt; a b) (if (&gt; a c)
                    (sum-squares b a)
                    (sum-squares b c))
        :else   (if (&gt; a c)
                    (sum-squares a b)
                    (sum-squares a c))))</pre>
<h3>Exercise 1.4</h3>
<p>Evaluates to a plus the absolute value of b</p>
<h3>Exercise 1.5</h3>
<p>Applicative order evaluation would go into an infinite loop, trying to evaluate the (p) argument, which would keep evaluating to (p), never making any progress. Normal order does not need to fully evaluate the operands first, so it is fine with just leaving in (p). Eventually the if predicate evaluates to true, and it returns the consequent, 0, never needing to evaluate the (p), and so avoiding the infinite loop problem. (Instead of infinite loop, applicative order may actually blow up with a stack or memory overflow problem.)</p>
<h3>Exercise 1.6</h3>
<p>The square root program written using &#8220;new-if&#8221; would never complete successfully, either entering an infinite loop, or blowing up due to exhausting stack space. This is because when it evaluates the first &#8220;new-if&#8221; it has to evaluate both operands since it is now not a special form. Evaluating the second operand, involves a call one level deeper, again involving a &#8220;new-if&#8221;, with the exact same requirement to evaluate both operands. We have infinite regress, and can never break out until we abort due to running out of some resource like stack space.</p>
<h3>Exercise 1.7</h3>
<p>With relatively large numbers, the arbitrary 0.001 absolute value tolerance cutoff works well, because the guess is much larger than 0.001, so getting the guess correct to within +/- 0.001 produces pretty good results. With very small numbers, however, 0.001 is considered large relative to the numbers, so it breaks down in terms of providing &#8220;pretty good&#8221; results. For example, even a guess of 0 would be considered within tolerance of x = 0.0005, but sqrt(0.0005) == 0 would arguably be a poor answer. A guess of 0.0007 would also be within tolerance of 0.0005, another poor answer.</p>
<p>Computers represent floating point numbers with a limited-precision mantissa and an exponent, similar to &#8220;scientific notation&#8221;, e.g. 2.3 x 10^8. Very large numbers do not have precision down to the decimal point, much less past it. So it is quite possible to get into a situation where we reach our best guess, but the difference is considered &gt; 0.001, and due to the limited precision the next guess doesn&#8217;t put us any closer to the answer, but perhaps we oscillate between two guess values, never breaking out because it never sees a value that it thinks is within 0.001 tolerance. Alternately, it does return a result, but one that is a lousy answer. For example, the initial good-enough? has sqrt returning about 0.0323 as sqrt of 0.0001 and about 0.03126 as sqrt of 0.000001.</p>
<p>Code showing previous linear iterative Clojure version and new version (with suffix 2 on functions.) Ad hoc testing shows that it does indeed work much better for very large and very small numbers.</p>
<pre>(defn average [a b] (/ (+ a b) 2))
(defn square [x] (* x x))
(defn abs [x] (if (&lt; x 0) (- x) x))

(defn improve [guess x]
  (average guess (/ x guess)))

(defn good-enough?
  [guess x]
  (&lt; (abs (- (square guess) x)) 0.001))
(defn good-enough2?
  [guess prevGuess]
  (&lt; (/ (abs (- guess prevGuess)) guess) 0.0001))

(def sqrt-iter
  (fn [guess x]
    (loop [guess guess x x]
      (if (good-enough? guess x)
        guess
        (recur (improve guess x) x)))))

(def sqrt-iter2
  (fn [guess x]
    (loop [guess guess prevGuess -10]
      (if (good-enough2? guess prevGuess)
        guess
        (recur (improve guess x) guess)))))

(defn sqrt [x] (sqrt-iter2 1.0 x))</pre>
<h3>Exercise 1.8</h3>
<pre>; Use (x / y^2 + 2y) / 3 for successive approximation of cube root

(defn abs [x] (if (&lt; x 0) (- x) x))

(defn improve [guess x]
  (/ (+ (/ x guess guess) guess guess) 3.0))

(defn good-enough? [guess prevGuess] (&lt; (/ (abs (- guess prevGuess)) guess) 0.0001))

(def cubert-iter
  (fn [guess x]
    (loop [guess guess prevGuess -10]
      (if (good-enough? guess prevGuess)
        guess
        (recur (improve guess x) guess)))))

(defn cubert [x] (cubert-iter 1.0 x))</pre>
<h3>Exercise 1.9</h3>
<p>(not translating these trivial examples to Clojure)</p>
<pre>(define (+ a b)
  (if (= a 0)
    b
    (inc (+ (dec a) b))))

(+ 4 5)
(inc (+ (dec 4) 5))
(inc (+ 3 5))
(inc (inc (+ (dec 3) 5)))
(inc (inc (+ 2 5)))
(inc (inc (inc (+ (dec 2) 5))))
(inc (inc (inc (+ 1 5))))
(inc (inc (inc (inc (+ (dec 1) 5)))))
(inc (inc (inc (inc (+ 0 5)))))
(inc (inc (inc (inc 5))))
(inc (inc (inc 6)))
(inc (inc 7))
(inc 8)
9

(define (+ a b)
  (if (= a 0)
    b
    (+ (dec a) (inc b))))

(+ 4 5)
(+ (dec 4) (inc 5))
(+ 3 6)
(+ (dec 3) (inc 6))
(+ 2 7)
(+ (dec 2) (inc 7))
(+ 1 8)
(+ (dec 1) (inc 8))
(+ 0 9)
9</pre>
<p>The first process is linear recursive. The second process is linear iterative.</p>
<h3>Exercise 1.10  Ackermann&#8217;s function</h3>
<pre>(defn A [x y]
  (cond (= y 0) 0
        (= x 0) (* 2 y)
        (= y 1) 2
        :else (A (- x 1)
                 (A x (- y 1)))))

(A 1 10) = 1024
(A 2 4) = 65536
(A 3 3) = 65536

(define (f n) (A 0 n))
(define (g n) (A 1 n))
(define (h n) (A 2 n))</pre>
<p>For positive integer values of n,<br />
(f n) computes 2n<br />
(g n) computes 2^n<br />
(h n) computes 2^^n (tetration, 2 exponentiated by itself n times, e.g. 2^^4 = 2^(2^(2^2))</p>
<h3>Exercise 1.11</h3>
<pre>
; compute f where f(n) = n if n = 3
; as a recursive process and a linear process

(defn frecur [n]
  (if (&lt; n 3) n
              (+ (frecur (- n 1)) (* 2 (frecur (- n 2))) (* 3 (frecur (- n 3))))))

; a, b, c track f(x-1), f(x-2), and f(x-3) respectively
(defn fiter [n]
  (if (&lt; n 3) n
              (loop [x 3 a 2 b 1 c 0]
                (let [fx (+ a b b c c c)]
                  (if (= x n) fx
                              (recur (inc x) fx a b))))))
</pre>
<h3>Exercise 1.12</h3>
<pre>; Compute (row, column) element of Pascal's triangle where row &amp; column are
; both 1-based and assuming both are ranged correctly (i.e., no error detection here)

(defn pascal [row col]
  (cond (= col 1) 1
        (= col row) 1
        :else (let [prevrow (dec row)]
                (+ (pascal prevrow (dec col)) (pascal prevrow col)))))</pre>
<h3>Exercise 1.13</h3>
<p>&Phi; = (1 + &radic;<span style="text-decoration:overline;">5</span>)/2<br />
&Psi; = (1 &#8211; &radic;<span style="text-decoration:overline;">5</span>))/2</p>
<p>Fib(0) = 0<br />
Fib(1) = 1<br />
otherwise Fib(n) = Fib(n-1) + Fib(n-2)<br />
^ all of these, by definition<br />
&Phi;<sup>2</sup> = (1 + &Phi;)<br />
&Psi;<sup>2</sup> = (1 + &Psi;)</p>
<p>Fib&#8217;(n) = (&Phi;<sup>n</sup> &#8211; &Psi;<sup>n</sup>)/&radic;<span style="text-decoration:overline;">5</span><br />
Fib&#8217;(0) = (&Phi;<sup>0</sup> &#8211; &Psi;<sup>0</sup>)/&radic;<span style="text-decoration:overline;">5</span> = (1 &#8211; 1)/&radic;<span style="text-decoration:overline;">5</span> = 0/&radic;<span style="text-decoration:overline;">5</span> = 0<br />
Fib&#8217;(1) = (&Phi;<sup>1</sup> &#8211; &Psi;<sup>1</sup>)/&radic;<span style="text-decoration:overline;">5</span> = &radic;<span style="text-decoration:overline;">5</span>/&radic;<span style="text-decoration:overline;">5</span> = 1<br />
So far, Fib&#8217; is same as Fib. In order for this to hold true in general,<br />
Fib&#8217;(n) = Fib&#8217;(n-1) + Fib&#8217;(n-2)<br />
= (&Phi;<sup>(n-1)</sup> &#8211; &Psi;<sup>(n-1)</sup> + &Phi;<sup>(n-2)</sup> &#8211; &Psi;<sup>(n-2)</sup>)/&radic;<span style="text-decoration:overline;">5</span><br />
= ((&Phi; + 1) * &Phi;<sup>(n-2)</sup> &#8211; (&Psi; + 1) * &Psi;<sup>(n-2)</sup>)/&radic;<span style="text-decoration:overline;">5</span><br />
= ((&Phi;<sup>2</sup>) * &Phi;<sup>(n-2)</sup> &#8211; (&Psi;<sup>2</sup>) * &Psi;<sup>(n-2)</sup>)/&radic;<span style="text-decoration:overline;">5</span><br />
= (&Phi;<sup>n</sup> &#8211; &Psi;<sup>n</sup>)/&radic;<span style="text-decoration:overline;">5</span></p>
<p>therefore Fib(n) = (&Phi;<sup>n</sup> &#8211; &Psi;<sup>n</sup>)/&radic;<span style="text-decoration:overline;">5</span> holds true in the general case.</p>
<p>Since this equation determines Fib(n) exactly, and |&Psi;<sup>n</sup>| &lt; 0.5 for all integer n &gt; 1<br />
then for all n &gt; 1, &Phi;<sup>n</sup>/&radic;<span style="text-decoration:overline;">5</span> differs from Fib(n) by less than 0.5. Therefore, for all integer n &gt; 1, closest integer to &Phi;<sup>n</sup>/&radic;<span style="text-decoration:overline;">5</span> must be Fib(n). For n = 0, &Phi;<sup>n</sup>/&radic;<span style="text-decoration:overline;">5</span> is approximately .447, and for n = 1, &Phi;<sup>n</sup>/&radic;<span style="text-decoration:overline;">5</span> is approximately 0.7236, so closest integers are 0 and 1, respectively, therefore for all integer n &gt;= 0, closest integer to &Phi;<sup>n</sup>/&radic;<span style="text-decoration:overline;">5</span> is equal to Fib(n).</p>
<h3>Exercise 1.14</h3>
<pre>(count-change 11)
     |
(cc 11 5) -- (cc -39 5) -- 0
     |
(cc 11 4) -- (cc -14 4) -- 0
     |
(cc 11 3) ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- (cc 1 3) -- (cc -1 3) -- 0
     |                                                                                                                                                                                                                                                                                      |
(cc 11 2) ------------------------------------------------------------------------------------------------------------------------------------------- (cc 6 2) ----------------------------------------------------------------------------- (cc 1 2) -- (cc -4 2) -- 0                 (cc 1 2) -- (cc -4 2) -- 0
     |                                                                                                                                                    |                                                                                      |                                          |
(cc 11 1) -- (cc 10 1) -- (cc 9 1) -- (cc 8 1) -- (cc 7 1) -- (cc 6 1) -- (cc 5 1) -- (cc 4 1) -- (cc 3 1) -- (cc 2 1) -- (cc 1 1) -- (cc 0 1) -- 1   (cc 6 1) -- (cc 5 1) -- (cc 4 1) -- (cc 3 1) -- (cc 2 1) -- (cc 1 1) -- (cc 0 1) -- 1  (cc 1 1) -- (cc 0 1) -- 1                  (cc 1 1) -- (cc 0 1) -- 1
     |           |            |           |           |           |           |           |           |           |           |                           |           |           |           |           |           |                          |                                          |
(cc 11 0)    (cc 10 0)    (cc 9 0)    (cc 8 0)    (cc 7 0)    (cc 6 0)    (cc 5 0)    (cc 4 0)    (cc 3 0)    (cc 2 0)    (cc 1 0)                    (cc 6 0)    (cc 5 0)    (cc 4 0)    (cc 3 0)    (cc 2 0)    (cc 1 0)                   (cc 1 0)                                   (cc 1 0)
     |           |            |           |           |           |           |           |           |           |           |                           |           |           |           |           |           |                          |                                          |
     0           0            0           0           0           0           0           0           0           0           0                           0           0           0           0           0           0                          0                                          0</pre>
<p>I reckon the tree size (# steps) to be theta(n^2) and maximum depth (space) theta(n).</p>
<h3>Exercise 1.15</h3>
<p>p is executed 5 times when executing (sine 12.15)</p>
<p>Angle is divided by 3 each iteration until it reaches 0.1 or below, so the # of iterations is equal to about logarithm base 3 of 10*angle. The code cannot use tail call optimization, so both the order of growth of space and the number of steps is theta(log a).</p>
<h3>Exercise 1.16</h3>
<pre>; compute b^n in a fast iterative fashion
(defn fast-expt [b n]
  (loop [a 1 b b n n]
    (cond (= n 0) a
          (even? n) (recur a (* b b) (/ n 2))
          :else (recur (* a b) b (- n 1)))))</pre>
<h3>Exercise 1.17</h3>
<pre>; compute a*b in a fast fashion
; doubl/halve are theoretically our primitives, in addition to (+)
; In principle they could for example be a bit shift,but we just use * and / here.
; Spelled doubl since double is reserved.
(defn doubl [n] (* n 2))
(defn halve [n] (/ n 2))

(defn fast-mul [a b]
  (cond (= b 0) 0
        (even? b) (fast-mul (doubl a) (halve b))
        :else (+ a (fast-mul a (- b 1)))))</pre>
<h3>Exercise 1.18</h3>
<pre>; compute a*b in a fast iterative fashion
; doubl/halve are theoretically our primitives, in addition to (+)
; In principle they could for example be a bit shift,
; but we just use * and / here. Spelled doubl since double is reserved.
(defn doubl [n] (* n 2))
(defn halve [n] (/ n 2))

(defn fast-mul [a b]
  (loop [s 0 a a b b]
    (cond (= b 0) s
          (even? b) (recur s (doubl a) (halve b))
          :else (recur (+ s a) a (- b 1)))))</pre>
<h3>Exercise 1.19</h3>
<p>Starting with (a0, b0), and applying Tpq once we get (qb0 + qa0 + pa0, pb0 + qa0), or a1 = qb0 + qa0 + pa0, b1 = pb0 + qa0. Applying Tpq a second time we get (qb1 + qa1 + pa1, pb1 + qa1), or a2 = b0(pq + qq + pq) + a0(qq + qq + pq + pq + pp), b2 = b0(pp + qq) + a0(pq + qq + pq)</p>
<p>We want a2 = q&#8217;b0 + q&#8217;a0 + p&#8217;a0, b2 = p&#8217;b0 + q&#8217;a0 therefore if we take p&#8217; = pp + qq, and q&#8217; = 2pq + qq, it works out in one transformation.</p>
<pre>; compute nth Fibonacci number efficiently
(defn fib-iter [a b p q count]
  (loop [a a b b p p q q count count]
    (cond (= count 0) b
          (even? count)
            (recur a
                   b
                   (+ (* p p) (* q q))    ; compute p'
                   (+ (* 2 p q) (* q q))  ; compute q'
                   (/ count 2))
          :else (recur (+ (* b q) (* a q) (* a p))
                       (+ (* b p) (* a q))
                       p
                       q
                       (- count 1)))))

(defn fib [n]
  (fib-iter 1 0 0 1 n))</pre>
<h3>Exercise 1.20</h3>
<pre>(define (gcd a b)
  (if (= b 0)
      a
      (gcd b (remainder a b))))</pre>
<p>Evaluating (gcd 206 40) in normal order:</p>
<pre>(gcd
  206
  40)
(if (= 40 0)
  206
  (gcd
    40
    (remainder 206 40)))
(gcd
  40
  (remainder 206 40))
(if (= (remainder 206 40) 0)
  40
  (gcd
    (remainder 206 40)
    (remainder 40 (remainder 206 40))))
(if (= 6 0)        ; 1 remainder performed here
  40
  (gcd
    (remainder 206 40)
    (remainder 40 (remainder 206 40))))
(gcd
  (remainder 206 40)
  (remainder 40 (remainder 206 40)))
(if (= (remainder 40 (remainder 206 40)) 0)
  (remainder 206 40)
  (gcd
    (remainder 40 (remainder 206 40))
    (remainder (remainder 206 40) (remainder 40 (remainder 206 40)))))
(if (= (remainder 40 6) 0)    ; 1 remainder performed here
  (remainder 206 40)
  (gcd
    (remainder 40 (remainder 206 40))
    (remainder (remainder 206 40) (remainder 40 (remainder 206 40)))))
(if (= 4 0)                   ; 1 remainder performed here
  (remainder 206 40)
  (gcd
    (remainder 40 (remainder 206 40))
    (remainder (remainder 206 40) (remainder 40 (remainder 206 40)))))
(gcd
  (remainder 40 (remainder 206 40))
  (remainder (remainder 206 40) (remainder 40 (remainder 206 40))))
(if (= (remainder (remainder 206 40) (remainder 40 (remainder 206 40))) 0)
  (remainder 40 (remainder 206 40))
  (gcd
    (remainder (remainder 206 40) (remainder 40 (remainder 206 40)))
    (remainder (remainder 40 (remainder 206 40)) (remainder (remainder 206 40) (remainder 40 (remainder 206 40))))))
(if (= (remainder 6 (remainder 40 6)) 0)    ; 2 remainders performed here
  (remainder 40 (remainder 206 40))
  (gcd
    (remainder (remainder 206 40) (remainder 40 (remainder 206 40)))
    (remainder (remainder 40 (remainder 206 40)) (remainder (remainder 206 40) (remainder 40 (remainder 206 40))))))
(if (= (remainder 6 4) 0)                   ; 1 remainder performed here
  (remainder 40 (remainder 206 40))
  (gcd
    (remainder (remainder 206 40) (remainder 40 (remainder 206 40)))
    (remainder (remainder 40 (remainder 206 40)) (remainder (remainder 206 40) (remainder 40 (remainder 206 40))))))
(if (= 2 0)                                 ; 1 remainder performed here
  (remainder 40 (remainder 206 40))
  (gcd
    (remainder (remainder 206 40) (remainder 40 (remainder 206 40)))
    (remainder (remainder 40 (remainder 206 40)) (remainder (remainder 206 40) (remainder 40 (remainder 206 40))))))
(gcd
  (remainder (remainder 206 40) (remainder 40 (remainder 206 40)))
  (remainder (remainder 40 (remainder 206 40)) (remainder (remainder 206 40) (remainder 40 (remainder 206 40))))))
(if (= (remainder (remainder 40 (remainder 206 40)) (remainder (remainder 206 40) (remainder 40 (remainder 206 40)))) 0)
  (remainder (remainder 206 40) (remainder 40 (remainder 206 40)))
  (gcd
    (remainder (remainder 40 (remainder 206 40)) (remainder (remainder 206 40) (remainder 40 (remainder 206 40))))
    (remainder
      (remainder (remainder 206 40) (remainder 40 (remainder 206 40)))
      (remainder (remainder 40 (remainder 206 40)) (remainder (remainder 206 40) (remainder 40 (remainder 206 40)))))))
(if (= (remainder (remainder 40 6) (remainder 6 (remainder 40 6))) 0)       ; 3 remainders performed here
  (remainder (remainder 206 40) (remainder 40 (remainder 206 40)))
  (gcd
    (remainder (remainder 40 (remainder 206 40)) (remainder (remainder 206 40) (remainder 40 (remainder 206 40))))
    (remainder
      (remainder (remainder 206 40) (remainder 40 (remainder 206 40)))
      (remainder (remainder 40 (remainder 206 40)) (remainder (remainder 206 40) (remainder 40 (remainder 206 40)))))))
(if (= (remainder 4 (remainder 6 4)) 0)                                     ; 2 remainders performed here
  (remainder (remainder 206 40) (remainder 40 (remainder 206 40)))
  (gcd
    (remainder (remainder 40 (remainder 206 40)) (remainder (remainder 206 40) (remainder 40 (remainder 206 40))))
    (remainder
      (remainder (remainder 206 40) (remainder 40 (remainder 206 40)))
      (remainder (remainder 40 (remainder 206 40)) (remainder (remainder 206 40) (remainder 40 (remainder 206 40)))))))
(if (= (remainder 4 2) 0)                                                   ; 1 remainder performed here
  (remainder (remainder 206 40) (remainder 40 (remainder 206 40)))
  (gcd
    (remainder (remainder 40 (remainder 206 40)) (remainder (remainder 206 40) (remainder 40 (remainder 206 40))))
    (remainder
      (remainder (remainder 206 40) (remainder 40 (remainder 206 40)))
      (remainder (remainder 40 (remainder 206 40)) (remainder (remainder 206 40) (remainder 40 (remainder 206 40)))))))
(if (= 0 0)                                                                 ; 1 remainder performed here
  (remainder (remainder 206 40) (remainder 40 (remainder 206 40)))
  (gcd
    (remainder (remainder 40 (remainder 206 40)) (remainder (remainder 206 40) (remainder 40 (remainder 206 40))))
    (remainder
      (remainder (remainder 206 40) (remainder 40 (remainder 206 40)))
      (remainder (remainder 40 (remainder 206 40)) (remainder (remainder 206 40) (remainder 40 (remainder 206 40)))))))
(remainder (remainder 206 40) (remainder 40 (remainder 206 40)))
(remainder 6 (remainder 40 6))                                              ; 2 remainders performed here
(remainder 6 4)                                                             ; 1 remainder performed here
2                                                                           ; 1 remainder performed here</pre>
<p>Evaluating (gcd 206 40) in applicative order:</p>
<pre>(gcd
  206
  40)
(if (= 40 0)
  206
  (gcd 40 (remainder 206 40)))
(gcd 40 (remainder 206 40)))
(gcd 40 6)                                                                  ; 1 remainder performed here
(if (= 6 0)
  40
  (gcd 6 (remainder 40 6)))
(gcd 6 (remainder 40 6))
(gcd 6 4)                                                                   ; 1 remainder performed here
(if (= 4 0)
  6
  (gcd 4 (remainder 6 4)))
(gcd 4 (remainder 6 4))
(gcd 4 2)                                                                   ; 1 remainder performed here
(if (= 2 0)
  4
  (gcd 2 (remainder 4 2)))
(gcd 2 (remainder 4 2))
(gcd 2 0)                                                                   ; 1 remainder performed here
(if (= 0 0)
  2
  (gcd 0 (remainder 2 0)))
2</pre>
<p>Total of 18 remainders performed in normal order evaluation of (gcd 206 40)<br />
Only 4 remainders performed in applicative order evaluation of (gcd 206 40)</p>
<h3>Exercise 1.21</h3>
<pre>; find smallest divisor of n
(defn remainder [a b] (mod a b))
(defn square [n] (* n n))
(defn divides? [a b]
  (= (remainder b a) 0))
(defn find-divisor [n test-divisor]
  (loop [n n test-divisor test-divisor]
    (cond (&gt; (square test-divisor) n) n
          (divides? test-divisor n) test-divisor
          :else (recur n (+ test-divisor 1)))))
(defn find-divisor [n test-divisor]
  (cond (&gt; (square test-divisor) n) n
        (divides? test-divisor n) test-divisor
        :else (find-divisor n (+ test-divisor 1))))
(defn smallest-divisor [n]
  (find-divisor n 2))</pre>
<p>Smallest divisors of 199, 1999, and 19999 are 199, 1999, and 7, respectively.</p>
<h3>Exercise 1.22</h3>
<pre>; find smallest divisor of n
(defn remainder [a b] (mod a b))
(defn square [n] (* n n))
(defn divides? [a b]
  (= (remainder b a) 0))
(defn find-divisor [n test-divisor]
  (loop [n n test-divisor test-divisor]
    (cond (&gt; (square test-divisor) n) n
          (divides? test-divisor n) test-divisor
          :else (recur n (+ test-divisor 1)))))
(defn smallest-divisor [n]
  (find-divisor n 2))

(defn prime? [n]
  (= n (smallest-divisor n)))

(defn report-prime [elapsed-time]
  (print " *** ")
  (print elapsed-time))
(defn start-prime-test [n start-time]
  (if (prime? n)
      (report-prime (- (System/currentTimeMillis) start-time))))

(defn timed-prime-test [n]
  (newline)
  (print n)
  (start-prime-test n (System/currentTimeMillis)))

(defn search-for-primes [min]
  (loop [n min remaining 3]
    (cond (= remaining 0) (newline)
          (prime? n)
            (do
              (timed-prime-test n)
              (recur (+ 2 n) (- remaining 1)))
          :else (recur (+ 2 n) remaining))))</pre>
<p>Timing tests frustrated by multiple factors including millisecond granularity (quite rough compared to current processor speeds.) So couldn&#8217;t get reliable timing numbers from primes around 1,000. Around 1,000,000, it took about 1 ms, and at 10,000,000, it took about 2-3 ms, and at 100,000,000 it took about 7-9 ms, and at 1,000,000,000 it took about 25-26 ms. We would expect order sqrt(n) timing, so each factor of 10 increase in n should cause a factor of sqrt(10) or about 3.2 increase in runtime. Our timing measurements seem to confirm that the timing numbers are approximately proportional to the number of steps taken.</p>
<h3>Exercise 1.23</h3>
<pre>; cannot use name next because it is reserved
(defn next-divisor
  "return next divisor value to test for find-divisor"
  [n]
  (if (= n 2) 3 (+ n 2)))

; find smallest divisor of n
(defn remainder [a b] (mod a b))
(defn square [n] (* n n))
(defn divides? [a b]
  (= (remainder b a) 0))
(defn find-divisor [n test-divisor]
  (loop [n n test-divisor test-divisor]
    (cond (&gt; (square test-divisor) n) n
          (divides? test-divisor n) test-divisor
          :else (recur n (+ test-divisor 1)))))
(defn smallest-divisor [n]
  (find-divisor n 2))

(defn prime? [n]
  (= n (smallest-divisor n)))

(defn report-prime [elapsed-time]
  (print " *** ")
  (print elapsed-time))
(defn start-prime-test [n start-time]
  (if (prime? n)
      (report-prime (- (System/currentTimeMillis) start-time))))

(defn timed-prime-test [n]
  (newline)
  (print n)
  (start-prime-test n (System/currentTimeMillis)))

(defn search-for-primes [min]
  (loop [n min remaining 3]
    (cond (= remaining 0) (newline)
          (prime? n)
            (do
              (timed-prime-test n)
              (recur (+ 2 n) (- remaining 1)))
          :else (recur (+ 2 n) remaining))))</pre>
<p>At around 10,000,000 this test takes about 1-2 ms., and at 100,000,000 the test takes about 4-5 ms. and at around 1,000,000,000 it takes around 14-16 ms. In principle we expect a 2x speedup, however we do not quite realize a full 2x speedup because part of the savings in fewer iterations of find-divisor are offset by the overhead of calling next-divisor.</p>
<h3>Exercise 1.24</h3>
<pre>(defn expmod [base exp m]
   (cond (= exp 0) 1
         (even? exp)
           (remainder (square (expmod base (/ exp 2) m))
                      m)
         :else (remainder (* base (expmod base (- exp 1) m))
                          m)))

(defn fermat-test [n]
  (defn try-it [a]
    (= (expmod a n n) a))
  (try-it (+ 1 (rand-int (- n 1)))))
(defn fast-prime? [n times]
  (loop [n n times times]
    (cond (= times 0) true
          (fermat-test n) (recur n (- times 1))
          :else false)))

(defn prime? [n] (fast-prime? n 4))

(defn report-prime [elapsed-time]
  (print " *** ")
  (print elapsed-time))
(defn start-prime-test [n start-time]
  (if (prime? n)
      (report-prime (- (System/currentTimeMillis) start-time))))

(defn timed-prime-test [n]
  (newline)
  (print n)
  (start-prime-test n (System/currentTimeMillis)))

(defn search-for-primes [min]
  (loop [n min remaining 3]
    (cond (= remaining 0) (newline)
          (prime? n)
            (do
              (timed-prime-test n)
              (recur (+ 2 n) (- remaining 1)))
          :else (recur (+ 2 n) remaining))))</pre>
<p>Times on the 1.24 version are barely measureable, even only measuring a ms. or so around 10,000,000,000 and even when the number gets 2 or 3 orders of magnitude higher. For this reason, it is difficult to confirm the actual log n growth, however it is clear that the runtime is much better than the prev. ones, and the growth pattern seems equally so, so it is reasonable to assume that we have approximate log n growth rate.</p>
<h3>Exercise 1.25</h3>
<p>Alyssa&#8217;s suggestion to simply use fast-expt in conjunction with remainder would work in principle, however it is likely to be considerably slower than our expmod version. The reason for this is that we are using arbitrary precision integer math, hence operations on values with more digits take longer. Our expmod implementation applies remainder at each step, keeping values from growing very large, so the overall operation should take less time than waiting until the end to apply remainder once to a large value.</p>
<h3>Exercise 1.26</h3>
<p>By using explicit multiplication instead of square, each operand of the multiplication has to get evaluated independently. So whereas we only make one recursive call to expmod with the &#8220;square&#8221; implementation, with the multiplication implementation, we would actually make 2. The whole principle of halving the problem space has been nullified, and the theta(log n) becomes theta(n).</p>
<h3>Exercise 1.27</h3>
<pre>(defn expmod [base exp m]
   (cond (= exp 0) 1
         (even? exp)
           (remainder (square (expmod base (/ exp 2) m))
                      m)
         :else (remainder (* base (expmod base (- exp 1) m))
                          m)))

(defn test-carmichael [n]
  (loop [a 1]
    (cond (= n a) true
          (= (expmod a n n) (remainder a n)) (recur (+ 1 a))
          :else false)))</pre>
<p>This does indeed return true for all the Carmichael numbers mentioned in footnote 47.</p>
<h3>Exercise 1.28</h3>
<pre>; squaring step in expmod, we check to see if we have discovered a ``nontrivial square root of 1 modulo n,''
; that is, a number not equal to 1 or n - 1 whose square is equal to 1 modulo n. It is possible to prove that if
; such a nontrivial square root of 1 exists, then n is not prime. It is also possible to prove that if n is an odd
(defn expmod [base exp m]
   (cond (= exp 0) 1
         (even? exp)
           (let [root (expmod base (/ exp 2) m) sqr (remainder (square root) m)]
             (if (and (not= root 1) (not= root (- m 1)) (= sqr 1))
               0        ; signal that found nontrivial square root of 1
               sqr))
         :else (remainder (* base (expmod base (- exp 1) m))
                          m)))

(defn fermat-test [n]
  (defn try-it [a]
    (= (expmod a n n) a))
  (try-it (+ 1 (rand-int (- n 1)))))
(defn fast-prime? [n times]
  (loop [n n times times]
    (cond (= times 0) true
          (fermat-test n) (recur n (- times 1))
          :else false)))

(defn prime? [n] (fast-prime? n 4))

(defn report-prime [elapsed-time]
  (print " *** ")
  (print elapsed-time))
(defn start-prime-test [n start-time]
  (if (prime? n)
      (report-prime (- (System/currentTimeMillis) start-time))))

(defn timed-prime-test [n]
  (newline)
  (print n)
  (start-prime-test n (System/currentTimeMillis)))

(defn search-for-primes [min]
  (loop [n min remaining 3]
    (cond (= remaining 0) (newline)
          (prime? n)
            (do
              (timed-prime-test n)
              (recur (+ 2 n) (- remaining 1)))
          :else (recur (+ 2 n) remaining))))</pre>
<h3>Exercise 1.29</h3>
<pre>(defn coefficient
  "Compute coefficient for term for evaluation via Simpson's Rule"
  [n total-n]
  (cond (= 0 n) 1
        (= total-n n) 1
        (even? n) 2
        :else 4))

(defn sum-simp [f a h n]
  (loop [k 0 acc 0]
    (if (&gt; k n)
      acc
      (recur (inc k) (+ acc (* (coefficient k n) (f (+ a (* k h)))))))))

(defn integral
  "Compute integral of f from a to b using n samples, via Simpson's Rule"
  [f a b n]
  (let [h (/ (- b a) n)]
    (/ (* h (sum-simp f a h n)) 3)))</pre>
<p>This implementation uses rational rather than floating point math.<br />
For computing integral of cube from 0 to 1, it computes exactly 1/4 for any<br />
even n &gt; 0, including 100 and 1000.</p>
<p>From the way the exercise is worded, perhaps the authors expected the<br />
implementation to use floating point, but it seems silly to rewrite it to<br />
make it less precise.</p>
<h3>Exercise 1.30</h3>
<pre>(defn sum
  "Iterative function to sum terms from a to b"
  [term a next b]
  (loop [a a result 0]
    (if (&gt; a b)
        result
        (recur (next a) (+ result (term a))))))</pre>
<h3>Exercise 1.31</h3>
<p>Implemented using floating point this time.</p>
<pre>(defn product
  "Iterative function to multiply terms from a to b"
  [term a next b]
  (loop [a a result 1.0]
    (if (&gt; a b)
        result
        (recur (next a) (* result (term a))))))

(defn pi-div-4 [nterms]
  (defn piterm [n]
    (if (even? n)
        (/ (+ n 2) (+ n 3))
        (/ (+ n 3) (+ n 2))))
  (product piterm 0 inc nterms))</pre>
<p>part b)</p>
<pre>(defn product
  "Recursive function to multiply terms from a to b"
  [term a next b]
  (if (&gt; a b)
      1.0
      (* (term a) (product term (next a) next b))))</pre>
<h3>Exercise 1.32</h3>
<p>Both sum and product iterate over a range of numbers, applying a certain operation to each number in turn, to generate a term, and then applying a binary merge operation to merge the current term into the accumulated result. For sum, the merge operation is + and for product, the merge operation is *. In each case, the accumulator must be initialized with the appropriate identity element for the operation. For sum, the identity element is 0, and for product, the identity element is 1. SICP calls this identity element the null-value or base value.</p>
<pre>(defn accumulate
  "accumulate a collection of terms from a to b using a combiner function"
  [combiner null-value term a next b]
  (loop [acc null-value n a]
    (if (&gt; n b)
        acc
        (recur (combiner acc (term n)) (next n)))))

(defn sum [term a next b]
  (accumulate + 0 term a next b))

(defn product [term a next b]
  (accumulate * 1 term a next b))</pre>
<p>part b) implement accumulator as a recursive procedure</p>
<pre>(defn accumulate
  "accumulate a collection of terms from a to b using a combiner function"
  [combiner null-value term a next b]
  (if (&gt; a b)
      null-value
      (combiner (accumulate combiner null-value term (next a) next b) (term a))))</pre>
<h3>Exercise 1.33</h3>
<pre>(defn filtered-accumulate
  "accumulate a filtered collection of terms from a to b using a combiner"
  [combiner null-value term a next b filterp]
  (loop [acc null-value n a]
    (if (&gt; n b)
      acc
      (let [cur-term (term n) next-n (next n)]
        (if (filterp cur-term)
            (recur (combiner acc cur-term) next-n)
            (recur acc next-n))))))

(defn sum-prime-squares [a b]
  (defn square [n] (* n n))
  (defn id [n] n)
  (defn combiner [acc n] (+ acc (* n n)))
  (filtered-accumulate combiner 0 id a inc b prime?))

(defn prod-relative-primes
  "compute product of all positive integers less than n that are relatively prime to n"
  [n]
  (defn id [n] n)
  (defn gcd [a b]
    (if (= b 0)
        a
        (gcd b (remainder a b))))
  (defn filterp [i] (= (gcd i n) 1))
  (filtered-accumulate * 1 id 1 inc (- n 1) filterp))</pre>
<h3>Exercise 1.34</h3>
<p>(defn f [g] (g 2))</p>
<p>Trying to evaluate (f f) with Clojure blows up with a ClassCastException because it will evaluate to (f 2) and then balk when trying to further evaluate because it&#8217;s expecting a function as the argument to f, and it cannot cast integer 2 to an integer function.</p>
<h3>Exercise 1.35</h3>
<p>Fixed point of x -&gt; 1 + 1/x is the value x such that x = 1 + 1/x.<br />
We are given Phi^2 = Phi + 1 by definition of the golden ratio. Dividing<br />
each side by Phi we get Phi = 1 + 1/Phi, and can immediately see that<br />
Phi serves as a fixed point for x -&gt; 1 + 1/x.</p>
<p>Have to use tryf in place of try since try is a Clojure reserved word.</p>
<pre>(defn fixed-point [f first-guess]
  (defn abs [x] (if (&lt; x 0.0) (- x) x))
  (defn close-enough? [v1 v2]
    (let [tolerance 0.00001]
      (&lt; (abs (- v1 v2)) tolerance)))
  (defn tryf [guess]
    (let [next (f guess)]
      (if (close-enough? guess next)
          next
          (tryf next))))
  (tryf first-guess))</pre>
<p>Or iteratively:</p>
<pre>
(defn fixed-point [f first-guess]
  (defn abs [x] (if (&lt; x 0.0) (- x) x))
  (defn close-enough? [v1 v2]
    (let [tolerance 0.00001]
      (&lt; (abs (- v1 v2)) tolerance)))
  (defn tryf [guess]
    (loop [guess guess next (f guess)]
      (if (close-enough? guess next)
          next
          (recur next (f next)))))
  (tryf first-guess))

user=&gt; (fixed-point (fn [x] (+ 1 (/ 1 x))) 1.0)
1.6180327868852458
</pre>
<h3>Exercise 1.36</h3>
<pre>(defn fixed-point [f first-guess]
  (defn abs [x] (if (&lt; x 0.0) (- x) x))
  (defn close-enough? [v1 v2]
    (let [tolerance 0.00001]
      (&lt; (abs (- v1 v2)) tolerance)))
  (defn tryf [guess]
    (loop [guess guess next (f guess)]
      (println guess)
      (if (close-enough? guess next)
          next
          (recur next (f next)))))
  (tryf first-guess))

user=&gt; (fixed-point (fn [x] (/ (Math/log 1000) (Math/log x))) 10)
10
2.9999999999999996
6.2877098228681545
3.7570797902002955
5.218748919675316
4.1807977460633134
4.828902657081293
4.386936895811029
4.671722808746095
4.481109436117821
4.605567315585735
4.522955348093164
4.577201597629606
4.541325786357399
4.564940905198754
4.549347961475409
4.5596228442307565
4.552843114094703
4.55731263660315
4.554364381825887
4.556308401465587
4.555026226620339
4.55587174038325
4.555314115211184
4.555681847896976
4.555439330395129
4.555599264136406
4.555493789937456
4.555563347820309
4.555517475527901
4.555547727376273
4.555527776815261
4.555540933824255
4.555532257016376
user=&gt;</pre>
<p>Now, with average damping:</p>
<pre>user=&gt; (fixed-point (fn [x] (average x (/ (Math/log 1000) (Math/log x)))) 10)
10
6.5
5.095215099176933
4.668760681281611
4.57585730576714
4.559030116711325
4.55613168520593
4.555637206157649
4.55555298754564
4.555538647701617
4.555536206185039
user=&gt;</pre>
<p>It only took 11 steps with average damping, versus 34 steps without damping.</p>
<h3>Exercise 1.37</h3>
<p>a.</p>
<pre>; Evaluate continued fraction based upon n and d which return terms for
; the numerator and denominator, and k is number of terms (indexed by 1).
(defn cont-frac [n d k]
  (defn contR [i]
    (if (= i k)
        (/ (n i) (d i))
        (/ (n i) (+ (d i) (contR (inc i))))))
  (contR 1))</pre>
<p>It takes k of 10 to approximate golden ratio to 4 decimal digits:</p>
<pre>user=&gt; (cont-frac (fn [x] 1.0) (fn [x] 1.0) 10)
0.6179775280898876</pre>
<p>b. Iterative process version:</p>
<pre>; Evaluate continued fraction based upon n and d which return terms for
; the numerator and denominator, and k is number of terms (indexed by 1).
; this version uses an iterative process
(defn cont-frac [n d k]
  (loop [i k acc 0]
    (if (= i 0)
        acc
        (recur (dec i) (/ (n i) (+ (d i) acc))))))</pre>
<h3>Exercise 1.38</h3>
<pre>; compute e via Euler's continued fraction, using k steps
; all Ni = 1, Di = 1,2,1,1,4,1,1,6,1,1,8,...
(defn compute-e [k]
  (defn d [i]
    (if (= (rem i 3) 2)
        (/ (+ i i 2) 3)
		1))
  (+ 2 (cont-frac (fn [x] 1.0) d k)))</pre>
<h3>Exercise 1.39</h3>
<pre>; compute tangent function via Lambert's continued fraction
; N1 = r; all other Ni = -r^2;  Di = 2i-1;  x is angle in radians; k is # steps
(defn tan-cf [x k]
  (let [mxx (- (* x x))]
    (defn n [i]
      (if (= i 1)
          x
          mxx))
    (cont-frac n (fn [i] (+ i i -1)) k)))</pre>
<h3>Exercise 1.40</h3>
<pre>(defn cubic
  "return function that computes f(x) -&gt; x^3 + ax^2 + bx + c"
  [a b c]
  (fn [x] (+ (* x x x) (* a x x) (* b x) c)))</pre>
<h3>Exercise 1.41</h3>
<pre>(defn doublef
  "takes 1-arg procedure and returns procedure that applies original twice"
  [f]
  (fn [x] (f (f x))))</pre>
<p>(((doublef (doublef doublef)) inc) 5) returns 21</p>
<h3>Exercise 1.42</h3>
<pre>(defn compose
  "compose f after g: create function that takes x and returns f(g(x))"
  [f g]
  (fn [x] (f (g x))))</pre>
<h3>Exercise 1.43</h3>
<pre>(defn compose
  "compose f after g: create function that takes x and returns f(g(x))"
  [f g]
  (fn [x] (f (g x))))

(defn repeated
  "nth repeated application of f"
  [f n]
  (fn [x] (if (= n 0)
              x
              ((compose f (repeated f (dec n))) x))))</pre>
<h3>Exercise 1.44</h3>
<pre>(defn smooth
  "create smoothed version that averages f(x) with f(x-dx) and f(x+dx)"
  [f]
  (let [dx 0.0001]
    (fn [x] (/ (+ (f (- x dx)) (f x) (f (+ x dx))) 3))))

(defn smooth-repeated
  "create the n-fold smoothed function based upon f"
  [f n]
  ((repeated smooth n) f))</pre>
<h3>Exercise 1.45</h3>
<pre>(defn nthroot
  "try to find nth root of x using a repeated applications of average damping"
  [n x a]
  (fixed-point ((repeated average-damp a) (fn [y] (/ x (Math/pow y (- n 1))))) 2.0))</pre>
<p>Experimentation with the above code with fixed-point instrumented with debugging println empirically shows that the number of applications of average damping required for the nth root calculation increases by 1 each time n reaches another power of 2. For n = 2, 1 application required, but for n = 32, 5 applications are required. For n = 31, 4 applications required. So a should be equal to the floor of log-base-2 of n.</p>
<p>This leads to the following code:</p>
<pre>(defn average2 [x y] (/ (+ x y) 2))
(defn average-damp
  "return a modified version of function that averages its value with its arg"
  [f]
  (fn [x] (average2 x (f x))))

(defn fixed-point [f first-guess]
  (defn abs [x] (if (&lt; x 0.0) (- x) x))
  (defn close-enough? [v1 v2]
    (let [tolerance 0.00001]
      (&lt; (abs (- v1 v2)) tolerance)))   (defn tryf [guess]     (loop [guess guess next (f guess)]       (if (close-enough? guess next)           next           (recur next (f next)))))   (tryf first-guess)) (defn compose   "compose f after g: create function that takes x and returns f(g(x))"   [f g]   (fn [x] (f (g x)))) (defn repeated   "nth repeated application of f"   [f n]   (fn [x] (if (= n 0)               x               ((compose f (repeated f (dec n))) x)))) (defn floor-log2   "return floor of log base 2 of n for positive n"   [n]   (loop [l 0 ll 2]     (if (&gt; ll n)
        l
        (recur (inc l) (* 2 ll)))))

(defn nthroot
  "try to find nth root of x using repeated applications of average damping"
  [n x]
  (fixed-point
    ((repeated average-damp (floor-log2 n)) (fn [y] (/ x (Math/pow y (- n 1)))))
    2.0))</pre>
<h3>Exercise 1.46</h3>
<pre>(def tolerance 0.00001)
(defn iterative-improve
  "perform iterative improvements of guess until it's good enough"
  [good-enough? improve]
  (fn [initial-guess]
    (loop [prev-guess initial-guess new-guess (improve initial-guess)]
      (if (good-enough? new-guess prev-guess)
          new-guess
          (recur new-guess (improve new-guess))))))

(defn average [x y] (/ (+ x y) 2))
(defn abs [x] (if (&lt; x 0) (- x) x))
(defn good-enough?
  [guess prevGuess]
  (&lt; (/ (abs (- guess prevGuess)) guess) 0.0001))

(defn sqrt [x]
  (defn improve-sqrt [guess]
    (average guess (/ x guess)))
  ((iterative-improve good-enough? improve-sqrt) 1.0))

(defn fixed-point
  [f first-guess]
  ((iterative-improve good-enough? (fn [x] (f x))) first-guess))</pre>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/alexstangl.wordpress.com/25/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/alexstangl.wordpress.com/25/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/alexstangl.wordpress.com/25/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/alexstangl.wordpress.com/25/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/alexstangl.wordpress.com/25/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/alexstangl.wordpress.com/25/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/alexstangl.wordpress.com/25/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/alexstangl.wordpress.com/25/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/alexstangl.wordpress.com/25/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/alexstangl.wordpress.com/25/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/alexstangl.wordpress.com/25/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/alexstangl.wordpress.com/25/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/alexstangl.wordpress.com/25/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/alexstangl.wordpress.com/25/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=alexstangl.wordpress.com&amp;blog=8530621&amp;post=25&amp;subd=alexstangl&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://alexstangl.wordpress.com/2010/03/16/sicp-chap-1-exercises-in-clojure/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/56924cdfc551b65852fe6e7ad9f78f41?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">alexstangl</media:title>
		</media:content>
	</item>
		<item>
		<title>SICP Exercise solutions in Clojure and Haskell</title>
		<link>http://alexstangl.wordpress.com/2010/03/16/sicp-exercise-solutions-in-clojure-and-haskell/</link>
		<comments>http://alexstangl.wordpress.com/2010/03/16/sicp-exercise-solutions-in-clojure-and-haskell/#comments</comments>
		<pubDate>Tue, 16 Mar 2010 01:28:52 +0000</pubDate>
		<dc:creator>alexstangl</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[Clojure]]></category>
		<category><![CDATA[Haskell]]></category>
		<category><![CDATA[Lambda]]></category>
		<category><![CDATA[SICP]]></category>

		<guid isPermaLink="false">http://alexstangl.wordpress.com/?p=16</guid>
		<description><![CDATA[In early 2010, some members of a local user&#8217;s group, Lambda Lounge started a book club to work through the book Structure And Interpretation of Computer Programs by Abelson and Sussman. I am starting some blog pages here to share the SICP exercise solutions in Clojure, and hopefully eventually in Haskell. Stay tuned! Other SICP-related [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=alexstangl.wordpress.com&amp;blog=8530621&amp;post=16&amp;subd=alexstangl&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>In early 2010, some members of a local user&#8217;s group, <a title="Lambda Lounge" href="http://lambdalounge.org">Lambda Lounge</a> started a <a href="http://groups.google.com/group/sicp-lounge">book club</a> to work through the book <a title="SICP" href="http://mitpress.mit.edu/sicp/">Structure And Interpretation of Computer Programs</a> by Abelson and Sussman.</p>
<p>I am starting some blog pages here to share the SICP exercise solutions in Clojure, and hopefully eventually in Haskell. Stay tuned!</p>
<div>Other SICP-related links:</div>
<p><a href="http://deptinfo.unice.fr/%7Eroy/sicp.pdf">PDF file containing full SICP textbook</a><br />
<a href="http://groups.csail.mit.edu/mac/classes/6.001/abelson-sussman-lectures/">MIT SICP Lecture videos</a><br />
<a href="http://www.archive.org/details/mit_ocw_sicp">Alternate source for lecture videos</a></p>
<p><a href="http://wiki.drewhess.com/wiki/Category:SICP_solutions">Exercise solutions</a></p>
<p><a href="http://sicpinclojure.com/">http://sicpinclojure.com/</a><br />
<a href="http://learnclojure.blogspot.com/">http://learnclojure.blogspot.com/</a><br />
<a href="http://lotrepls.appspot.com/">Online REPL for Scheme and Clojure (and more)</a></p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/alexstangl.wordpress.com/16/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/alexstangl.wordpress.com/16/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/alexstangl.wordpress.com/16/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/alexstangl.wordpress.com/16/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/alexstangl.wordpress.com/16/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/alexstangl.wordpress.com/16/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/alexstangl.wordpress.com/16/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/alexstangl.wordpress.com/16/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/alexstangl.wordpress.com/16/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/alexstangl.wordpress.com/16/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/alexstangl.wordpress.com/16/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/alexstangl.wordpress.com/16/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/alexstangl.wordpress.com/16/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/alexstangl.wordpress.com/16/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=alexstangl.wordpress.com&amp;blog=8530621&amp;post=16&amp;subd=alexstangl&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://alexstangl.wordpress.com/2010/03/16/sicp-exercise-solutions-in-clojure-and-haskell/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/56924cdfc551b65852fe6e7ad9f78f41?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">alexstangl</media:title>
		</media:content>
	</item>
		<item>
		<title>Simple parser</title>
		<link>http://alexstangl.wordpress.com/2009/07/11/simple-parser/</link>
		<comments>http://alexstangl.wordpress.com/2009/07/11/simple-parser/#comments</comments>
		<pubDate>Sat, 11 Jul 2009 13:34:37 +0000</pubDate>
		<dc:creator>alexstangl</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[Haskell]]></category>

		<guid isPermaLink="false">http://alexstangl.wordpress.com/2009/07/11/simple-parser/</guid>
		<description><![CDATA[A recent thread on the St. Louis Lambda Lounge mailing list resurrected an old thread on Tony Morris&#8217; blog, writing a parser for a simple grammar (balanced () and []) in different languages. The original author shows a dense Haskell implementation (not using Parsec), among others. Followup comments include a Parsec implementation. Here is my [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=alexstangl.wordpress.com&amp;blog=8530621&amp;post=1&amp;subd=alexstangl&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>A recent thread on the <a href="http://lambdalounge.org">St. Louis Lambda Lounge</a> mailing list resurrected an old thread on <a href="http://dibblego.wordpress.com/2008/09/05/haskell-scala-java-7-functional-java-java/">Tony Morris&#8217; blog</a>, writing a parser for a simple grammar (balanced () and []) in different languages. The original author shows a dense Haskell implementation (not using Parsec), among others. Followup comments include a Parsec implementation.</p>
<p>Here is my attempt at a simple Haskell implementation. In some ways not as concise as the original Haskell version, it seems easy to read and extend.</p>
<pre>-- Parser returns whether string is composed of balanced
-- brackets and parens (e.g., "[()]", "[]()", "", etc.)
-- returns false if not balanced or any other character found

pairs = [('[',']'), ('(',')')]

parse = match []
-- ss is stack of closing chars to match, cs is input string
match (s:ss) (c:cs) | c == s = match ss cs
match ss (c:cs) =
  case lookup c pairs of
    Nothing -&gt; False
    Just s  -&gt; match (s:ss) cs
match ss [] = null ss</pre>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/alexstangl.wordpress.com/1/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/alexstangl.wordpress.com/1/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/alexstangl.wordpress.com/1/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/alexstangl.wordpress.com/1/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/alexstangl.wordpress.com/1/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/alexstangl.wordpress.com/1/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/alexstangl.wordpress.com/1/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/alexstangl.wordpress.com/1/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/alexstangl.wordpress.com/1/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/alexstangl.wordpress.com/1/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/alexstangl.wordpress.com/1/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/alexstangl.wordpress.com/1/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/alexstangl.wordpress.com/1/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/alexstangl.wordpress.com/1/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=alexstangl.wordpress.com&amp;blog=8530621&amp;post=1&amp;subd=alexstangl&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://alexstangl.wordpress.com/2009/07/11/simple-parser/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/56924cdfc551b65852fe6e7ad9f78f41?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">alexstangl</media:title>
		</media:content>
	</item>
	</channel>
</rss>
