[racket] Is there a better way to do this in Racket?

From: Harry Spier (vasishtha.spier at gmail.com)
Date: Sun May 13 16:47:45 EDT 2012

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

Posted on the users mailing list.