Wizard

COMP 524: Programming Language Concepts

Spring, 2008
Jeff Terrell
jsterrel AT cs.unc.edu
(919) 962-1791 (office: Sitterson 138)

View Source of exercise2.php

In the interest of open source, and in the interest of keeping Mr. Webmaster honest, here is the PHP source of exercise2.php. (This encourages him to write clean, easy-to-understand code...well, relatively clean and easy-to-understand, that is.) If you become interested in PHP, you can read more about it at PHP: Hypertext Preprocessor. You will also see plenty of HTML code, which is what makes the World Wide Web go 'round. You can read more about HTML (and CSS, another technology used on this site) here, at the official page of the very official World Wide Web Consortium (W3C). Anyway, enough rambling, here's the code!


<?php include("header1.php"); ?>
<?php $THIS_FILE 
"exercise2.php"?>
  <title>COMP 524-S08 - Exercise 2 (Scheme)</title>
  <link rel="stylesheet" href="local.css" type="text/css" charset="iso-8859-1" title="Default" />
<?php include("header2.php"); ?>
<?php 
include("localheader.php"); ?>

<h1>COMP 524 Exercise 2 (Scheme)</h1>

<h2>General Instructions</h2>
<p>First, review the assignment submission policy in the <a href="syllabus.php">syllabus</a>.  Note that there is <strong>no collaboration</strong> allowed.</p>
<p>This assignment is <strong>due at 11:59pm on Friday, March 7</strong>.  Submit assignments to me via email.  All of your functions should be included in a file called 'exercise2.scm', and 'exercise2.scm' should include everything that you turn in.  When I am finished grading your assignment, I will email you your grade and any comments that I have (assuming I have your permission for this).  There are a total of 100 points.</p>
<p>Remember: <strong>start early</strong>!  I guarantee my availability during office hours, but not at 11pm the night it is due.</p>
<p>When you turn in exercise2.scm, there should be no statements at the top level that produce output or require input.  Merely provide the required functions and anything the functions need--do not include any code related to your testing or debugging.  When I import your functions into another script, I want the import to be silently successful.  Thank you.</p>

<p><a href="exercise2.scm">My solutions</a> are available.</p>

<h3>1. Chasing the Tail</h3>
<dl>
  <dt>Details</dt>
  <dd>Define a procedure <code>last-pair</code> that returns the list that contains only the last element of a given (nonempty) list.</dd>
  <dt>Example</dt>
  <dd class="code">
    (last-pair (list 23 72 149 34))<br/>
    <em>(34)</em>
  </dd>
  <dt>Points</dt>
  <dd>10 points</dd>
  <dt>Par</dt>
  <dd>2 minutes</dd>
</dl>

<h3>2. Reversing Lists</h3>
<dl>
  <dt>Details</dt>
  <dd>Define a procedure <code>reverse</code> that takes a list as the argument and returns a list of the same elements in reverse order.</dd>
  <dt>Example</dt>
  <dd class="code">
    (reverse (list 1 4 9 16 25))<br/>
    <em>(25 16 9 4 1)</em>
  </dd>
  <dt>Hint</dt>
  <dd>If you're using the <a href="http://dynamo.iro.umontreal.ca/~gambit/wiki/index.php/Main_Page">Gambit Scheme</a> Interpreter (gsi), you may want to use the <code>pretty-print</code> function with lists.  (It's more legible than the <code>print</code> function.)</dd>
  <dt>Points</dt>
  <dd>10 points</dd>
  <dt>Par</dt>
  <dd>12 minutes</dd>
</dl>

<h3>3. Dotted Tails</h3>
<dl>
  <dt>Summary</dt>
  <dd>Practice using dotted-tail notation to define variable-argument procedures.</dd>
  <dt>Background</dt>
  <dd><p>The procedures <code>+</code>, <code>*</code>, and <code>list</code> take arbitrary numbers of arguments. One way to define such procedures is to use <code>define</code> with dotted-tail notation. In a procedure definition, a parameter list that has a dot before the last parameter name indicates that, when the procedure is called, the initial parameters (if any) will have as values the initial arguments, as usual, but the final parameter's value will be a list of any remaining arguments.</p>
    <p>For instance, given the definition <code>(define (f x y . z) &lt;body&gt;)</code>, the procedure <code>f</code> can be called with two or more arguments. If we evaluate <code>(f 1 2 3 4 5 6)</code>, then, in the body of <code>f</code>, <code>x</code> will be 1, <code>y</code> will be 2, and <code>z</code> will be the list <code>(3 4 5 6)</code>. As another example, given the definition <code>(define (g . w) &lt;body&gt;)</code>, the procedure <code>g</code> can be called with zero or more arguments. If we evaluate <code>(g 1 2 3 4 5 6)</code>, then, in the body of <code>g</code>, <code>w</code> will be the list <code>(1 2 3 4 5 6)</code>.</p>
  </dd>
  <dt>Details</dt>
  <dd>Use this notation to write a procedure <code>same-parity</code> that takes one or more integers and returns a list of all the arguments that have the same even-odd parity as the first argument.</dd>
  <dt>Examples</dt>
  <dd>
    <p><strong>Update 2008-02-26, 11:20am:</strong> the examples were wrong.  The first argument should not be part of the list that is returned.  So <code>(same-parity 1 3)</code> returns <code>(3)</code>, not <code>(1 3)</code>.  (This makes it easier to write this function.  If you already have a function which works the old way, you can just use that; I will accept it either way.)</p>
    <div class="code">
      (same-parity 3 1 2 3 4 5 6 7)<br/>
      <em>(1 3 5 7)</em><br/>
      (same-parity 2 2 3 4 5 6 7)<br/>
      <em>(2 4 6)</em>
    </div>
  </dd>
  <dt>Hints</dt>
  <dd>
    <p>One problem is how to call a variable-argument function with a list, so that the arguments are in the list.  To do this, use the <code>apply</code> function.  For example, <code>(+ (list 1 2))</code> gives <code>Error: number expected</code>, but <code>(apply + (list 1 2))</code> gives <code>3</code>.</p>
    <p>You might want to use the <code>modulo</code> or <code>odd?</code> functions provided with Scheme.</p>
  </dd>
  <dt>Points</dt>
  <dd>10 points</dd>
  <dt>Par</dt>
  <dd>11 minutes</dd>
</dl>

<h3>4. Products</h3>
<dl>
  <dt>Summary</dt>
  <dd>Write an abstract function for product forms.</dd>
  <dt>Background</dt>
  <dd>The <code>sum</code> procedure that we saw in class is only the simplest of a vast number of similar abstractions that can be captured as higher-order procedures.  Recall that <code>sum</code> looked like this:<br/>
<pre class="code">(define (sum term a next b)
  (if (&gt; a b)
      0
      (+ (term a)
         (sum term (next a) next b)
      )
  ))</pre>
  </dd>
  <dt>Details</dt>
  <dd><p>Write an analogous procedure called <code>product</code> that returns the product of the values of a function at points over a given range.  Define a function <code>factorial</code> in terms of <code>product</code>. Also use <code>product</code> to compute approximations to pi using the formula:</p>
    <p><img src="eqn2.png" alt="Approximation to PI/4" /></p>
    <p>by defining a function <code>pi-approx</code> that accepts a single argument <code>n</code>, the number of terms to use in the approximation (where 2/3 is one term, 4/3 is another, and so on).</p>
    <p>Then, make <code>product</code> into a tail-recursive procedure called <code>prod-iterative</code>.</p>
  </dd>
  <dt>Examples</dt>
  <dd class="code">
    (factorial 5)<br/>
    <em>120</em><br/>
    (pi-approx 5)<br/>
    <em>2.9257142857142853</em><br/>
    (pi-approx 10000)<br/>
    <em>3.1417497057379746</em>
  </dd>
  <dt>Hint</dt>
  <dd>To keep Scheme from representing numbers as fractions, specify a number literal with a decimal point.  <code>(/ 2 8)</code> is <code><em>1/4</em></code>, but <code>(/ 2. 8)</code> is <code><em>.25</em></code>.</dd>
  <dt>Points</dt>
  <dd>5 for <code>product</code>; 5 for <code>prod-iterative</code>; 5 for <code>factorial</code>; and 5 for <code>pi-approx</code>.</dd>
  <dt>Par</dt>
  <dd>33 minutes</dd>
</dl>

<h3>5. Pascal's Triangle</h3>
<dl>
  <dt>Summary</dt>
  <dd>Compute a row of Pascal's Triangle.</dd>
  <dt>Background</dt>
  <dd>The following pattern of numbers is called Pascal's Triangle:<br/>
  <pre class="code">    1
   1 1
  1 2 1
 1 3 3 1
1 4 6 4 1</pre>
  That is, each number is the sum of the numbers immediately above it, with 1's along the outside.</dd>
  <dt>Details</dt>
  <dd>Write a Scheme function called <code>pascal-row</code> that returns a list of the i-th row of Pascal's Triangle.</dd>
  <dt>Examples</dt>
  <dd class="code">
    (pascal-row 1)<br/>
    <em>(1 1)</em><br/>
    (pascal-row 17)<br/>
    <em>(1 17 136 680 2380 6188 12376 19448 24310 24310 19448 12376 6188 2380 680 136 17 1)</em>
  </dd>
  <dt>Points</dt>
  <dd>20 points</dd>
  <dt>Par</dt>
  <dd>10 minutes</dd>
</dl>

<h3>6. Simpson's Rule</h3>
<dl>
  <dt>Summary</dt>
  <dd>Apply Simpson's rule to numerically compute integral approximations.</dd>
  <dt>Background</dt>
  <dd><p>Simpson's Rule is an accurate method of numerical integration. Using Simpson's Rule, the integral of a function <code>f</code> between <code>a</code> and <code>b</code> is approximated as:</p>
    <p><img src="eqn1.png" alt="Equation for Simpson's Rule" /></p>
    <p>where <code>h = (b - a)/n</code>, for some even integer <code>n</code>, and <code>y<sub>k</sub> = f(a + kh)</code>. (Increasing <code>n</code> increases the accuracy of the approximation.)</p>
    </dd>
  <dt>Details</dt>
  <dd><p>Define a procedure that takes as arguments <code>f</code>, <code>a</code>, <code>b</code>, and <code>n</code> and returns the value of the integral, computed using Simpson's Rule.  Call your procedure <code>simpson</code>.</p>
    <p>Then, write a procedure that integrates <code>cube</code> (i.e. <code>(lambda (x) (* x x x))</code>) from 0 to 1 and only accepts <code>n</code> as an argument.  Your procedure should call <code>simpson</code> to perform the integration.  Call this procedure <code>approx-int-cube</code>.</p>
    <p>Note: when using Gambit Scheme, I ran into a problem if I made <code>n</code> too large.  Apparently, the <code>+</code> operator cannot handle more than 8,191 arguments.  So, I will not grade your problem with <code>n</code> larger than 8,000.  (Remember that <code>n</code> is supposed to be even.)</p>
  </dd>
  <dt>Example</dt>
  <dd class="code">
    (simpson sin 0. 3.1415926 1000)<br/>
    <em>2.0000000000010814</em><br/>
    (approx-int-cube 10)<br/>
    <em>.25</em><br/>
    (approx-int-cube 100)<br/>
    <em>.25000000000000006</em><br/>
    (approx-int-cube 1000)<br/>
    <em>.25</em><br/>
    (approx-int-cube 8190)<br/>
    <em>.25000000000000033</em>
  </dd>
  <dt>Hint</dt>
  <dd>You might find the <code>let*</code> special form to be helpful here.  It's like <code>let</code>, except that the scope of each variable is extended to include all following declarations.  The effect is that you can effectively chain <code>define</code>s.</dd>
  <dt>Points</dt>
  <dd>25 points for <code>simpson</code>; 5 for <code>approx-int-cube</code></dd>
  <dt>Par</dt>
  <dd>46 minutes, +20 more debugging after I learned that my answers were off.</dd>
</dl>

<?php include("footer.php"); ?>
viewsource.php: Last Modified: 02/06/08@14:19:08 | Size: 2795 bytes | View Source Valid XHTML 1.1 Valid CSS