<< Previous exercises (2.14-2.15-2.16) | Index | Next exercise (2.18) >>
;; ex-2.17 (define (last-pair items) (let ((rest (cdr items))) (if (null? rest) items (last-pair rest)))) ;; Testing (last-pair (list 23 72 149 34)) ; (34)
solution which doesn't fail for '() (define (last-pair items) (define (iter items result) (if (null? items) result (iter (cdr items) items))) (iter items items))
A lot of people here concern such a conner case that the list is empty, but the exercise dictates conversely:
> Define a procedure last-pair that returns the list that contains only the last element of a given (**nonempty**) list:
Speaking of it, I cannot imagine what the last element is while the list is empty exactly. It is contradictory that an empty list contains an empty list as its latest element inside.
A simple but ingenious code
(define(lastPair L)
(if(=(length L)1) (car L)
(lastPair (cdr L))))
same as EcsCodes, but passes test for empty list (define (last-pair items) (if (< (length items) 2) items (last-pair (cdr items))))
;; ex 2.17 (define(lastPair L) (define (ref lst x) (if(= x 0) (car lst) (ref (cdr lst) (- x 1)))) (if(=(length L)1) (car L) (cons (ref L (- (length_ L) 2)) (cons (ref L (- (length_ L) 1)) '()) ) ) )
I think using (length L) repeatadly is not a good idea (unless your length is O(1), but the implementation in the book is O(n)) because it makes lastPair do n! length-iter on the list, its rest, the rest of the rest... where n is the size of the items list.
You understood the exercise wrongly. Here pair only has one element although it sounds a bit weird.
The answer was meant to return the last item of a list as a list. So you must modify the return value to return a list.
(define (last-pair l) (cond ((null? l) l) ((null? (cdr l)) (list (car l))) (else (last-pair (cdr l))))) ;; test (last-pair (list 23 72 149 34)) ;;= (34) (last-pair '()) ;;= ()
Regarding the first solution. We need to return a list, not a particular element. 1 != '(1)
;; returns the list that contains the last element ;; of a given non-empty list (define (last-pair L) (if (null? (cdr L)) L (last-pair (cdr L)))) (last-pair (list 1)) ;; '(1) (last-pair (list 1 2)) ;; '(2) (last-pair (list 1 2 3)) ;; '(3) (last-pair (list 1 2 3 4)) ;; '(4)
Does the solution have to be recursive?
(define (last-pair inlist)
(list (list-ref inlist (- (length inlist) 1))))
racket with contracts
(define/contract (last-pair items) (->i ([items list?]) #:pre (items) (not (null? items)) [_ list?]) (if (null? (cdr items)) items (last-pair (cdr items)))) (check-equal? (last-pair (list 23 72 149 34)) '(34)) (last-pair '()) ; contract violation
;; ex 2.17 (define nil '()) ;; procedure for length of list (define length (lambda (list) (if (null? list) 0 (+ 1 (length (cdr list)))))) ;; list-ref (define list-ref (lambda (list n) (if (= n 0) (car list) (list-ref (cdr list) (- n 1))))) ;; last-pair procedure (define last-pair (lambda (list) (if (null? list) nil (let ((s (- (length list) 1))) (cons (list-ref list s) nil))))) ;; Testing (last-pair (list 1 2 3 4 5 6 7 8 9)) ;; '(9)
jz