(module chinese-zodiac mzscheme (require (lib "etc.ss")) ;; ranking->animal: number -> symbol ;; Given a ranking from 0-11, returns the corresponding animal. (define (ranking->animal ranking) (cond [(= ranking 0) 'Rat] [(= ranking 1) 'Ox] [(= ranking 2) 'Tiger] [(= ranking 3) 'Rabbit] [(= ranking 4) 'Dragon] [(= ranking 5) 'Snake] [(= ranking 6) 'Horse] [(= ranking 7) 'Goat] [(= ranking 8) 'Monkey] [(= ranking 9) 'Rooster] [(= ranking 10) 'Dog] [(= ranking 11) 'Pig] [else (error 'ranking->animal "Illegal ranking ~a" ranking)])) ;; animal->ranking: symbol -> number ;; Given an animal, returns the corresponding rank. (define (animal->ranking an-animal) (define (loop i) (cond [(symbol=? an-animal (ranking->animal i)) i] [else (loop (add1 i))])) (loop 0)) ;; emmity: symbol -> symbol ;; Given an-animal, returns the name of its greatest enemy. (define (emmity an-animal) (ranking->animal (modulo (+ 6 (animal->ranking an-animal)) 12))) ;; An affinity-pair is a structure ;; (make-affinity-pair a1 a2) ;; where a1 and a2 are animals. (define-struct affinity-pair (first-animal second-animal) #f) ;; affinities: symbol -> affinity-pair ;; Returns an affinity-pair of the animals with the strongest affinity ;; to an-animal. (define (affinities an-animal) (make-affinity-pair (ranking->animal (modulo (+ (animal->ranking an-animal) 4) 12)) (ranking->animal (modulo (- (animal->ranking an-animal) 4) 12)))) )