# EoPL Exercise 1.36

**URL:** <https://racket.discourse.group/t/eopl-exercise-1-36/3520>\
**Category:** Questions & Answers\
**Created:** [January 27, 2025, 10:45am UTC](https://racket.discourse.group/t/eopl-exercise-1-36/3520 "2025-01-27T10:45:29Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![matteo-daddio](https://yyz2.discourse-cdn.com/free1/user_avatar/racket.discourse.group/matteo-daddio/32/1245_2.png) [@matteo-daddio](https://racket.discourse.group/u/matteo-daddio)\
**Post date:** [January 27, 2025, 10:45am UTC](https://racket.discourse.group/t/eopl-exercise-1-36/3520/1 "2025-01-27T10:45:29Z")

</div>

Hello,

I’m reading EoPL and I’m stuck in the 1.36 exercise.

Write a procedure g such that number-elements from page 23 could be defined as:

```scheme
(define number-elements
  (lambda (lst)
    (if (null? lst) ’()
      (g (list 0 (car lst))
         (number-elements (cdr lst))))))

(number-elements ‘(a b c d))
=> ‘((0 a) (1 b) (2 c) (3 d))

```

I really can't figure out how to solve this problem. I tried with an imperative approach but it didn’t work.

Matteo

---

<div class="post-metadata">

**Author:** ![Antigen-11](https://yyz2.discourse-cdn.com/free1/user_avatar/racket.discourse.group/antigen-11/32/1813_2.png) [@Antigen-11](https://racket.discourse.group/u/Antigen-11)\
**Post date:** [January 27, 2025, 1:57pm UTC](https://racket.discourse.group/t/eopl-exercise-1-36/3520/2 "2025-01-27T13:57:43Z")

</div>

I'm not reading this book but I think I've found a solution.

```scheme
> (define (g r l)
    (cons r (map (lambda (e) (list (add1 (car e)) (cadr e))) l)))
> (define number-elements
      (lambda (lst)
        (if (null? lst) '()
          (g (list 0 (car lst))
             (number-elements (cdr lst))))))
> (number-elements '(a b c d a))
'((0 a) (1 b) (2 c) (3 d) (4 a))

```

---

<div class="post-metadata">

**Author:** ![benknoble](https://yyz2.discourse-cdn.com/free1/user_avatar/racket.discourse.group/benknoble/32/16_2.png) [@benknoble](https://racket.discourse.group/u/benknoble)\
**Post date:** [January 27, 2025, 6:02pm UTC](https://racket.discourse.group/t/eopl-exercise-1-36/3520/3 "2025-01-27T18:02:06Z")

</div>

I would take an equational approach: what must be true of `(g (list 0 (car lst)) (number-elements (cdr lst)))` when `lst` is `'(a)`? What about `'(a b)` or `'(a b c)`? Now generalize to `(cons x xs)`. You'll have to expand definitions; for `'(a)`, perhaps something like this

```scheme
  (number-elements '(a))
= (g (list 0 'a)
     (number-elements '()))
= (g '(0 a) '())
= ???
= '((0 a))

```

and for `'(a b)`

```scheme
  (number-elements '(a b))
= (g (list 0 'a)
     (number-elements '(b)))
= (g '(0 a)
     (g '(0 b) '()))
= ???
= '((0 a) (1 b))

```

That last example makes `g` look an awful lot like a `cons` operator that also does some counting/addition, doesn't it? Try again with 3 elements, and then see if you can generalize. You're looking for equations about `g` that have to be true, and then you can build an implementation that satisfies those requirements (if you have to guess at an implementation, it's a good idea to prove to yourself that it meets all the equational requirements). Don't forget the order of evaluation: in the last example, `(g '(0 b) '())` is evaluated before the outer call to `g`.

---

<div class="post-metadata">

**Author:** ![JustinZed](https://avatars.discourse-cdn.com/v4/letter/j/8e7dd6/32.png) [@JustinZed](https://racket.discourse.group/u/JustinZed)\
**Post date:** [January 27, 2025, 8:18pm UTC](https://racket.discourse.group/t/eopl-exercise-1-36/3520/4 "2025-01-27T20:18:13Z")

</div>

I have put together an explanation of how to go about solving this kind of problem. I wrote it as a literate program, and had hope to make it more readable, but GitHub is not displaying the Scribble output properly. You can find the Scribble source in raw form at [eopl-1.36.scrbl](https://gist.githubusercontent.com/zamora/52a15edceb7d812aa92aa07f66dfa9e0/raw/3e06b1cd8ac3e8bb7207977a0f68edfb3996b17f/eopl-1.36.scrbl).

Copy and paste the Scribble code into DrRacket, and click on "Scribble HTML" to generate the documentation. Click on "Run" to run the program.

[GitHub is eliminating the chunk names. If anyone is interested in exploring why GitHub doesn't like the Scribble output, let me know.]

---

<div class="post-metadata">

**Author:** ![JustinZed](https://avatars.discourse-cdn.com/v4/letter/j/8e7dd6/32.png) [@JustinZed](https://racket.discourse.group/u/JustinZed)\
**Post date:** [January 27, 2025, 8:27pm UTC](https://racket.discourse.group/t/eopl-exercise-1-36/3520/5 "2025-01-27T20:27:02Z")

</div>

For the impatient, here is the code of my solution. You can read the Scribble if you want to understand how I developed it.

```scheme
#lang racket

(define number-elements
  (lambda (lst)
    (if (null? lst)
        '()
        (g (list 0 (car lst))
           (number-elements (cdr lst))))))

(define g
  (lambda (first numbered-elements)
    (cons first (map (lambda (elt)
                       (cons (add1 (car elt)) (cdr elt)))
                     numbered-elements))))

```

Welcome to DrRacket, version 8.15 [cs].  
Language: racket, with debugging; memory limit: 4096 MB.

> (number-elements '(a b c d))  
> '((0 a) (1 b) (2 c) (3 d))
