``` Subject: Re: 3:rd solution sought From: rpw3@rigden.engr.sgi.com (Rob Warnock) Date: 1997/12/10 Newsgroups: comp.lang.scheme Message-ID: <66lb8t\$6pj2f@fido.asd.sgi.com> ```
```
Bengt Kleberg <bengtk@damek.kth.se> wrote:
+---------------
| Note that the real problem demands ... the use of (cons ..) in the
| construction of the _list_ of results. Ie, don't use an accumulator to
| make that part of the code tail-recursive. As you can see it is ok to use
| an accumulator for _one_ of the results.
| The toy example: Given a list '( 1 1 1 0 1 1 1 1 1 0 1 1 1 0 1 1 0) I want
| to get a result like this '(3 5 3 2). Ie, add the ones until you reach a 0,
| then start anew.
+---------------

Interesting coincidence! Just last night I had occasion to write some code
(as part of a small assembler for a weird RISC) that does something almost
identical, except the sub-results needed to be lists, too. That is, assuming
"0" is the magic delimiter and given a list '(1 2 3 0 5 0 5 2 1), return
((1 2 3) (5) (5 2 1)).  My solution was one tail-recursive routine, inside
a driver that special-cased null input:

(define MAGIC-TOKEN 0)                      ; or whatever
(define (DELIM-TEST x) (eq? x MAGIC-TOKEN)) ; or equal? or whatever

(define (gather-between-delims ls)
(letrec ((gather
(lambda (result partial input)
(cond
((null? input)
(reverse (cons (reverse partial) result)))
((DELIM-TEST (car input))
(gather (cons (reverse partial) result) '() (cdr input)))
(else
(gather result (cons (car input) partial) (cdr input)))))))
(if (null? ls)
ls
(gather '() '() ls))))

Examples:

(gather-between-delims '(1 2 3 0 5 0 4 2 1))
==> ((1 2 3) (5) (4 2 1))

(gather-between-delims '(1 1 1 0 1 1 1 1 1 0 1 1 1 0 1 1 0))
==> ((1 1 1) (1 1 1 1 1) (1 1 1) (1 1) ())

You can get Kleberg's "summation" result with:

(map length (gather-between-delims '(1 1 1 0 1 1 1 1 1 0 1 1 1 0 1 1 0)))
==> (3 5 3 2 0)

Though note that I deliberately chose not to suppress the empty list/count
at the end, since it was significant in my application.

-Rob

p.s. You can see what I was using it for if you replace "0" with ",",
and replace single-digit numbers with various other tokens (and add
a lexer to produce them):

(define MAGIC-TOKEN #\,)

(gather-between-delims
==> ((t3) (a0 #\+ 1) (tbl_end #\- tbl_beg #\+ 1))

Now all I need is to map a simple "infix->prefix" over that, and:

==> (t3 (+ a0 1) (+ (- tbl_end tbl_beg) 1))

-----
Rob Warnock, 7L-551		rpw3@sgi.com   http://reality.sgi.com/rpw3/
Silicon Graphics, Inc.		Phone: 650-933-1673 [New area code!]
2011 N. Shoreline Blvd.		FAX: 650-933-4392
Mountain View, CA  94043	PP-ASEL-IA

```