list homework problems

Write functions that maintain sets, keep count, and find indices.

``` \$ cat hw.rkt
#lang racket

(require srfi/1)

; Return a copy of the given list; the copy contains the
; given element.  The given list is assumed to be sorted
; in strictly ascending order, as will be the copy.

(define (as l)
(if (null? l)
(list e)
(let ((hd (car l)))
(cond
((char<? e hd)
(cons e l))
((char=? e hd)
l)
(#t
(cons hd (as (cdr l))))))))

(as l))

; Return a copy of the given list; the copy contains the
; given element.  The given list is assumed to be sorted
; in strictly ascending order, as will be the copy.

(let as ((unsearched l) (searched '()))
(if (null? unsearched)
(reverse (cons e searched))
(let ((hd (car unsearched)))
(cond
((char<? e hd)
(append (reverse searched) (cons e unsearched)))
((char=? e hd)
(append (reverse searched) unsearched))
(#t
(as (cdr unsearched) (cons hd searched))))))))

(define (list-index l e [eq? eq?])

; Return the index of the left-most occurrence of the
; given element in the given list, or -1 if the given
; element doesn't appear in the given list.

(let loop ((l l) (i 0))
(cond
((null? l)
-1)
((eq? (car l) e)
i)
(#t
(loop (cdr l) (+ i 1))))))

(define (list-index-cc l e [eq? eq?])

; Return the index of the left-most occurrence of the
; given element in the given list, or -1 if the given
; element doesn't appear in the given list.

(call-with-current-continuation
(lambda (k)
(fold (lambda (le i)
(if (eq? le e) (k i) (+ i 1)))
0
l)
-1)))

(define (update-count l k)

; Return a copy of the list of (key . count) pairs l.  If
; (k . c) appears in l, it is replaced in the copy by (k
; . c + 1); if no pair in l has key k, (k . 1) appears in
; the copy.

(let uc ((l l))
(if (null? l)
(list (cons k 1))
(let ((hd (car l))
(tl (cdr l)))
(if (eq? (car hd) k)
(cons (cons k (+ 1 (cdr hd))) tl)
(cons hd (uc tl)))))))

(define (update-count-tr l k)

; Return a copy of the list of (key . count) pairs l.  If
; (k . c) appears in l, it is replaced in the copy by (k
; . c + 1); if no pair in l has key k, (k . 1) appears in
; the copy.

(let uc ((unsearched l) (searched '()))
(if (null? unsearched)
(cons (cons k 1) searched)
(let ((hd (car unsearched))
(tl (cdr unsearched)))
(if (eq? (car hd) k)
(append searched (cons (cons k (+ 1 (cdr hd))) tl))
(uc tl (cons hd searched)))))))

(require rackunit "utl.rkt")

(define (run-tests as li uc str)

(let*
((N 10)
(nums (iota N)))

(do ((i 0 (+ i 1))) ((= i N) #t)
(check-eq? (li nums i) i))
(check-eq? (li nums N) -1)
(check-eq? (li '() 0) -1))

(let*
((chars (string->list str))
(char-set (fold (lambda (e l) (as l e)) '() chars))
(counts (fold (lambda (e l) (uc l e)) '() chars))
(N (length counts)))

(check-eq? (length char-set) N)
(check-eq?
(fold (lambda (e cnt) (+ (cdr e) cnt)) 0 counts)
(string-length str))

(let loop ((lst char-set))
(unless (null? lst)
(let ((fst (car lst))
(rst (cdr lst)))
(check-eq? (li rst fst) -1)
(loop rst))))

(for-each
(lambda (ch)
(let ((i (li counts ch (lambda (e x) (eq? (car e) x)))))
(check-true (and (< -1 i) (< i N)))))
char-set)))

(for-each
(lambda (s)