Functional Problem Solving (CSC 151 2015F) : EBoards
Primary: [Front Door] [Schedule] - [Academic Honesty] [Disabilities] [Email] - [FAQ] [Teaching & Learning] [Grading] [Taking Notes] [Rubric] [Remote Access]
Current: [Assignment] [EBoard] [Lab] [Outline] [Reading]
Sections: [Assignments] [EBoards] [Labs] [Outlines] [Readings] - [Examples] [Handouts]
Reference: [Setup] [VM] [Errors] - [Functions A-Z] [Functions By Topic] - [Racket] [Scheme Report (R5RS)] [R6RS] [TSPL4]
Related Courses: [Curtsinger (2015F)] [Davis (2013F)] [Rebelsky (2015S)] [Weinman (2014F)]
Misc: [Submit Questions] - [SamR] [Glimmer Labs] [CS@Grinnell] [Grinnell] - [Issue Tracker (Course)]
Overview
Two minutes with partner:
Key Ideas:
When is it useful to have a helper function? Here's an example: Sum
Often makes it easier to think about solving the problem. Also other issues that we'll discuss in a few minutes.
(define sum
(lambda (lst)
(sum-kernel lst 0)))
(define sum-kernel
(lambda (lst running-sum)
(if (null? lst)
running-sum
(sum-kernel (cdr lst) (+ (car lst) running-sum)))))
What kinds of parameters can you use for recursion? Can you just do recursion on lists?
We can do recursion on all sorts of things. You'll learn about recursion with numbers tonight!
Why does helper recursion give us lists backwards?
(define select-odd-1
(lambda (lst)
(cond
[(null? lst)
null]
[(odd? (car lst))
(cons (car lst)
(select-odd-1 (cdr lst)))]
[else
(select-odd-1 (cdr lst))])))
(define select-odd-2
(lambda (lst)
(select-odd-kernel lst null)))
(define select-odd-kernel
(lambda (lst odds-so-far)
(cond
[(null? lst)
odds-so-far]
[(odd? (car lst))
(select-odd-kernel (cdr lst)
(cons (car lst) odds-so-far))]
[else
(select-odd-kernel (cdr lst)
odds-so-far)])))
(select-odd-2 '(5 2 1 3 4 7))
-> (select-odd-kernel '(5 2 1 3 4 7) null)
-> (select-odd-kernel '(2 1 3 4 7) '(5))
-> (select-odd-kernel '(1 3 4 7) '(5))
-> (select-odd-kernel '(3 4 7) '(1 5))
-> (select-odd-kernel '(4 7) '(3 1 5))
-> (select-odd-kernel '(7) '(3 1 5))
-> (select-odd-kernel '() '(7 3 1 5))
-> '(7 3 1 5)
Can we do the non-helper version?
(define select-odd-1
(lambda (lst)
(cond
[(null? lst)
null]
[(odd? (car lst))
(cons (car lst)
(select-odd-1 (cdr lst)))]
[else
(select-odd-1 (cdr lst))])))
(select-odd-1 '(3 4 1 2 5))
-> (cons (car '(3 4 1 2 5)) (select-odd-1 (cdr '(3 4 1 2 5))))
-> (cons 3 (select-odd-1 (cdr '(3 4 1 2 5))))
-> (cons 3 (select-odd-1 '(4 1 2 5)))
-> (cons 3 (select-odd-1 (cdr '(4 1 2 5))))
-> (cons 3 (select-odd-1 '(1 2 5)))
-> (cons 3 (cons (car '(1 2 5)) (select-odd-1 (cdr '(1 2 5)))))
-> (cons 3 (cons 1 (select-odd-1 '(2 5))))
-> (cons 3 (cons 1 (select-odd-1 (cdr '(2 5)))))
-> (cons 3 (cons 1 (select-odd-1 '(5))))
-> (cons 3 (cons 1 (cons (car '(5)) (select-odd-1 (cdr '(5))))))
-> (cons 3 (cons 1 (cons 5 (select-odd-1 null))))
-> (cons 3 (cons 1 (cons 5 null)))
-> (cons 3 (cons 1 '(5)))
-> (cons 3 '(1 5))
-> '(3 1 5))
When we use helpers with lists, should we reverse them at the end?
Probably. It depends on the goals of the procedure.
(define select-odd-2
(lambda (lst)
(reverse (select-odd-kernel lst null))))
(define select-odd-kernel
(lambda (lst odds-so-far)
(cond
[(null? lst)
odds-so-far]
[(odd? (car lst))
(select-odd-kernel (cdr lst)
(cons (car lst) odds-so-far))]
[else
(select-odd-kernel (cdr lst)
odds-so-far)])))
If the goal was to reverse, then probably not
Why is (and) #t and (or) #f?
(or ...)is #t if any of its parameters are true.
(or ...)is false otherwise. None of the parameters to(or)is true.
(and ...)is #f if any of its parameters are false.(and ...)is #t (or truish) otherwise. None of the parameters to(and)are false. So it must be true.
Two minutes with partner:
What are two ways we can fix it?
(define irgb-brightest
(lambda (colors)
(cond
[(null? (cdr colors))
(car colors)]
[(>= (irgb-brightness (car colors))
(irgb-brightness (irgb-brightest (cdr colors))))
(car colors)]
[else
(irgb-brightest (cdr colors))])))
What's wrong?
How to fix?
Not done. Please read over and send questions!