Here's my shot using generators. It's probably much slower than yours due to all the continuation jumps. This way keeps all four states in your "state machine" in one place.
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; (require racket/generator) (define (list-of-ranges-of-ones v) (define vec (append (vector->list v) '(0))) (sequence->list (in-generator (for/fold ([in-ones? #f]) ([elt (in-list vec)] [index (in-naturals)]) (cond [(and (zero? elt) in-ones?) ; Stop! Yield the list (yield (list in-ones? (sub1 index))) #f] [(and (zero? elt) (not in-ones?)) ; Keep stopping #f] [(and (not (zero? elt)) in-ones?) ; Keep going in-ones?] [(and (not (zero? elt)) (not in-ones?)) ; Go! Save this spot. index]))))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; On Sun, 13 May 2012 16:47:45 -0400, Harry Spier <vasishtha.sp...@gmail.com> wrote: > Is there a better way to do this iin Racket (shorter, clearer, more readable)? > > I have vectors of 1's and 0's (each vector representing a row of black > and white pixels. I need to transform each vector into a list of > pairs. Each pair containing the start and end vector-ref's of a > contiguous segment of black pixels. > Examples: > (list-of-ranges-of-ones #(0)) -> '() > (list-of-ranges-of-ones #(0 0)) -> '() > (list-of-ranges-of-ones #(0 0 0)) -> '() > (list-of-ranges-of-ones #(1)) -> '((0 0)) > (list-of-ranges-of-ones #(1 1)) -> '((0 1)) > (list-of-ranges-of-ones #(1 1 1)) -> '((0 2)) > (list-of-ranges-of-ones #(1 1 1 0)) -> '((0 2)) > (list-of-ranges-of-ones #(0 1 1 1)) -> '((1 3)) > (list-of-ranges-of-ones #(0 1 1 1 0)) -> '((1 3)) > (list-of-ranges-of-ones #( 0 1 1 1 0 0 0 1 1 1 0)) -> '((1 3) (7 9)) > (list-of-ranges-of-ones #( 1 1 1 1 0 0 0 1 1 1 1)) -> '((0 3) (7 10)) > (list-of-ranges-of-ones #( 0 1 0 1 0 1 0 1 0 1 0)) ->'((1 1) (3 3) (5 > 5) (7 7) (9 9)) > > I've come up with the following but is there a better way to do this > in Racket (shorter, clearer, more elegant?) > > #lang racket > (define (list-of-ranges-of-ones vectr) > (let-values ([(more? get-next)(sequence-generate (in-indexed vectr))]) > > (define (add-a-range-of-ones current-range) > (define-values (current-val vectr-ref) (get-next)) > (cond > [(and (not (more?)) (= current-val 1)) (list (reverse (cons > vectr-ref current-range)))] > [(and (not (more?)) (= current-val 0)) (list (reverse (cons > (sub1 vectr-ref) current-range)))] > [(= current-val 1) (add-a-range-of-ones current-range)] > [else (cons (reverse (cons (sub1 vectr-ref) current-range)) > (skip-zeroes))])) > > (define (skip-zeroes) > (cond > [(not (more?)) '()] > [else (define-values (current-val vectr-ref) (get-next)) > (cond > [(= current-val 0) (skip-zeroes)] > [else (add-a-range-of-ones (list vectr-ref))])])) > > (if (= 1 (vector-ref vectr 0)) > (add-a-range-of-ones '(0)) > (skip-zeroes)))) > > Thanks, > Harry > ____________________ > Racket Users list: > http://lists.racket-lang.org/users ____________________ Racket Users list: http://lists.racket-lang.org/users