Skip to main content

CSC 151.01, Class 31: Numeric Recursion

Overview

  • Preliminaries
    • Notes and news
    • Upcoming work
    • Extra credit
    • Questions
  • Some review from yesterday
  • Lab

News / Etc.

  • New partners!

Rotating reminders

  • Visit review sessions! I run review sessions on Thursdays at 9am in this room.
    (If you are unable to make Friday’s class, take the quiz at the review session.)
  • Visit mentor sessions! We have mentor sessions on Thursday evening from 8:00-9:00 p.m. in the CS Commons.

Upcoming Work

  • Lab writeup: Exercise 3
  • Reading for Friday: Naming Local Procedures
  • No homework over break.
  • Friday’s quiz: Identify your classmates

Extra credit (Academic/Artistic)

Extra credit (Peer)

  • Singers Concerts during spring break.
    • If there is an admission fee, I will reimburse up to $20.
  • Baseball games during spring break (Arkansas & Alabama).
    • If there is an admission fee, I will reimburse up to $20.
  • Baseball games last weekend of spring break. (1 hour suffices; no more than two units for the weekend.)
  • Ultimate games during spring break in Myrtle Beach.

Extra credit (Misc)

Good things to do

Questions

Some notes from last class

Insert a line that prints that the procedure has been called, and how.

(define my-last
  (lambda (lst)
    (write (list 'last lst)) (newline)
    (if (null? (cdr lst))
        (car lst)
        (my-last (cdr lst)))))

Building tables for tail-recursive procedures

When you are thinking about how to write a tail-recursive procedure in which you have so-far and remaining, it can be helpful to make a table in which you keep track of what should happen at each step.

E.g., tally-odds: Count the number of odd integers that appear in a list.

Example: (tally-odds (list 'a 1 2 5 'b))`:

        tally-so-far    remaining
        0               (list 'a 1 2 5 'b)
          car is not odd  take the cdr
          keep the same
        0               (list 1 2 5 'b)
          car is odd      take the cdr
          increment by 1
        1               (list 2 5 'b)
          car is not odd  take the cdr
          keep the same
        1               (list 5 'b)
          car is odd      take the cdr
          increment by 1
        2               (list 'b)
          car is not odd  take the cdr
          keep the same
        2               (list)
          List is empty, return so-far

How do we actually write this?

(define tally-odds
  (lambda (lst)
    (tally-odds-helper ....)))

(define tally-odds-helper
  (lambda (tally remaining)
    (write (list 'tally-odds-helper tally remaining)) (newline)
    (cond 
      [(null? remaining)
       tally]
      [(and (number? (car remaining)) (odd? (car remaining)))
       (tally-odds-helper (increment tally) (cdr remaining))]
      [else
       (tally-odds-helper tally (cdr remaining))])))

Some design issues

#lang racket

(define iota
  (lambda (n)
    (iota-helper 0 n)))
(define iota-helper
  (lambda (start end)
    (if (>= start end)
        null
        (cons start (iota-helper (+ start 1) end)))))

(define smallest
  (lambda (lst)
    (display (list 'smallest lst)) (newline)
    (cond
      [(null? (cdr lst)) 
       (car lst)]
      [(< (car lst) (smallest (cdr lst)))
       (car lst)]
      [else
       (smallest (cdr lst))])))

(define minimal
  (lambda (lst)
    (if (null? (cdr lst))
        (car lst)
        (min (car lst) (minimal (cdr lst))))))

(define la
  (lambda (lol)
    (lala lol null)))

(define lala
  (lambda (remaining so-far)
    (if (null? remaining)
        so-far
        (lala (cdr remaining) (append so-far (car remaining))))))

(define example
  (lambda (lol)
    (time (la lol))
    1))

Output

> (smallest (iota 10))
(smallest (0 1 2 3 4 5 6 7 8 9))
(smallest (1 2 3 4 5 6 7 8 9))
(smallest (2 3 4 5 6 7 8 9))
(smallest (3 4 5 6 7 8 9))
(smallest (4 5 6 7 8 9))
(smallest (5 6 7 8 9))
(smallest (6 7 8 9))
(smallest (7 8 9))
(smallest (8 9))
(smallest (9))

Questionable output: Prediction

“We’ll call smallest twice, once for the test and once for the else.”

> (smallest (reverse (iota 5)))
(smallest (4 3 2 1 0))
(smallest (3 2 1 0))
(smallest (2 1 0))
...
(smallest (2 1 0))
(smallest (3 2 1 0))

Questionable output: Actual

> (smallest (reverse (iota 5)))
(smallest (4 3 2 1 0))
(smallest (3 2 1 0))
(smallest (2 1 0))
(smallest (1 0))
(smallest (0))
(smallest (0))
(smallest (1 0))
(smallest (0))
(smallest (0))
(smallest (2 1 0))
(smallest (1 0))
(smallest (0))
(smallest (0))
(smallest (1 0))
(smallest (0))
(smallest (0))
(smallest (3 2 1 0))
(smallest (2 1 0))
(smallest (1 0))
(smallest (0))
(smallest (0))
(smallest (1 0))
(smallest (0))
(smallest (0))
(smallest (2 1 0))
(smallest (1 0))
(smallest (0))
(smallest (0))
(smallest (1 0))
(smallest (0))
(smallest (0))
0

Lab

Sam’s favorite incorrect definition of my-iota.

(define my-iota
  (lambda (n)
    (if (<= n 0)
        null
        (reverse (cons (- n 1) (my-iota (- n 1)))))))
> (my-iota 10)
'(8 6 4 2 0 1 3 5 7 9)

Writeup

Write up exercise 3 from the lab on numeric recursion. You need not document my-iota or its helper(s).

Send your solution to csc151-01-grader@grinnell.edu.

Title your email CSC 151.01 Writeup for Class 31 (YOUR FULL NAMES).