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