Warning! You are being recorded and transcribed, provided the technology is working correctly.
Approximate optimistic overview
Scholarly
Artistic
Multicultural
Peer
Musical, theatric, sporting, and academic events involving this section’s students are welcome.
Wellness
Misc
These do not earn tokens, but are worth your consideration.
let
and let*
)See your notes or the recording.
func1a
;;; (func-1a x lst) -> list-of anything?
;;; x : any?
;;; lst : list-of anything?
;;; Creates a new list consisting of the elements of `lst` with `x`
;;; added to the end.
(define func-1a
(lambda (x lst)
(if (null? lst)
(list x)
(cons (car lst) (func-1a x (cdr lst))))))
func1b
;;; (func-1b lst1 lst2) -> list?
;;; lst1 : list?
;;; lst2 : list?
;;; Constructs a new list all the elements of list 1 followed by all the
;;; elements of lst2.
(define func-1b
(lambda (lst1 lst2)
(if (null? lst1)
lst2
(cons (car lst1) (func-1b (cdr lst1) lst2)))))
> (test-equal? "simple test" (func1b '(1 2 3) '(4 5 6)) '(1 2 3 4 5 6))
func2a
;;; (func-2a x lst) -> list?
;;; x : any?
;;; lst : list-of any?
;;; Remove all values equal to x
(define func-2a
(lambda (x lst)
(if (null? lst)
null
(if (equal? (car lst) x)
(func-2a x (cdr lst))
(cons (car lst) (func-2a x (cdr lst)))))))
(test-equal? "the value to remove is first" (func-2a 1 '(1 2 3)) '(2 3))
(test-equal? "value to remove in middle" (func-2a 2 '(1 2 3 4)) '(1 3 4))
(test-equal? "empty list" (func-2a "um" '()) '())
(test-equal? "not in list" (func-2a 5 '(1 2 3)) '(1 2 3))
(test-equal? "wawa" (func-2a 'wa (make-list 10 'wa)) '())
(test-equal? "string in middle" (func-2a "two" '(1 "two" 3 4)) '(1 3 4))
(test-equal? "value to remove at end" (func-2a 'd '(a b c d)) '(a b c))
(test-equal? "multiple copies"
(func-2a 'wa '(wa ter wa sh wa rn wa ck wa llaby))
'(ter sh rn ck llaby))
func2b
;;; (func-2b lst1 lst2) -> list?
;;; lst1 : list?
;;; lst2 : list?
;;; The concatenation of `lst2` and `lst1`.
;;; The concatenation of (the reverse of `lst2`) and `lst1`.
(define func-2b
(lambda (lst1 lst2)
(if (null? lst2)
lst1
(func-2b (cons (car lst2) lst1) (cdr lst2)))))
r
; reverse `lst`
(define r
(lambda (lst)
(func-2b '() lst)))
Tests for tally-odd
Tests for alphabetically-first
?
At least four versions. We’re going to explore them a bit. But first, some documentation and tests.
;;; (alphabetically-first words) -> string?
;;; words : list-of string?
;;; Find the alphabetically first string in `words`, using
;;; string-ci<=? for comparison.
What about our tests? (TPS)
Okay, on to our first version.
(define alphabetically-first-a
(lambda (lst)
(if (= 1 (len lst))
(car lst)
(if (string-ci<=? (car lst) (alphabetically-first-a (cdr lst)))
(car lst)
(alphabetically-first-a (cdr lst))))))
Hmmm … Sam says that when we repeat code, we should use a let
binding.
What’s repeated here?
(define alphabetically-first-b
(lambda (lst)
(if (= 1 (len lst))
(car lst)
(let ([first-of-rest (alphabetically-first-b (cdr lst))])
(if (string-ci<=? (car lst) first-of-rest)
(car lst)
first-of-rest)))))
Hmmm … Sam said something about how to check for one-element lists. How do we update that code.
(define alphabetically-first-c
Does it make a difference? We’ll start by defining a variety of values.
(define nums10 (map number->string (range 10)))
(define nums20 (map number->string (range 20)))
(define rev20 (reverse nums20))
(define nums22 (map number->string (range 22)))
(define rev22 (reverse nums22))
(define nums25 (map number->string (range 25)))
(define rev25 (reverse nums25))
(define nums30 (map number->string (range 30)))
(define rev30 (reverse nums30))
(define nums100 (map number->string (range 100)))
(define nums1000 (map number->string (range 1000)))
(define nums10000 (map number->string (range 10000)))
(define nums20000 (map number->string (range 20000)))
(define nums40000 (map number->string (range 40000)))
And some experiments with those. First we’ll look at version a.
Let’s compare version b.
And on to version c
Here’s another approach.
(define alphabetically-first-d
(lambda (lst)
(if (= 1 (len lst))
(car lst)
(if (string-ci<=? (car lst) (cadr lst))
(alphabetically-first-d (cons (car lst) (cddr lst)))
(alphabetically-first-d (cdr lst))))))
And here’s that same approach with a more sensible “does it have one item?”
(define alphabetically-first-e
(lambda (lst)
(if (null? (cdr lst))
(car lst)
(if (string-ci<=? (car lst) (cadr lst))
(alphabetically-first-e (cons (car lst) (cddr lst)))
(alphabetically-first-e (cdr lst))))))
And yes, it makes a difference.
> (time (alphabetically-first-d nums10000))
???
> (time (alphabetically-first-d nums40000))
???
> (time (alphabetically-first-e nums40000))
???
Here’s another approach, one based on largest
.
(define largest
(lambda (numbers)
(if (null? (cdr numbers))
(car numbers)
(max (car numbers) (largest (cdr numbers))))))
(define alphabetically-first-f
(lambda (words)
(if (null? (cdr words))
(car words)
(alphabetically-first-of-two (car words)
(alphabetically-first-f (cdr words))))))
(define alphabetically-first-of-two
(lambda (str1 str2)
(if (string-ci<=? str1 str2)
str1
str2)))
(define alphabetically-first-g
(lambda (words)
(afg-helper (car words) (cdr words))))
(define afg-helper
(lambda (word remaining)
(if (null? remaining)
word
(afg-helper (alphabetically-first-of-two word (car remaining))
(cdr remaining)))))
TPS: Which do you prefer (c, e, f, or g)? Why?
We’ll also do these as TPS.
I’ll ask for documentation, then tests, then code.
grab
Like take
, but still works if we try to grab more elements than there are.
(in that case, it just returns what’s there).
skip
Like drop
, but still works if we try to skip more elements than there are.
(merge-alternating lst1 lst2)
Alternately grab elements from the two lists, which may have different lengths. When we run out of one, grab from the other.