Comp210 Lecture # 10    Spring 2003

Finish discussion of mixed data

numbers au naturel

During the twelve days of christmas, we might be wondering how many items our true love gave us, on the nth day. Let's write a function which takes in a natural number n, and returns the sum of the first n numbers. (Sometimes called the nth triangular number -- think of arranging pennies on a table, into triangles.)

Hmmm, before writing code about natural numbers, let's be sure we're exactly clear on what the defintion of a natural number is. Well, ask any 7-year-old: it's 0, 1, 2, 3, ..., 29, 30, 31, .... But as a definition, this suffers from the ol' dot-dot-dot flaw: what explicitly is the pattern? Here's a hint (-:
0, (add1 0), (add1 (add1 0)), (add1 (add1 (add1 0))), ...
Admittedly, in everday life, we've given given shortened names to these things after 0, but mathematicians consider the natural number in this sense. (Some texts use "natural numbers" as starting from 1 and "whole numbers" as starting from 0; for our purposes, we'll consider zero as natural :-) Formally:

; A NatNum is:
;   - 0, or
;   - (add1 NatNum)
(Note: How do mathematicians prove things about all natural numbers? They use induction: prove something about 0, and then prove that add1 preserves the desired property; voila. Actually, when proving things about all lists, or all recipes, ... we generalize induction to structural induction. Take comp280 for details :-).

If add1 constructs new natNums, how do we tear apart a given non-zero natNum, to find the smaller natNum it's based on? Yes: sub1. (Of course, use (+ .. 1) and (- .. 1) if you prefer.)

What is the template for natural numbers?

 

 

 

 

 

Template for Natural Numbers


(define (f-natnum n)
    (cond 
         [(zero? n) ....]
         [else ...n... (f-natnum (sub1 n))]))   ;; could use (< 0 n) too
		 
Now (in a different color pen) go back and fill in the template, to get the code for (given n) computing the sum of the first n numbers: n + (n-1) + (n-2) ... + 2 + 1.

To think about: how many presents did our true love give us overall? (This is the sum of the first n triangular numbers, sometimes referred to as the nth pyramidal number -- think of arranging a pyramid of cannonballs.)

How about the product of the first n numbers (some times referred to as "n!").


;; (! n): natNum --> num
;; Given n, return n*(n-1)*...*2*1.
;;
(define (! n)
    (cond [(zero? n) ...]
        [else  ..(! (sub1 n))..]))

; Test cases
;
(= 2 (! 2))

(= 6 (! 3))


(! 0)
; ??? what should this be?
Think of attaching thought-bubbles to various parts of the code: Taking some concrete input (say, n = 23), What is (sub1 n)? How about (! (sub1 n))?

Mathematically, !0 is the number such that !1 = 1 * !0 = 1. This is the identity function. Thus, !0 must = 1.

This is the same argument for what the sum of an empty list of number is: (sum (cons 1 empty) = 1 + (sum empty) = 1 --> thus (sum empty) = 0.
And also the product of a list of numbers: (prod (cons 1 empty) = 1 *(sum empty) = 1 --> thus (prod empty) = 1.

 

 

 

 

Consider this function:

;; rabbits: natnum num --> num
;; calculates the number of rabbits after n breeding cycles ;; assuming that each rabbit has b offspring on average
;; Start with 2 rabbits ;; Assume no deaths. (define (rabbits n b) (cond [(zero? n) ...] [else ..(rabbits (sub1 n) b)..])) "Rabbits test cases:" (= 2 (rabbits 0 2)) (= 4 (rabbits 1 1)) (= 8 (rabbits 1 3)) (= 6250 (rabbits 5 4))

Solutions to the above code can be found here: lec10.scm

In lab today, you will write some functions on natural numbers that return lists. Will this be any different that any other recursive functions we've written to return lists?

 

At home:

 

Written by Ian Barland

 

©2003 Stephen Wong