Perhaps this is a more elegant approach to the tactical problem:
simultaneously iterating over displaced versions of the original list. E.g.

_x '(1 1 2 3   5   7 200 201 202) ; shifted right
x  '(1 2 3 5   7 200 201 202 203) ; original list
x_ '(2 3 5 7 200 201 202 203 203) ; shifted left

When (= (+ _x 1) x (- x_ 1)) we are mid-run. Otherwise we're at the start
or end of a run. Code below.

A further displacement is needed to deal with extended runs: x__ to skip
elements in long runs.


#lang racket

; Given a strictly ascending list of numbers, summarise runs
; (... b b+1 ... b+n c ...) -> (... a b - b+n c ...)
(define (runify xs)
  (define MIN (first xs))
  (define MAX (last xs))
  (for/list ([_x (cons MIN xs)]
             [x xs]
             [x_ (append (rest xs) (list MAX))]
             [x__ (append (drop xs 2) (list MAX MAX))]
             #:unless (= (+ _x 2) x_ (- x__ 1)))
    (if (= (+ _x 1) x (- x_ 1))
        '-
        x)))

; Replace runify-ed lists with lists of lists
; E.g. '(1 - 3 8 12 15 - 100) -> '((1 3) (8) (12) (15 100))
;
(define (chunkify xs [acc null])
  (cond [(null? xs) acc]
        [(equal? (first xs) '-)
         (chunkify (drop xs 2)
                   (cons (list (caar acc) (second xs))
                         (rest acc)))]
        [else
         (chunkify (rest xs) (cons (list (first xs)) acc))]))


(define xs '(1 2 3 5 7 200 201 202 203))

(runify xs) ; '(1 - 3 5 7 200 - 203)

(reverse (chunkify (runify xs))) ; '((1 3) (5) (7) (200 203))


* * *

Racket question: How do I define a sequence generator (in-shifted-list xs
shift) to make runify work in true single pass fashion?

I would like to be able to write the following version of runify, without
generating auxiliary lists:

(define (runify-efficient xs)
  (for/list ([_x (in-shifted-list xs -1)]
             [x xs]
             [x_ (in-shifted-list xs 1)]
             [x__ (in-shifted-list xs 2)]
             #:unless (= (+ _x 2) x_ (- x__ 1)))
    (if (= (+ _x 1) x (- x_ 1))
        '-
        x)))

Dan

-- 
You received this message because you are subscribed to the Google Groups 
"Racket Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to racket-users+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to