;;appendTo: list-of-any any --> list-of-any ;; appends dat to the end of the list (define (appendTo a-list dat) (cond [(empty? a-list) (cons dat empty)] [(cons? a-list) (cons (first a-list) (appendTo (rest a-list) dat))])) "appendTo test cases:" (equal? (cons 'z empty) (appendTo empty 'z)) (equal? (list 42 'a) (appendTo (list 42) 'a)) (equal? (list 'a 'b 'c 'd) (appendTo (list 'a 'b 'c) 'd)) ;;appendList: list-of-any list-of-any --> list-of-any ;; appends list2 to the end of list 1. ;; If either list is empty, the other list is returned. (define (appendList list1 list2) (cond [(empty? list1) list2] [(cons? list1) (cons (first list1) (appendList (rest list1) list2))])) "appendList test cases:" (equal? empty (appendList empty empty)) (equal? (list 1 2) (appendList empty (list 1 2))) (equal? (list 3 4) (appendList (list 3 4) empty)) (equal? (list 'a 'b 'c 'd 'e) (appendList (list 'a 'b) (list 'c 'd 'e))) #| ;; Template #1 ;; f-2lists: list list --> ... (define (f-2lists list1 list2) (cond [(empty? list1) (f_empty_help list2)] [(cons? list1) (f_cons_help list1 list2)])) ;; f-empty_help: list --> ... (define (f-empty_help list2) (cond [(empty? list2) ...] [(cons? list2) ( ... (first list2)... (rest list2))])) ;; f-cons_help: cons cons --> ... (define (f-cons_help list1 list2) (cond [(empty? list2) (...(first list1)...(rest list1)...)] [(cons? list2) ( ...(first list1)...(rest list1)... (first list2)... (rest list2))])) |# #| ;; Template #2 (define (f-2lists list1 list2) (cond [(and (empty? list1)(empty? list2)) ...] [(and (cons? list1)(empty? list2)) ...] [(and (empty? list1)(cons? list2)) ...] [(and (cons? list1)(cons? list2)) ...])) |# ;; merge: list-of num list-of-num --> list-of-num ;; Takes two list-of-nums already sorted in descending order ;; and creates a new list with all the values of both lists combined ;; in descending order. (define (merge lon1 lon2) (cond [(empty? lon1) lon2] [(cons? lon1) (merge_help lon1 lon2)])) ;; merge_help: cons list-of-num --> list-of-num ;; Takes two list-of-nums already sorted in descending order ;; and creates a new list with all the values of both lists combined ;; in descending order. lon1 is assumed to be cons. ;; Merge_help only checks lon2 for empty/cons and thus uses merge to check both ;; lon1 and lon2 when needed. (define (merge_help lon1 lon2) (cond [(empty? lon2) lon1] [(cons? lon2) (cond [(> (first lon1) (first lon2)) (cons (first lon1) (merge (rest lon1) lon2))] [else (cons (first lon2) (merge lon1 (rest lon2)))])])) (define myList1 (list 5 4 1)) (define myList2 (list 6 3 )) "merge test cases:" (equal? empty (merge empty empty)) (equal? myList1 (merge myList1 empty)) (equal? myList2 (merge empty myList2)) (equal? (list 6 5 4 3 1) (merge myList1 myList2)) (equal? (list 6 5 4 3 1) (merge myList2 myList1)) ;;Alternative implementation of merge that uses a 4-way cond. (define (merge1 lon1 lon2) (cond [(and (empty? lon1)(empty? lon2)) empty] [(and (cons? lon1)(empty? lon2)) lon1] [(and (empty? lon1)(cons? lon2)) lon2] [(and (cons? lon1)(cons? lon2)) (cond [(> (first lon1) (first lon2)) (cons (first lon1) (merge1 (rest lon1) lon2))] [else (cons (first lon2) (merge1 lon1 (rest lon2)))])])) "merge1 test cases:" (equal? empty (merge1 empty empty)) (equal? myList1 (merge1 myList1 empty)) (equal? myList2 (merge1 empty myList2)) (equal? (list 6 5 4 3 1) (merge1 myList1 myList2)) (equal? (list 6 5 4 3 1) (merge1 myList2 myList1)) ;; Simplified merge1 implementation (define (merge1b lon1 lon2) (cond [(empty? lon1) lon2] [(empty? lon2) lon1] [else (cond [(> (first lon1) (first lon2)) (cons (first lon1) (merge1b (rest lon1) lon2))] [else (cons (first lon2) (merge1b lon1 (rest lon2)))])])) "merge1b test cases:" (equal? empty (merge1b empty empty)) (equal? myList1 (merge1b myList1 empty)) (equal? myList2 (merge1b empty myList2)) (equal? (list 6 5 4 3 1) (merge1b myList1 myList2)) (equal? (list 6 5 4 3 1) (merge1b myList2 myList1)) ;; make-tuples: list-of-any list-of-any --> list-of-list-any or symbol ;; Takes two lists and returns a single list ;; which consists of two element lists (tuples) consisting of the ;; corresponding pairs from the input lists. ;; If both input lists are empty, the result is an empty list. ;; If one list is longer than the other, the result is truncated at the shorter list. (define (make-tuples list1 list2) (cond [(empty? list1) empty] [(cons? list1) (make-tuples_help list1 list2)])) ;; list1 is known to be non-empty (define (make-tuples_help list1 list2) (cond [(empty? list2) empty] [(cons? list2) (cons (list (first list1) (first list2)) (make-tuples (rest list1) (rest list2)))])) "make-tuples test cases:" (equal? empty (make-tuples empty empty)) (equal? (list (list 'a 1) (list 'b 2)) (make-tuples (list 'a 'b) (list 1 2 3))) (equal? (list (list 1 'a) (list 2 'b)) (make-tuples (list 1 2 3) (list 'a 'b))) (equal? (list (list 1 'a) (list 2 'b) (list 3 'c)) (make-tuples (list 1 2 3) (list 'a 'b 'c))) (equal? (list (list 'Bart 1979) (list 'Homer 1955)(list 'Marge 1956)) (make-tuples (list 'Bart 'Homer 'Marge) (list 1979 1955 1956))) ;; make-tuples2: list-of-any list-of-any --> list-of-list-any or symbol ;; Takes two lists and returns a single list ;; which consists of two element lists (tuples) consisting of the ;; corresponding pairs from the input lists. ;; If both input lists are empty, the result is an empty list. ;; If one list is longer than the other, the result is truncated at the shorter list. (define (make-tuples2 list1 list2) (cond [(and (empty? list1)(empty? list2)) empty] [(and (cons? list1)(empty? list2)) empty] [(and (empty? list1)(cons? list2)) empty] [(and (cons? list1)(cons? list2)) (cons (list (first list1) (first list2)) (make-tuples2 (rest list1) (rest list2)))])) "make-tuples2 test cases:" (equal? empty (make-tuples2 empty empty)) (equal? (list (list 'a 1) (list 'b 2)) (make-tuples2 (list 'a 'b) (list 1 2 3))) (equal? (list (list 1 'a) (list 2 'b)) (make-tuples2 (list 1 2 3) (list 'a 'b))) (equal? (list (list 1 'a) (list 2 'b) (list 3 'c)) (make-tuples2 (list 1 2 3) (list 'a 'b 'c))) (equal? (list (list 'Bart 1979) (list 'Homer 1955)(list 'Marge 1956)) (make-tuples2 (list 'Bart 'Homer 'Marge) (list 1979 1955 1956))) ;; Simplified make-tuples -- assumes that list2 is not shorter than list1 (define (make-tuples3 list1 list2) (cond [(empty? list1) empty] [(cons? list1) (cons (list (first list1) (first list2)) (make-tuples3 (rest list1) (rest list2)))])) "make-tuples3 test cases:" (equal? empty (make-tuples3 empty empty)) (equal? (list (list 'a 1) (list 'b 2)) (make-tuples3 (list 'a 'b) (list 1 2 3))) ;;(equal? (list (list 1 'a) (list 2 'b)) (make-tuples3 (list 1 2 3) (list 'a 'b))) ;; Can't do this test! (equal? (list (list 1 'a) (list 2 'b) (list 3 'c)) (make-tuples3 (list 1 2 3) (list 'a 'b 'c))) (equal? (list (list 'Bart 1979) (list 'Homer 1955)(list 'Marge 1956)) (make-tuples3 (list 'Bart 'Homer 'Marge) (list 1979 1955 1956))) ;; unzip: list-of-any --> (cons list-of-any (cons list-of-any empty)) ;; takes a list and returns a list of two lists, which contain the alternate values ;; in the original list. (define (unzip a-list) (cond [(empty? a-list) (list empty empty)] [(cons? a-list) (unzip_help (rest a-list) empty (cons (first a-list) empty))])) ;; unzip_help: list-of-any list-of-any list-of-any --> (cons list-of-any (cons list-of-any empty)) ;; takes a list and returns a list of two lists, which contain the alternate values ;; in the original list. The alternating values are appended to the two accumulator lists ;; starting with acc1. (define (unzip_help a-list acc1 acc2) (cond [(empty? a-list) (list acc1 acc2)] [(cons? a-list) (unzip_help (rest a-list) acc2 (appendTo acc1 (first a-list)))])) "unzip test cases:" (equal? (list empty empty) (unzip empty)) (equal? (list empty (list 42)) (unzip (list 42))) (equal? (list (list 1 3 5 ) (list 2 4 6)) (unzip (list 1 2 3 4 5 6))) ;; A beautiful unzip implementation by Craig Fratrik: ;;a loa is: ;;- empty ;;- (cons ) ;;a tuple is: ;;(list ) ;;unzip2: loa --> tuple ;;unzip2 returns a list of two lists, with each having half of the members of the given list (define (unzip2 a-list) (cond [(empty? a-list) (list empty empty)] [(cons? a-list) (list (cons (first a-list) (second (unzip2 (rest a-list)))) (first (unzip2 (rest a-list))))])) "unzip2 test cases:" (equal? (list empty empty) (unzip2 empty)) (equal? (list (list 42) empty) (unzip2 (list 42))) (equal? (list (list 1 3 5 ) (list 2 4 6)) (unzip2 (list 1 2 3 4 5 6))) ;;second doesn't violate encapsulation because it is a tuple ;; Notice how the unzip2 function really describes a recursive definition of unzipping. ;; Notice that unzip and unzip2 aren't quite the same, that is, they don't have the same output for the same input. ;; mergesort: list-of-num --> list-of-num ;; sorts the list of num in descending order. (define (mergesort lon) (cond [(empty? lon) empty] [(cons? lon) (mergesort_help lon (rest lon) (first lon))])) (define (mergesort_help lon rest_lon dat) (cond [(empty? rest_lon) (list dat)] [(cons? rest_lon) (merge (mergesort (first (unzip lon))) (mergesort (first (rest (unzip lon)))))])) "mergesort test cases:" (equal? empty (mergesort empty)) (equal? (list 42) (mergesort (list 42))) (equal? (list 7 6 5 4 3 2 1 ) (mergesort (list 3 5 2 1 6 4 7))) ;; Alternative implementation of mergesort that simplifies the code by violating the encapasulation of rest. (define (mergesort2 lon) (cond [(empty? lon) empty] [(empty? (rest lon)) lon] [else (merge (mergesort2 (first (unzip lon))) (mergesort2 (first (rest (unzip lon)))))])) "mergesort2 test cases:" (equal? empty (mergesort2 empty)) (equal? (list 42) (mergesort2 (list 42))) (equal? (list 7 6 5 4 3 2 1 ) (mergesort2 (list 3 5 2 1 6 4 7)))