# sicp-ex-2.17

```
;; 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)
```

jz

```
;; ex 2.17
(define (last-pair items)
(let ((rest (cdr items)))
(if (null? rest)
items
(last-pair rest))))

;; Test:
(last-pair (list 1 2 3 4))

```

asb

``` 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.

EcsCodes

``` 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.

AMS

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 '()) ;;= ()
```

Without error checking though.

``` (define (last-pair s)
(if (null? (cdr (cdr s)))
(cdr s)
(last-pair (cdr s))))
```

Daniel-Amariei

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)
```

Anonymous coward

Does the solution have to be recursive?

``` (define (last-pair inlist)
(list (list-ref inlist (- (length inlist) 1))))
```

anon

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
```

bmm

```
;; 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)
```