segment.scm 1.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657
  1. (library (segment)
  2. (export make-segment
  3. segment-start
  4. segment-end
  5. segment-map
  6. segment)
  7. (import (except (rnrs base)
  8. let-values
  9. map)
  10. (only (guile)
  11. lambda* λ))
  12. (define make-segment
  13. (λ (start end)
  14. (cons start end)))
  15. (define segment-start
  16. (λ (seg)
  17. (car seg)))
  18. (define segment-end
  19. (λ (seg)
  20. (cdr seg)))
  21. (define segment-map
  22. (lambda* (proc seg #:key (next (λ (num) (+ num 1))))
  23. (let ([min-val (segment-start seg)]
  24. [max-val (segment-end seg)])
  25. (let iter ([current-val° min-val])
  26. (cond
  27. [(<= current-val° max-val)
  28. (cons (proc current-val°)
  29. (iter (next current-val°)))]
  30. [else '()])))))
  31. (define segment
  32. (lambda* (start end segment-count #:key (next (λ (num) (+ num 1))))
  33. "Make segments of mostly equal length/size. A
  34. segment's starting point is based on the previous segment's
  35. ending point. Segments do not necessarily connect with no
  36. gap in between. The NEXT argument is a function, which is
  37. used to calculate the start of the starting point of the
  38. following segment from the ending point of the previous
  39. segment."
  40. (let ([segment-size
  41. (ceiling
  42. (/ (- end start)
  43. segment-count))])
  44. (let loop ([pos start])
  45. (cond
  46. [(>= (+ pos segment-size) end)
  47. (list (make-segment pos end))]
  48. [else
  49. (cons (make-segment pos (+ pos segment-size))
  50. (loop (next (+ pos segment-size))))]))))))