;; ------------------------------------------------------------------------ ;; | | ;; | FILE : self-verifying-numbers.rkt | ;; | AUTHOR : Eugene Wallingford | ;; | CREATION DATE : January 28, 1998 | ;; | | ;; | DESCRIPTION : The functions in this file use the ideas on | ;; | higher-order functions in Session 5 to | ;; | several kinds of self-verifying numbers. | ;; | | ;; | REQUIRES : None. | ;; | | ;; ------------------------------------------------------------------------ ;; | | ;; | MODIFIED BY : Eugene Wallingford | ;; | DATE : January 26, 2004 | ;; | DATE : January 23, 2007 | ;; | DATE : February 5, 2019 | ;; | DESCRIPTION : Cosmetic changes to format and documentation. | ;; | | ;; ------------------------------------------------------------------------ #lang racket ;; This function works operates on the digits of a UPC bar code. (define UPC-f (lambda (digit pos) (if (zero? (modulo pos 2)) (* 3 digit) digit))) ;; valid-UPC? returns true if its argument is a legal UPC bar code, ;; based on the modular sum algorithm described in the reading. (define valid-UPC? (lambda (list-of-digits) (zero? (modulo (apply + (counted-map UPC-f list-of-digits)) 10)))) ;; A first cut at valid-ISBN?, following the same approach: (define ISBN-f (lambda (digit pos) (* digit (+ 1 pos)))) (define valid-ISBN? (lambda (list-of-digits) (zero? (modulo (apply + (counted-map ISBN-f list-of-digits)) 11)))) ;; A better solution: factor the validation algorithm into a function ;; that generates validators, parameterized on *f* and *m*. Then ;; define the validation functions by calling make-validator. (define make-validator (lambda (f m) ;--------------------------------------------------------- (lambda (list-of-digits) (zero? (modulo (apply + (counted-map f list-of-digits)) m))) ;--------------------------------------------------------- )) ;; (define valid-UPC? ;; (make-validator UPC-f 10)) ;; ;; (define valid-ISBN? ;; (make-validator ISBN-f 11)) ;; ----------------------------------------------------------------------- ;; HELPER FUNCTION: counted-map maps function f over list-of-numbers lon ;; ;; It differs from map by passing both an element from lst ;; and the 0-based position of that element in lst. ;; ;; We will discuss programming techniques for writing this sort of ;; recursive function beginning next week. ;; ----------------------------------------------------------------------- (define counted-map (lambda (f lst) (counted-map-helper f lst 0))) (define counted-map-helper (lambda (f lst pos) (if (null? lst) '() (cons (f (car lst) pos) (counted-map-helper f (cdr lst) (+ pos 1)))))) ;; ------------ ;; END OF FILE! ;; ------------