#lang racket (provide 2nd-max) ;; ------------------------------------------------------------------- ;; A recursive solution, with the choices among the cases made ;; explicitly using a cond expression. It is O(n), with one pass. (define (2nd-max lon) (2nd-max-tr (max (first lon) (second lon)) (min (first lon) (second lon)) (rest (rest lon)))) (define (2nd-max-tr largest 2nd-largest lon) (if (null? lon) 2nd-largest (cond ((> (first lon) largest) (2nd-max-tr (first lon) largest (rest lon))) ((> (first lon) 2nd-largest) (2nd-max-tr largest (first lon) (rest lon))) (else (2nd-max-tr largest 2nd-largest (rest lon)))))) ;; ------------------------------------------------------------------- ;; This is a tail-recursive version of the helper function. ;; It is more functional and a bit more elegant, ;; with a single recursive call in the else clause. ;; It uses functions to compute the new arguments to pass, ;; rather than a cond expression. ;; (define (2nd-max-tr largest 2nd-largest lon) ;; (if (null? lon) ;; 2nd-largest ;; (2nd-max-tr ;; (max largest (first lon)) ;; (max 2nd-largest (min largest (first lon))) ;; (rest lon)))) ;; ------------------------------------------------------------------- (require rackunit) (check-equal? (2nd-max '(2 3)) 2) (check-equal? (2nd-max '(2 -1)) -1) (check-equal? (2nd-max '(2 3 8 6 6 75 38 3 2)) 38) (check-equal? (2nd-max '(6 1 2 -3 9 4 -1 2 8 1 2 4)) 8) ;; -------------------------------------------------------------------