Question 3: Define a procedure, nucleotide-complement, that takes as input a single base represented by its symbol ('A, 'C, 'T, or 'G) and evaluates to the complement of that base.
(define (nucleotide-complement base) (if (eq? base 'A) 'T (if (eq? base 'T) 'A (if (eq? base 'G) 'C (if (eq? base 'C) 'G (error "Bad base: " base))))))
Now that you know the cond special form, there is a simpler way:
(define (nucleotide-complement base) (cond ((eq? base 'A) 'T) ((eq? base 'T) 'A) ((eq? base 'G) 'C) ((eq? base 'C) 'G) (else (error "Bad base: " base))))
Question 4: Define a procedure, sequence-complement, that takes as input a list of symbols representing a DNA sequence, and outputs a list of symbols that are the complement of that sequence.
(define (sequence-complement s) (list-map nucleotide-complement s))
Question 5: Define a procedure, count-matches, that takes as inputs a list and a value, and outputs the number of elements in the list that match the value. For example, (count-matches null 'A) should evaluate to 0 and (count-matches (list 'A 'C 'A 'T) 'A) should evaluate to 2. (Note: This is not actually useful for defining Hamming distance, but this question will give you practice with an easier recursive procedure before trying Hamming distance.)
(define (count-matches p b) (list-sum (map (lambda (v) (if (eq? v b) 1 0)) p)))
Question 6: Define a procedure, hamming-distance, that takes as inputs two lists and outputs the number of positions where the list elements are different. You may assume that both inputs are the same length (although it would be even better to define a procedure that does not assume this!). Here are some examples: (hamming-distance null null) ==> 0, (hamming-distance (list 'A 'C 'A 'T) (list 'A 'C 'T 'A)) ==> 2.
(define (hamming-distance p q) (if (null? p) (length q) (if (null? q) (length p) (+ (if (eq? (car p) (car q)) 0 1) (hamming-distance (cdr p) (cdr q))))))
Question 8: Define a procedure, edit-distance, that takes as input two lists and outputs the edit distance between those lists.
(define (edit-distance s1 s2) (if (or (null? s1) (null? s2)) (+ (length s1) (length s2)) (min (+ (if (eq? (car s1) (car s2)) 0 1) (edit-distance (cdr s1) (cdr s2))) (+ 1 (edit-distance s1 (cdr s2))) ; insert in s1 (+ 1 (edit-distance (cdr s1) s2)))))) ; delete from s1
Question 9: Define a procedure, memoized-edit-distance, that computes the edit distance efficiently using memoize to avoid re-computing redundant evaluations.
We do this by making a generalized-edit-distance procedure that takes a procedure as input which is the function used in the previously recursive calls.
(define (generalized-edit-distance f s1 s2) (if (or (null? s1) (null? s2)) (+ (length s1) (length s2)) (min (+ (if (eq? (car s1) (car s2)) 0 1) (f (cdr s1) (cdr s2))) (+ 1 (f s1 (cdr s2))) ; insert in s1 (+ 1 (f (cdr s1) s2))))) ; delete from s1 (define memoized-edit-distance (memoize (lambda (s1 s2) (generalized-edit-distance memoized-edit-distance s1 s2))))
You must be logged in to post a comment.