;;; File: ;;; index-of.ss ;;; Author: ;;; Samuel A. Rebelsky ;;; Version: ;;; 1.1 of 20 September 2006 ;;; Summary: ;;; Various implementations of the index-of procedure. ;;; History: ;;; At end. ; +--------------------+------------------------------------------------ ; | Primary Procedures | ; +--------------------+ ;;; Procedure: ;;; index-of-v1 ;;; index-of-v2 ;;; index-of-v3 ;;; Parameters: ;;; sym, a symbol ;;; lst, a list of symbols ;;; Purpose: ;;; Find the first index of sym in lst. ;;; Produces: ;;; index, a number ;;; Preconditions: ;;; (none) ;;; Postconditions: ;;; If sym appears in list, ;;; (index-of lst index) equals sym ;;; (index-of lst i) is not sym for all i < sym. ;;; If sym does not appear in list ;;; index is #f. (define index-of-v1 (lambda (sym lst) ; index-of-v1-helper adds a counter of the elements we've skipped over (index-of-v1-helper 0 sym lst))) (define index-of-v1-helper (lambda (skipped sym remaining) (cond ; If nothing remains, sym isn't there. ((null? remaining) #f) ; If the first symbol is sym, the index is the number ; of values we've skipped over ((eq? sym (car remaining)) skipped) ; Otherwise, skip over the current element and continue (else (index-of-v1-helper (+ 1 skipped) sym (cdr remaining)))))) (define index-of-v2 (lambda (sym lst) (cond ; If there are no elements in the list, sym can't be there ((null? lst) #f) ; If sym is the first element of the list, its index is 0. ((eq? sym (car lst)) 0) ; If sym appears at position p in the cdr, then it appears ; p+1 in the list. ((number? (index-of-v2 sym (cdr lst))) (+ 1 (index-of-v2 sym (cdr lst)))) ; Otherwise, sym does not appear in the list (else #f)))) (define index-of-v3 (lambda (sym lst) (cond ; If there are no elements in the list, sym can't be there ((null? lst) #f) ; If sym is the first element of the list, its index is 0. ((eq? sym (car lst)) 0) ; Otherwise, we find the index in the rest of the list. It ; is either at position p in the cdr, in which case the ; recursive call returns a number and we should add 1, or ; it is not in the cdr, in which case the recursive call returns #f ; and we should return #f (else (index-of-v3-helper (index-of-v3 sym (cdr lst))))))) (define index-of-v3-helper (lambda (index) (if (number? index) (+ 1 index) #f))) (define index-of-v3-helper-v2lt (lambda (index) (and index (+ 1 index)))) (define index-of index-of-v2) ; +---------+----------------------------------------------------------- ; | Testing | ; +---------+ (define check (lambda (testname found expected) (display testname) (display " ... ") (if (equal? expected found) (success found expected) (failure found expected)) (newline))) (define success (lambda (found expected) (display "OK"))) (define failure (lambda (found expected) (display "Failed. Expected ") (display expected) (display ", found ") (display found))) (define test-index-of (lambda () (check "(index-of-v1 'a null)" (index-of-v1 'a null) #f) (check "(index-of-v1 'a (list 'a))" (index-of-v1 'a (list 'a)) 0) (check "(index-of-v1 'a (list 'b 'a))" (index-of-v1 'a (list 'b'a)) 1) (check "(index-of-v1 'a (list 'b 'a 'a))" (index-of-v1 'a (list 'b 'a 'a)) 1) (check "(index-of-v1 'a (list 'b 'b 'b))" (index-of-v1 'a (list 'b 'b 'b)) #f) (check "(index-of-v2 'a null)" (index-of-v2 'a null) #f) (check "(index-of-v2 'a (list 'a))" (index-of-v2 'a (list 'a)) 0) (check "(index-of-v2 'a (list 'b 'a))" (index-of-v2 'a (list 'b'a)) 1) (check "(index-of-v2 'a (list 'b 'a 'a))" (index-of-v2 'a (list 'b 'a 'a)) 1) (check "(index-of-v2 'a (list 'b 'b 'b))" (index-of-v2 'a (list 'b 'b 'b)) #f) (check "(index-of-v3 'a null)" (index-of-v3 'a null) #f) (check "(index-of-v3 'a (list 'a))" (index-of-v3 'a (list 'a)) 0) (check "(index-of-v3 'a (list 'b 'a))" (index-of-v3 'a (list 'b 'a)) 1) (check "(index-of-v3 'a (list 'b 'a 'a))" (index-of-v3 'a (list 'b 'a 'a)) 1) (check "(index-of-v3 'a (list 'b 'b 'b))" (index-of-v3 'a (list 'b 'b 'b)) #f) )) ; +---------+----------------------------------------------------------- ; | History | ; +---------+ ; Tuesday, 19 September 2006 (v1.0) [Samuel A. Rebelsky] ; * Wrote first two versions of index-of. ; * Wrote tester. ; Wednesday, 20 September 2006 (v1.1) [Samuel A. Rebelsky] ; * Add a third version (using recursive helper), now named -v1. ; * Renamed procedures slightly. ; * Rearranged tester. ; * Added history.