0

I'm writing an algorithm to remove overlaps, given a range of lines (I'm calling it "lines" due to the ambiguity of the term "range" in this case).

This is how a line looks like:

struct line {
   int begin, width;
   int end() const { return begin + width; }
};

Example: Given three lines (0,3), (1,2) and (5,1) I expect to obtain (0,3), (3,2) and (5,1) after the transformation. Here is a graphical representation of this problem:

Overlap Removal

This is one possible solution for the problem:

auto removeOverlap(std::pair<line, line> input)
{
    // keeps first line untouched and shifts the second line to the end of the first one, if necessary
    return std::pair<line, line>{std::get<0>(input), {std::max(std::get<0>(input).end(), std::get<1>(input).begin), std::get<1>(input).width}};
}

int main(int argc, char *argv[])
{

    std::array<line, 3> lines{{{0,3},{1,2},{5,1}}};
    for(int i = 0; i < lines.size()-1; ++i)
    {
        std::tie(lines[i], lines[i+1]) = removeOverlap(std::make_pair(lines[i], lines[i+1]));
    }
    assert(lines[0].begin == 0);
    assert(lines[1].begin == 3);
    assert(lines[2].begin == 5);

My question: How could I do this using range-v3?

I'm thinking of using a modified view::chunk(N) in which the size of the increment is 1 (instead of N). But I really don't know how to proceed from this point.

csguth
  • 569
  • 3
  • 18

2 Answers2

3

You may do:

auto pair_view =
    ranges::view::zip(lines | ranges::view::take(lines.size() - 1),
                      lines | ranges::view::drop(1));

for (auto&& p : pair_view)
{
    p = removeOverlap(p);
}

Demo

Jarod42
  • 203,559
  • 14
  • 181
  • 302
1
auto push_highwater = [](int& highwater){
  return [&](line l) {
    l.begin = (std::max)(highwater, l.begin);
    highwater = l.end();
    return l;
  };
};

Feed that to a transform view of your original range, then iterate over the transformed view in order.

Start with a highwater of min int. Ensure the int lives long enough.

Live example (couldn't figure out an easier way to transform from an array back into itself...)

Yakk - Adam Nevraumont
  • 262,606
  • 27
  • 330
  • 524